~ubuntu-branches/ubuntu/precise/debtags/precise-proposed

« back to all changes in this revision

Viewing changes to debtagshw/debtagshw.py

  • Committer: Package Import Robot
  • Author(s): Michael Vogt
  • Date: 2012-02-13 10:33:06 UTC
  • Revision ID: package-import@ubuntu.com-20120213103306-71cdhoe5b0zb5r1k
Tags: 1.8.0+git20120213ubuntu1
* updated git snapshot:
  - include new debtags-hardware command
  - include support for postive/negative match generator

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
21
 
22
22
import logging
23
 
import os
24
 
import subprocess
25
 
 
26
23
LOG=logging.getLogger(__name__)
27
24
 
28
 
try:
29
 
    from gi.repository import GUdev
30
 
    HAVE_GUDEV = True
31
 
except ImportError:
32
 
    HAVE_GUDEV = False
33
 
 
34
 
from opengl import OpenGL
35
 
 
36
 
class HardwareSupported:
37
 
    YES = "yes"
38
 
    NO = "no"
39
 
    UNKOWN = "unknown"
 
25
# get the detecotors lib
 
26
import detectors
 
27
 
 
28
from enums import HardwareSupported
40
29
 
41
30
class DebtagsAvailableHW(object):
 
31
    """ Match the currents system hardware to debtags """
42
32
    
43
 
    DEBTAG_TO_UDEV_PROPERTY = {
44
 
        # storage
45
 
        "hardware::storage:cd" : "ID_CDROM",
46
 
        "hardware::storage:cd:writer" : "ID_CDROM_CD_R",
47
 
        "hardware::storage:dvd" : "ID_CDROM_DVD",
48
 
        "hardware::storage:dvd:writer" : "ID_CDROM_DVD_R",
49
 
        # input
50
 
        "hardware::input:touchscreen" : "ID_INPUT_TOUCH",
51
 
        "hardware::input:mouse" : "ID_INPUT_MOUSE",
52
 
        "hardware::input:keyboard" : "ID_INPUT_KEYBOARD",
53
 
        "hardware::input:joystick" : "ID_INPUT_JOYSTICK",
54
 
    }
55
 
 
56
 
    LAPTOP_DETECT = "/usr/sbin/laptop-detect"
57
 
    SCANIMAGE = ["scanimage", "-L"]
58
 
 
59
33
    def __init__(self):
60
 
        if HAVE_GUDEV:
61
 
            self._uc = GUdev.Client()
62
 
        else:
63
 
            self._uc = None
 
34
        self._init_detectors()
 
35
 
 
36
    def _init_detectors(self):
 
37
        self._detectors = detectors.get_detectors()
64
38
 
65
39
    # public functions
66
40
    def get_hardware_support_for_tags(self, tags_list):
73
47
        for tag in tags_list:
74
48
            if not tag.startswith("hardware::"):
75
49
                continue
76
 
            # FIXME: not 100% accurate as a generic udev property could
77
 
            #        be set also (but that is not done yet
78
 
            if (not self._has_func_for_tag(tag) and
79
 
                not tag in self.DEBTAG_TO_UDEV_PROPERTY):
80
 
                result[tag] = HardwareSupported.UNKOWN
81
 
            else:
82
 
                if self._check_hw_debtag(tag):
83
 
                    result[tag] = HardwareSupported.YES
84
 
                else:
85
 
                    result[tag] = HardwareSupported.NO
 
50
            result[tag] = self._check_hw_debtag(tag)
86
51
        return result
87
52
 
88
 
    # generic
 
53
    def generate_tag_expressions(self):
 
54
        """
 
55
        Generate a sequence of (HardwareSupported, taglist)
 
56
 
 
57
        HardwareSupported is one of the constants defined in HardwareSupported
 
58
 
 
59
        taglist is a sequence of tags that applies or does not apply to the
 
60
        current system.
 
61
 
 
62
        The resulting positive or negative tag lists can be used to evaluate
 
63
        whether a package is suitable or not for the current system, or to list
 
64
        uninstalled packages that could use the hardware of the current system.
 
65
        """
 
66
        for detector in self._detectors:
 
67
            for supported, tags in detector.generate_tag_expressions():
 
68
                yield supported, tags
 
69
 
 
70
    def get_supported_tags(self):
 
71
        supported_tags = []
 
72
        for detector in self._detectors:
 
73
            supported_tags += detector.get_supported_tags()
 
74
        return supported_tags
 
75
 
 
76
    # private
89
77
    def _check_hw_debtag(self, tag):
90
 
        """ check if the current HW supports the given debtag """
91
 
        LOG.debug("check_hw_debtags: '%s'" % tag)
92
 
        res = False
93
 
        # FIXME: would be nice to have "yes", "no", "unknown" here instead
94
 
        # generic check first
95
 
        res |= self._check_generic_udev_info(tag)
96
 
        # then see if there is a detection function for the given tag
97
 
        funcname = "_%s" % tag.replace(":", "_")
98
 
        f = getattr(self, funcname, None)
99
 
        if f:
100
 
            res |= f()
 
78
        """ helper that checks a individual tag for support """
 
79
        # ask each detector
 
80
        res = HardwareSupported.UNKNOWN
 
81
        for detector in self._detectors:
 
82
            res = detector.is_supported(tag)
 
83
            if res != HardwareSupported.UNKNOWN:
 
84
                break
101
85
        return res
102
86
 
103
 
    def _has_func_for_tag(self, tag):
104
 
        return hasattr(self, "_%s" % tag.replace(":", "_"))
105
 
    
106
 
    def _check_generic_udev_info(self, tag):
107
 
        if self._uc is None: 
108
 
            return False
109
 
        for device in self._uc.query_by_subsystem(None):
110
 
            #print device.get_property_keys(), device.get_property("DEVPATH")
111
 
            if device.has_property("HW_DEBTAGS"):
112
 
                return tag in device.get_property("HW_DEBTAGS")
113
 
            prop = self.DEBTAG_TO_UDEV_PROPERTY.get(tag)
114
 
            if prop and device.has_property(prop):
115
 
                #print device.get_property(prop)
116
 
                return bool(device.get_property(prop))
117
 
        return False
118
 
 
119
 
    # hardware::opengl
120
 
    def _hardware__video_opengl(self):
121
 
        # FIXME: this should probably be launched in a seperate
122
 
        #        subprocess as the ctypes opengl stuff might be 
123
 
        #        fragile (segfault happy)
124
 
        oh = OpenGL()
125
 
        return oh.opengl_supported()
126
 
 
127
 
    # hardware::laptop
128
 
    def _hardware__laptop(self):
129
 
        if os.path.exists(self.LAPTOP_DETECT):
130
 
            return subprocess.call([self.LAPTOP_DETECT]) == 0
131
 
        else:
132
 
            LOG.warn(
133
 
                "No laptop-detect '%s' helper found" % self.LAPTOP_DETECT)
134
 
        return False
135
 
 
136
 
    # hardware::printer
137
 
    def _hardware__printer(self):
138
 
        try:
139
 
            # alternative use lpstat -p
140
 
            import cups
141
 
            c = cups.Connection()
142
 
            if len(c.getPrinters()) > 0:
143
 
                return True
144
 
        except ImportError:
145
 
            LOG.warn("No python-cups installed")
146
 
        except:
147
 
            LOG.exception("_check_printers")
148
 
        return False
149
 
        
150
 
    # hardware::printer
151
 
    def _hardware__scanner(self):
152
 
        # note that this is slow to run (1-2s)
153
 
        #ver = c_int()
154
 
        #devices = c_long()
155
 
        #sane = cdll.LoadLibrary("libsane.so.1")
156
 
        #res = sane.sane_init(byref(ver), None)
157
 
        #print res, ver
158
 
        #if not res == SANE_STATUS_GOOD:
159
 
        #    return False
160
 
        #print res
161
 
        #sane.sane_get_devices(byref(devices), False)
162
 
        # device is SANE_device** device_list how to get data?
163
 
        try:
164
 
            output = subprocess.check_output(self.SCANIMAGE)
165
 
            if output.startswith("device"):
166
 
                return True
167
 
        except Exception:
168
 
            LOG.warn("error running '%s'" % self.SCANIMAGE)
169
 
        return False
170
87