Ticket #9943: myth_smolt_7.patch

File myth_smolt_7.patch, 201.5 KB (added by anonymous, 9 years ago)
  • mythtv/programs/scripts/hardwareprofile/defaults.cfg

    commit 90de27844ec058cf060367ca7cca295a6ba7aa3c
    Author: James Meyer <james.meyer@operamail.com>
    Date:   Mon Jul 25 11:29:25 2011 -0500
    
        updated myth_smolt client.
        Removed gentoo specific stuff
    
    diff --git a/mythtv/programs/scripts/hardwareprofile/defaults.cfg b/mythtv/programs/scripts/hardwareprofile/defaults.cfg
    index be89af7..7380938 100644
    a b run_level = yes 
    1313selinux             = yes
    1414swap_size           = yes
    1515vendor              = yes
    16 MythTV              = no
    17 mythRemote          = yes
    18 MythTheme           = yes
    19 MythPlugins         = yes
    20 MythTuner           = yes
  • mythtv/programs/scripts/hardwareprofile/deleteProfile.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/deleteProfile.py b/mythtv/programs/scripts/hardwareprofile/deleteProfile.py
    old mode 100755
    new mode 100644
    index 23475dc..db3aac2
    a b  
    33# smolt - Fedora hardware profiler
    44#
    55# Copyright (C) 2007 Mike McGrath
     6# Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    67#
    78# This program is free software; you can redistribute it and/or modify
    89# it under the terms of the GNU General Public License as published by
     
    1920# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    2021
    2122import sys
     23import urlgrabber.grabber
    2224from optparse import OptionParser
    2325from urlparse import urljoin
    24 import urllib2
    25 
    26 sys.path.append('/usr/share/smolt/client')
    27 
    28 from i18n import _
    29 import smolt
    30 from smolt import error
    31 from smolt import debug
    32 from request import Request, ConnSetup
    33 
    34 def serverMessage(page):
    35     for line in page.split("\n"):
    36         if 'ServerMessage:' in line:
    37             error(_('Server Message: "%s"') % line.split('ServerMessage: ')[1])
    38             if 'Critical' in line:
    39                 sys.exit(3)
    40 
    41 parser = OptionParser(version = smolt.smoltProtocol)
    42 
    43 parser.add_option('-d', '--debug',
    44                   dest = 'DEBUG',
    45                   default = False,
    46                   action = 'store_true',
    47                   help = _('enable debug information'))
    48 parser.add_option('-s', '--server',
    49                   dest = 'smoonURL',
    50                   default = smolt.smoonURL,
    51                   metavar = 'smoonURL',
    52                   help = _('specify the URL of the server (default "%default")'))
    53 parser.add_option('-p', '--printOnly',
    54                   dest = 'printOnly',
    55                   default = False,
    56                   action = 'store_true',
    57                   help = _('print information only, do not send'))
    58 parser.add_option('-u', '--useragent',
    59                   dest = 'user_agent',
    60                   default = smolt.user_agent,
    61                   metavar = 'USERAGENT',
    62                   help = _('specify HTTP user agent (default "%default")'))
    63 parser.add_option('-t', '--timeout',
    64                   dest = 'timeout',
    65                   type = 'float',
    66                   default = smolt.timeout,
    67                   help = _('specify HTTP timeout in seconds (default %default seconds)'))
    68 parser.add_option('--uuidFile',
    69                   dest = 'uuidFile',
    70                   default = smolt.hw_uuid_file,
    71                   help = _('specify which uuid to use, useful for debugging and testing mostly.'))
    72 
    73 
    74 (opts, args) = parser.parse_args()
    75 ConnSetup(opts.smoonURL, opts.user_agent, opts.timeout, None)
    76 
    77 smolt.DEBUG = opts.DEBUG
    78 smolt.hw_uuid_file = opts.uuidFile
    79 # read the profile
    80 profile = smolt.Hardware()
    81 
    82 delHostString = 'uuid=%s' % profile.host.UUID
    83 
    84 try:
    85     req = Request('/client/delete')
    86     req.add_header('Content-length', '%i' % len(delHostString))
    87     req.add_header('Content-type', 'application/x-www-form-urlencoded')
    88     req.add_data(delHostString)
    89     o = req.open()
    90 except urllib2.URLError, e:
    91     sys.stderr.write(_('Error contacting Server:'))
    92     sys.stderr.write(str(e))
    93     sys.stderr.write('\n')
    94     sys.exit(1)
    95 else:
    96     serverMessage(o.read())
    97     o.close()
    98 
    99 sys.stdout.write(_('Profile removed, please verify at'))
    100 sys.stdout.write(' ')
    101 sys.stdout.write(urljoin(opts.smoonURL + '/', '/client/show?%s\n' % delHostString))
    10226
    10327
     28def main():
     29    sys.path.append('/usr/share/smolt/client')
     30
     31    from i18n import _
     32    import smolt
     33    from smolt import error, debug, get_profile_link, PubUUIDError
     34    from uuiddb import create_default_uuiddb
     35
     36    def serverMessage(page):
     37        for line in page.split("\n"):
     38            if 'ServerMessage:' in line:
     39                error(_('Server Message: "%s"') % line.split('ServerMessage: ')[1])
     40                if 'Critical' in line:
     41                    sys.exit(3)
     42
     43    parser = OptionParser(version = smolt.smoltProtocol)
     44
     45    parser.add_option('-d', '--debug',
     46                    dest = 'DEBUG',
     47                    default = False,
     48                    action = 'store_true',
     49                    help = _('enable debug information'))
     50    parser.add_option('-s', '--server',
     51                    dest = 'smoonURL',
     52                    default = smolt.smoonURL,
     53                    metavar = 'smoonURL',
     54                    help = _('specify the URL of the server (default "%default")'))
     55    parser.add_option('-p', '--printOnly',
     56                    dest = 'printOnly',
     57                    default = False,
     58                    action = 'store_true',
     59                    help = _('print information only, do not send'))
     60    parser.add_option('-u', '--useragent',
     61                    dest = 'user_agent',
     62                    default = smolt.user_agent,
     63                    metavar = 'USERAGENT',
     64                    help = _('specify HTTP user agent (default "%default")'))
     65    parser.add_option('-t', '--timeout',
     66                    dest = 'timeout',
     67                    type = 'float',
     68                    default = smolt.timeout,
     69                    help = _('specify HTTP timeout in seconds (default %default seconds)'))
     70    parser.add_option('--uuidFile',
     71                    dest = 'uuidFile',
     72                    default = smolt.hw_uuid_file,
     73                    help = _('specify which uuid to use, useful for debugging and testing mostly.'))
     74
     75
     76    (opts, args) = parser.parse_args()
     77
     78    smolt.DEBUG = opts.DEBUG
     79    smolt.hw_uuid_file = opts.uuidFile
     80
     81    grabber = urlgrabber.grabber.URLGrabber(user_agent=opts.user_agent, timeout=opts.timeout)
     82
     83    uuid = smolt.read_uuid()
     84    delHostString = 'uuid=%s' % uuid
     85
     86    # Try retrieving current pub_uuid  (from cache or remotely if necessary)
     87    pub_uuid = None
     88    try:
     89        pub_uuid = smolt.read_pub_uuid(create_default_uuiddb(), uuid, silent=True)
     90    except PubUUIDError:
     91        pass
     92
     93
     94    try:
     95        o=grabber.urlopen(urljoin(opts.smoonURL + '/', '/client/delete'), data=delHostString, http_headers=(
     96                        ('Content-length', '%i' % len(delHostString)),
     97                        ('Content-type', 'application/x-www-form-urlencoded')))
     98    except urlgrabber.grabber.URLGrabError, e:
     99        sys.stderr.write(_('Error contacting Server:'))
     100        sys.stderr.write(str(e))
     101        sys.stderr.write('\n')
     102        sys.exit(1)
     103    else:
     104        serverMessage(o.read())
     105        o.close()
     106
     107    if pub_uuid is None:
     108        profile_url = urljoin(opts.smoonURL + '/', '/client/show?%s' % delHostString)
     109    else:
     110        profile_url = get_profile_link(opts.smoonURL, pub_uuid)
     111    print _('Profile removed, please verify at'), profile_url
     112
     113
     114if __name__ == '__main__':
     115    main()
  • mythtv/programs/scripts/hardwareprofile/devicelist.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/devicelist.py b/mythtv/programs/scripts/hardwareprofile/devicelist.py
    index a7645d7..22cd802 100644
    a b  
    11#!/usr/bin/python
     2# -*- coding: utf-8 -*-
     3
     4# smolt - Fedora hardware profiler
     5#
     6# Copyright (C) 2010 Mike McGrath <mmcgrath@redhat.com>
     7#
     8# This program is free software; you can redistribute it and/or modify
     9# it under the terms of the GNU General Public License as published by
     10# the Free Software Foundation; either version 2 of the License, or
     11# (at your option) any later version.
     12#
     13# This program is distributed in the hope that it will be useful,
     14# but WITHOUT ANY WARRANTY; without even the implied warranty of
     15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16# GNU General Public License for more details.
     17#
     18# You should have received a copy of the GNU General Public License
     19# along with this program; if not, write to the Free Software
     20# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     21
    222import os
    323from hwdata import DeviceMap
    424
    def get_class(class_id): 
    89109pci = DeviceMap('pci')
    90110usb = DeviceMap('usb')
    91111
    92 class Device():
    93     def __init__(self, id):
    94         self.id = id
    95         self.bus = 'Unknown'
    96         self.vendorid = 'None'
    97         self.type = 'Unknown'
    98         self.description = 'Unknown'
    99         self.vendorid = 'Unknown'
    100         self.deviceid = 'Unknown'
    101         self.subsysvendorid = 'Unknown'
    102         self.subsysdeviceid = 'Unknown'
    103         self.driver = 'None'
     112
    104113
    105114def device_factory(cls, id):
    106115    cls = eval(cls.upper() + 'Device')
    class USBDevice( Device ): 
    147156        PATH = '/sys/bus/usb/devices/' + self.id + '/'
    148157        self.vendorid       = int(cat(PATH +         'idVendor')[0].strip(), 16)
    149158        self.deviceid       = int(cat(PATH +        'idProduct')[0].strip(), 16)
    150         desc                =     cat(PATH +          'product')[0].strip()
     159        try:
     160            desc                =     cat(PATH +          'product')[0].strip().decode('ASCII',  errors='ignore')
     161        except:
     162            #The fedora python pkg is broken and doesn't like decode with options, so this is a fallback
     163            desc                =     cat(PATH +          'product')[0].strip().decode()
    151164        self.description    = usb.device(self.vendorid,
    152165                                         self.deviceid,
    153166                                         alt=desc)
    def get_device_list(): 
    156169    devices = {}
    157170    for bus in BUS_LIST:
    158171        PATH = '/sys/bus/' + bus + '/devices/'
    159         for device in os.listdir(PATH):
    160             devices[device] = device_factory(bus, device)
     172        if os.path.exists(PATH):
     173            for device in os.listdir(PATH):
     174                devices[device] = device_factory(bus, device)
    161175    return devices
    162176
  • mythtv/programs/scripts/hardwareprofile/distros/all.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/all.py b/mythtv/programs/scripts/hardwareprofile/distros/all.py
    index bb67ff0..3cde05c 100644
    a b  
    1616# along with this program; if not, write to the Free Software
    1717# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    1818
    19 from gentoo.main import Gentoo
     19#from gentoo.main import create_gentoo
     20from mythtv_data.main import create_mythtv
    2021
    2122def get():
    22     res = [Gentoo(),]
     23    #res = [create_gentoo(),create_mythtv()]
     24    res = [create_mythtv()]
    2325    return res
  • mythtv/programs/scripts/hardwareprofile/distros/distro.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/distro.py b/mythtv/programs/scripts/hardwareprofile/distros/distro.py
    index f7abca6..a3bac89 100644
    a b class Distro: 
    2626    def detected(self, debug=False):
    2727        return False
    2828
    29     def gather(self, debug=False):
     29    def gather(self, gate, debug=False):
    3030        pass
    3131
    3232    def data(self):
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/_mismatch.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/__init__.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/__init__.py
    deleted file mode 100644
    index e69de29..0000000
    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/_mismatch.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/_mismatch.py
    deleted file mode 100644
    index 0d06448..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 from tools.syncfile import SyncFile
    20 from tools.overlayparser import OverlayParser
    21 import ConfigParser
    22 import os
    23 import sys
    24 
    25 layman_config = ConfigParser.ConfigParser()
    26 layman_config.read('/etc/layman/layman.cfg')
    27 layman_storage_path = layman_config.get('MAIN', 'storage')
    28 if not layman_storage_path.endswith('/'):
    29     layman_storage_path = layman_storage_path + '/'
    30 
    31 sync_file = SyncFile(
    32         'http://www.gentoo.org/proj/en/overlays/layman-global.txt',
    33         'layman-global.txt')
    34 parser = OverlayParser()
    35 file = open(sync_file.path(), 'r')
    36 parser.parse(file.read())
    37 file.close()
    38 
    39 legend_printed = False
    40 for i in parser.get().keys():
    41     layman_global_name = i
    42     overlay_folder = os.path.join(layman_storage_path, layman_global_name)
    43     if not os.path.exists(overlay_folder):
    44         sys.stderr.write('ERROR: Overlay "%s" not found\n' % layman_global_name)
    45         continue
    46     filename = os.path.join(overlay_folder, 'profiles', 'repo_name')
    47     if not os.path.exists(filename):
    48         sys.stderr.write('ERROR: Overlay "%s" lacks repo_name entry\n' % \
    49             layman_global_name)
    50         continue
    51     try:
    52         file = open(filename, 'r')
    53         repo_name = file.readline().rstrip('\n\r')
    54         file.close()
    55     except IOError:
    56         continue
    57     if layman_global_name != repo_name:
    58         if not legend_printed:
    59             sys.stderr.write('Format:\n')
    60             sys.stderr.write('    "<repo_name>",  # <layman-global.txt>\n')
    61             sys.stderr.write('\n')
    62             sys.stderr.write('Entries:\n')
    63             legend_printed = True
    64         print '    "%s",  # %s' % \
    65             (repo_name, layman_global_name)
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/_mismatch_contacts.sh

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/_mismatch_contacts.sh b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/_mismatch_contacts.sh
    deleted file mode 100755
    index 20131c0..0000000
    + -  
    1 #!/usr/bin/env bash
    2 get_overlay_contact() {
    3     overlay=$1
    4     layman -i "${overlay}" | fgrep 'Contact :' | grep -o '[^ ]\+@[^ ]\+'
    5 }
    6 
    7 echo 'missing'
    8 for overlay in $(python _mismatch.py |& fgrep 'lacks' |& sed -e 's|^ERROR: Overlay "||' -e 's|" lacks repo_name entry$||'); do
    9     contact=$(get_overlay_contact "${overlay}")
    10     echo "  ${overlay} overlay contact <${contact}>"
    11 done
    12 echo
    13 
    14 echo 'mismatch'
    15 while read overlay ; do
    16     contact=$(get_overlay_contact "${overlay}")
    17     echo "  ${overlay} overlay contact <${contact}>"
    18 done < <(python _mismatch.py 2>/dev/null | grep -o '# [^ ]\+$' | sed 's|^# ||')
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/compileflags.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/compileflags.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/compileflags.py
    deleted file mode 100644
    index ca80cc6..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import re
    20 import portage
    21 from makeopts import MakeOpts
    22 
    23 import os
    24 import sys
    25 import distros.shared.html as html
    26 from gate import Gate
    27 
    28 SHORT_PARA_PATTERN = '-[XxAloDUubVIG]\\s+\\S+|-[^-]\\S+'
    29 LONG_PARA_PATTERN = '--param\\s+\\S+=\\S+|--\\S+|--\\S+=\\S+'
    30 PARA_PATTERN = re.compile('(%s|%s)\\b' % (SHORT_PARA_PATTERN, LONG_PARA_PATTERN))
    31 LINKER_FLAG_LIST_PATTERN = re.compile('-Wl,[^,]*,')
    32 
    33 class CompileFlags:
    34     def __init__(self):
    35         self._publish = Gate().grants('gentoo', 'compile_flags')
    36         if self._publish:
    37             self._cflags = self._parse(portage.settings['CFLAGS'])
    38             self._cxxflags = self._parse(portage.settings['CXXFLAGS'])
    39             self._ldflags = self._parse(portage.settings['LDFLAGS'])
    40             self._makeopts = MakeOpts().serialize()
    41         else:
    42             self._cflags = []
    43             self._cxxflags = []
    44             self._ldflags = []
    45             self._makeopts = []
    46 
    47     def _parse(self, flags):
    48         list = []
    49         for m in re.finditer(PARA_PATTERN, flags):
    50             text = re.sub('\\s{2,}', ' ', m.group()) # Normalize whitespace
    51             if re.match(LINKER_FLAG_LIST_PATTERN, text):
    52                 # "-Wl,foo,bar" --> "-Wl,foo" "-Wl,bar"
    53                 split_linker_flags = ['-Wl,%s' % e for e in text.split(',')[1:]]
    54                 list.extend(split_linker_flags)
    55             else:
    56                 list.append(text)
    57         return list
    58 
    59     def get_cflags(self):
    60         return self._cflags
    61 
    62     def get_cxxflags(self):
    63         return self._cxxflags
    64 
    65     def get_ldflags(self):
    66         return self._ldflags
    67 
    68     def serialize(self):
    69         res = {
    70             'cflags':self._cflags,
    71             'cxxflags':self._cxxflags,
    72             'ldflags':self._ldflags,
    73             'makeopts':self._makeopts,
    74         }
    75         return res
    76 
    77     def get_metrics(self, target_dict):
    78         def make_entry(count):
    79             return (self._publish, 0, count)
    80 
    81         target_dict['call_flags_cflags'] = make_entry(len(self._cflags))
    82         target_dict['call_flags_cxxflags'] = make_entry(len(self._cxxflags))
    83         target_dict['call_flags_ldflags'] = make_entry(len(self._ldflags))
    84         target_dict['call_flags_makeopts'] = make_entry(len(self._makeopts))
    85 
    86     def dump_html(self, lines):
    87         lines.append('<h2>Compile flags</h2>')
    88         for group, values in sorted(self.serialize().items()):
    89             lines.append('<h3>%s</h3>' % html.escape(group))
    90             lines.append('<ul>')
    91             for v in values:
    92                 lines.append('<li>%s</li>' % html.escape(v))
    93             lines.append('</ul>')
    94 
    95     def dump_rst(self, lines):
    96         lines.append('Compile flags')
    97         lines.append('-----------------------------')
    98         for k, v in sorted(self.serialize().items()):
    99             lines.append('- %s: %s' % (k, ' '.join(v)))
    100 
    101     def _dump(self):
    102         lines = []
    103         self.dump_rst(lines)
    104         print '\n'.join(lines)
    105         print
    106 
    107 if __name__ == '__main__':
    108     compileflags = CompileFlags()
    109     compileflags._dump()
    110 
    111 """
    112 Samples
    113 -Os -pipe -march=armv6j -mtune=arm1136jf-s -mfpu=vfp --param ggc-min-expand=0 --param ggc-min-heapsize=65536"
    114 -march=k8 -O2 -pipe -ggdb -Wall
    115 -Wl,-O1 -Wl,--hash-style=gnu,--enable-new-dtags,--as-needed
    116 """
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/features.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/features.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/features.py
    deleted file mode 100644
    index 7fcb1bf..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import portage
    20 import distros.shared.html as html
    21 from gate import Gate
    22 
    23 try:
    24     set
    25 except NameError:
    26     from sets import Set as set  # Python 2.3 fallback
    27 
    28 
    29 class _Features:
    30     def __init__(self):
    31         self._fill_features()
    32 
    33     def _fill_features(self):
    34         def pre_evaluate_to_set(use_flags):
    35             # .. -foo .. foo .. --> foo
    36             # .. foo .. -foo .. --> -foo
    37             d = {}
    38             for i in [e.lstrip('+') for e in use_flags]:
    39                 if i.startswith('-'):
    40                     enabled = False
    41                     flag = i.lstrip('-')
    42                 else:
    43                     enabled = True
    44                     flag = i
    45                 d[flag] = enabled
    46             return set((enabled and flag or '-' + flag) for flag, enabled in d.items())
    47 
    48         def get_features(section):
    49             res = pre_evaluate_to_set(portage.settings.configdict[section].get("FEATURES", "").split())
    50             return res
    51 
    52         publish_features = Gate().grants('gentoo', 'features')
    53         publish_system_profile = Gate().grants('gentoo', 'system_profile')
    54 
    55 
    56         self._features = {}
    57         for key in ('defaults', 'conf', 'env', 'globals'):
    58             self._features[key] = {}
    59 
    60         self._features['defaults']['publish'] = \
    61                 publish_features and publish_system_profile
    62         self._features['conf']['publish'] = publish_features
    63         self._features['globals']['publish'] = publish_features
    64         self._features['env']['publish'] = \
    65                 self._features['defaults']['publish'] and \
    66                 self._features['globals']['publish'] and \
    67                 self._features['conf']['publish']
    68 
    69         _all_features = {}
    70         for key in ('defaults', 'conf', 'env', 'globals'):
    71             if self._features[key]['publish']:
    72                 _all_features[key] = get_features(key)
    73             else:
    74                 _all_features[key] = []
    75 
    76         for key in ('defaults', 'conf', 'env', 'globals'):
    77             self._features[key]['entries'] = \
    78                     set(_all_features[key])
    79 
    80     def serialize(self):
    81         res = {
    82             'profile':sorted(self._features['defaults']['entries']),
    83             'make_conf':sorted(self._features['conf']['entries']),
    84             'make_globals':sorted(self._features['globals']['entries']),
    85             'final':sorted(self._features['env']['entries']),
    86         }
    87         return res
    88 
    89     def get_metrics(self, target_dict):
    90         fill_jobs = {
    91             'features_profile':'defaults',
    92             'features_make_conf':'conf',
    93             'features_make_globals':'globals',
    94             'features_final':'env',
    95         }
    96         for target, source in fill_jobs.items():
    97             target_dict[target] = (
    98                     self._features[source]['publish'], \
    99                     0, \
    100                     self._features[source]['publish'] and \
    101                         len(self._features[source]['entries']) or 0)
    102 
    103     def _dump_html_section(self, lines, title, data, line_break=True):
    104         lines.append('<h3>%s</h3>' % html.escape(title))
    105         lines.append('<ul>')
    106         for i in sorted(data):
    107             lines.append('<li>%s</li>' % html.escape(i))
    108         lines.append('</ul>')
    109 
    110     def dump_html(self, lines):
    111         serialized = self.serialize()
    112         lines.append('<h2>Features</h2>')
    113         self._dump_html_section(lines, 'From make.conf', serialized['make_conf'])
    114         self._dump_html_section(lines, 'From make.globals', serialized['make_globals'])
    115         self._dump_html_section(lines, 'From system profile', serialized['profile'])
    116         self._dump_html_section(lines, 'Combined', serialized['final'], line_break=False)
    117 
    118     def _dump_rst_section(self, lines, title, data, line_break=True):
    119         lines.append(title)
    120         lines.append('`````````````````````')
    121         for i in sorted(data):
    122             lines.append('- %s' % i)
    123         if line_break:
    124             lines.append('')
    125 
    126     def dump_rst(self, lines):
    127         serialized = self.serialize()
    128         lines.append('Features')
    129         lines.append('-----------------------------')
    130         self._dump_rst_section(lines, 'From make.conf', serialized['make_conf'])
    131         self._dump_rst_section(lines, 'From make.globals', serialized['make_globals'])
    132         self._dump_rst_section(lines, 'From system profile', serialized['profile'])
    133         self._dump_rst_section(lines, 'Combined', serialized['final'], line_break=False)
    134 
    135     def _dump(self):
    136         lines = []
    137         self.dump_rst(lines)
    138         print '\n'.join(lines)
    139         print
    140 
    141 
    142 _features_instance = None
    143 def Features():
    144     """
    145     Simple singleton wrapper around _Features class
    146     """
    147     global _features_instance
    148     if _features_instance == None:
    149         _features_instance = _Features()
    150     return _features_instance
    151 
    152 
    153 if __name__ == '__main__':
    154     features = Features()
    155     features._dump()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/generatedpackages.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/generatedpackages.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/generatedpackages.py
    deleted file mode 100644
    index ec6c40f..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 _COLLECT_CROSSDEV = True  # TODO configurable
    20 _COLLECT_GCPAN = True  # TODO configurable
    21 _COLLECT_G_CTAN = True  # TODO configurable, affects overlays.py, too
    22 
    23 class _GeneratedPackages:
    24     def __init__(self):
    25         pass
    26 
    27     def is_generated_cat(self, cat):
    28         return self._is_crossdev_cat(cat) or \
    29             self._is_gcpan_cat(cat) or \
    30             self._is_g_ctan_cat(cat)
    31 
    32     def is_private_cat(self, cat):
    33         return (self._is_crossdev_cat(cat) and not _COLLECT_CROSSDEV) or \
    34             (self._is_gcpan_cat(cat) and not _COLLECT_GCPAN) or \
    35             (self._is_g_ctan_cat(cat) and not _COLLECT_G_CTAN)
    36 
    37     def _is_crossdev_cat(self, cat):
    38         return cat.startswith('cross-')
    39 
    40     def _is_gcpan_cat(self, cat):
    41         return cat == 'perl-gcpan'
    42 
    43     def _is_g_ctan_cat(self, cat):
    44         return cat == 'g-ctan'
    45 
    46     def is_dedicated_repo_name(self, repo_name):
    47         return repo_name in ('g-ctan', )
    48 
    49 
    50 _generated_packages = None
    51 def GeneratedPackages():
    52     """
    53     Simple singleton wrapper around _GeneratedPackages class
    54     """
    55     global _generated_packages
    56     if _generated_packages == None:
    57         _generated_packages = _GeneratedPackages()
    58     return _generated_packages
    59 
    60 
    61 if __name__ == '__main__':
    62     generated_packages = GeneratedPackages()
    63     for cpv in ('perl-gcpan/Set-Object-1.27',
    64             'cross-spu-elf/newlib-1.16.0',
    65             'dev-util/git',
    66             ):
    67         cat = cpv.split('/')[0]
    68         print '%s: generated=[%s] private=[%s]' % \
    69             (cpv, str(generated_packages.is_generated_cat(cat)),
    70             str(generated_packages.is_private_cat(cat)))
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/globaluseflags.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/globaluseflags.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/globaluseflags.py
    deleted file mode 100644
    index 81b3094..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import portage
    20 import re
    21 import os
    22 from tools.maintreedir import main_tree_dir
    23 
    24 import os
    25 import sys
    26 import distros.shared.html as html
    27 from gate import Gate
    28 
    29 try:
    30     set
    31 except NameError:
    32     from sets import Set as set  # Python 2.3 fallback
    33 
    34 
    35 def _flatten_dict_tree(dict_tree):
    36     def process_compressables(compressables, res):
    37         if len(compressables) > 1:
    38             res.append((k + '_' + '{' + ','.join(s for (s, d) in compressables) + '}', 1))
    39         else:
    40             res.append((k + '_' + compressables[0][0], 1))
    41 
    42     res = []
    43     for k in sorted(dict_tree.keys()):
    44         flat = _flatten_dict_tree(dict_tree[k])
    45         if not flat:
    46             res.append((k, 0))
    47         else:
    48             if len(flat) > 1:
    49                 compressables = []
    50                 for (s, d) in sorted(flat):
    51                     if d > 0:
    52                         if compressables:
    53                             process_compressables(compressables, res)
    54                             compressables = []
    55                         res.append((k + '_' + s, d))
    56                     else:
    57                         compressables.append((s, d))
    58                 if compressables:
    59                     process_compressables(compressables, res)
    60             else:
    61                 res.append((k + '_' + flat[0][0], flat[0][1]))
    62     return res
    63 
    64 def compress_use_flags(flag_list):
    65     # Convert to tree
    66     dict_tree = {}
    67     for f in flag_list:
    68         parts = f.split('_')
    69         d = dict_tree
    70         for i, v in enumerate(parts):
    71             if v not in d:
    72                 d[v] = {}
    73             d = d[v]
    74 
    75     # Flatten back
    76     return [s for (s, d) in _flatten_dict_tree(dict_tree)]
    77 
    78 
    79 class _GlobalUseFlags:
    80     def __init__(self):
    81         self._fill_use_flags()
    82 
    83     def _registered_global_use_flags(self):
    84         global_line_sub = re.compile('^([^ ]+) - .*\\n')
    85         global_line_filter = re.compile('^[^ ]+ - ')
    86         try:
    87             f = open(os.path.join(main_tree_dir(), 'profiles', 'use.desc'), 'r')
    88             lines = [global_line_sub.sub('\\1', l) for l in
    89                     f.readlines() if global_line_filter.match(l)]
    90             f.close()
    91             return set(lines)
    92         except IOError:
    93             return set()
    94 
    95     def _registered_local_use_flags(self):
    96         local_line_sub = re.compile('^[^ :]+:([^ ]+) - .*\\n')
    97         local_line_filter = re.compile('^[^ :]+:[^ ]+ - ')
    98         try:
    99             f = open(os.path.join(main_tree_dir(), 'profiles',
    100                 'use.local.desc'), 'r')
    101             lines = [local_line_sub.sub('\\1', l) for l in
    102                     f.readlines() if local_line_filter.match(l)]
    103             f.close()
    104             return set(lines)
    105         except IOError:
    106             return set()
    107 
    108     def _expanded_use_flags(self):
    109         use_flags = []
    110         expand_desc_dir = os.path.join(main_tree_dir(), 'profiles', 'desc')
    111         try:
    112             expand_list = os.listdir(expand_desc_dir)
    113         except OSError:
    114             pass
    115         else:
    116             for desc_filename in expand_list:
    117                 if not desc_filename.endswith('.desc'):
    118                     continue
    119                 use_prefix = desc_filename[:-5].lower() + '_'
    120                 for line in portage.grabfile(os.path.join(
    121                         expand_desc_dir, desc_filename)):
    122                     x = line.split()
    123                     if x:
    124                         use_flags.append(use_prefix + x[0])
    125         return set(use_flags)
    126 
    127     def _auto_use_flags(self):
    128         return set(portage.grabfile(os.path.join(main_tree_dir(), 'profiles',
    129             'arch.list')))
    130 
    131     def _fill_use_flags(self):
    132         def pre_evaluate_to_set(use_flags):
    133             # .. -foo .. foo .. --> foo
    134             # .. foo .. -foo .. --> -foo
    135             d = {}
    136             for i in [e.lstrip('+') for e in use_flags]:
    137                 if i.startswith('-'):
    138                     enabled = False
    139                     flag = i.lstrip('-')
    140                 else:
    141                     enabled = True
    142                     flag = i
    143                 d[flag] = enabled
    144             return set((enabled and flag or '-' + flag) for flag, enabled in d.items())
    145 
    146         def get_use_flags(section):
    147             res = pre_evaluate_to_set(portage.settings.configdict[section].get("USE", "").split())
    148             use_expand = portage.settings.configdict[section].get("USE_EXPAND", "").split()
    149             for expand_var in use_expand:
    150                 expand_var_values = portage.settings.configdict[section].get(expand_var, "").split()
    151                 prefix = expand_var.lower()
    152                 res = res.union(set('%s_%s' % (prefix, e) for e in expand_var_values))
    153             return res
    154 
    155         publish_global_use_flags = Gate().grants('gentoo', 'global_use_flags')
    156         publish_system_profile = Gate().grants('gentoo', 'system_profile')
    157 
    158 
    159         self._use_flags = {}
    160         for key in ('defaults', 'conf', 'env'):
    161             self._use_flags[key] = {}
    162 
    163         self._use_flags['defaults']['publish'] = \
    164                 publish_global_use_flags and publish_system_profile
    165         self._use_flags['conf']['publish'] = publish_global_use_flags
    166         self._use_flags['env']['publish'] = \
    167                 self._use_flags['defaults']['publish'] and \
    168                 self._use_flags['conf']['publish']
    169 
    170         _all_use_flags = {}
    171         for key in ('defaults', 'conf', 'env'):
    172             if self._use_flags[key]['publish']:
    173                 _all_use_flags[key] = get_use_flags(key)
    174             else:
    175                 _all_use_flags[key] = []
    176 
    177         # Filter our private use flags
    178         self._non_private_space = self._registered_global_use_flags().union(
    179                 self._registered_local_use_flags()).union(
    180                 self._expanded_use_flags()).union(
    181                 self._auto_use_flags())
    182 
    183         def is_non_private(x):
    184             positive = x.lstrip('-')
    185             return positive in self._non_private_space
    186 
    187         for key in ('defaults', 'conf', 'env'):
    188             self._use_flags[key]['flags'] = \
    189                     set(e for e in _all_use_flags[key] if is_non_private(e))
    190             self._use_flags[key]['count_non_private'] = \
    191                     len(self._use_flags[key]['flags'])
    192             self._use_flags[key]['count_private'] = len(_all_use_flags[key]) - \
    193                     self._use_flags[key]['count_non_private']
    194 
    195     def is_known(self, flag):
    196         return flag in self._non_private_space
    197 
    198     def serialize(self):
    199         res = {
    200             'profile':sorted(self._use_flags['defaults']['flags']),
    201             'make_conf':sorted(self._use_flags['conf']['flags']),
    202             'final':sorted(self._use_flags['env']['flags']),
    203         }
    204         return res
    205 
    206     def get_metrics(self, target_dict):
    207         fill_jobs = {
    208             'global_use_flags_profile':'defaults',
    209             'global_use_flags_make_conf':'conf',
    210             'global_use_flags_final':'env',
    211         }
    212         for target, source in fill_jobs.items():
    213             target_dict[target] = (
    214                     self._use_flags[source]['publish'], \
    215                     self._use_flags[source]['count_private'], \
    216                     self._use_flags[source]['count_non_private'])
    217 
    218     def dump_html(self, lines):
    219         serialized = self.serialize()
    220         lines.append('<h2>Global use flags</h2>')
    221         lines.append('<h3>From make.conf</h3>')
    222         lines.append('<p>')
    223         lines.append(html.escape(', '.join(compress_use_flags(serialized['make_conf']))))
    224         lines.append('</p>')
    225         lines.append('<h3>From system profile</h3>')
    226         lines.append('<p>')
    227         lines.append(html.escape(', '.join(compress_use_flags(serialized['profile']))))
    228         lines.append('</p>')
    229         lines.append('<h3>Combined</h3>')
    230         lines.append('<p>')
    231         lines.append(html.escape(', '.join(compress_use_flags(serialized['final']))))
    232         lines.append('</p>')
    233 
    234     def dump_rst(self, lines):
    235         serialized = self.serialize()
    236         lines.append('Global use flags')
    237         lines.append('-----------------------------')
    238         lines.append('From make.conf')
    239         lines.append('`````````````````````')
    240         lines.append('  '.join(compress_use_flags(serialized['make_conf'])))
    241         lines.append('')
    242         lines.append('From system profile')
    243         lines.append('`````````````````````')
    244         lines.append('  '.join(compress_use_flags(serialized['profile'])))
    245         lines.append('')
    246         lines.append('Combined')
    247         lines.append('`````````````````````')
    248         lines.append('  '.join(compress_use_flags(serialized['final'])))
    249 
    250     def _dump(self):
    251         lines = []
    252         self.dump_rst(lines)
    253         print '\n'.join(lines)
    254         print
    255 
    256 
    257 _global_use_flags_instance = None
    258 def GlobalUseFlags():
    259     """
    260     Simple singleton wrapper around _GlobalUseFlags class
    261     """
    262     global _global_use_flags_instance
    263     if _global_use_flags_instance == None:
    264         _global_use_flags_instance = _GlobalUseFlags()
    265     return _global_use_flags_instance
    266 
    267 
    268 if __name__ == '__main__':
    269     global_use_flags = GlobalUseFlags()
    270     global_use_flags._dump()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/installedpackages.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/installedpackages.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/installedpackages.py
    deleted file mode 100644
    index dcb42a5..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import portage
    20 from portage.dbapi.vartree import vartree
    21 from portage.versions import catpkgsplit
    22 from overlays import Overlays
    23 from globaluseflags import GlobalUseFlags, compress_use_flags
    24 from worldset import WorldSet
    25 from packagestar import PackageMask, PackageUnmask, ProfilePackageMask
    26 from packageprivacy import is_private_package_atom
    27 
    28 import os
    29 import sys
    30 import distros.shared.html as html
    31 from gate import Gate
    32 
    33 class InstalledPackages:
    34     def __init__(self, debug=False,
    35             cb_enter=None, cb_done=None):
    36         self._publish_installed_packages = Gate().grants('gentoo', 'installed_packages')
    37         self._publish_installed_packages_use_flags = Gate().grants('gentoo', 'installed_packages_use_flags')
    38         self._publish_repos = Gate().grants('gentoo', 'repositories')
    39 
    40         self._cpv_flag_list = []
    41         self._private_count = 0
    42         self._private_use_flags = 0
    43         self._non_private_use_flags = 0
    44         if self._publish_installed_packages:
    45             var_tree = vartree()
    46             installed_cpvs = var_tree.getallcpv()  # TODO upstream plans rename?
    47             self._total_count = len(installed_cpvs)
    48             i = 0
    49             for cpv in sorted(installed_cpvs):
    50                 i = i + 1
    51                 if cb_enter:
    52                     cb_enter(cpv, i, self._total_count)
    53                 entry = self._process(var_tree, cpv, debug=debug)
    54                 if entry:
    55                     self._cpv_flag_list.append(entry)
    56                 else:
    57                     self._private_count = self._private_count + 1
    58         else:
    59             self._total_count = 0
    60         if cb_done:
    61             cb_done()
    62 
    63     def _keyword_status(self, ARCH, ACCEPT_KEYWORDS, KEYWORDS):
    64         k = set(KEYWORDS.split(' '))
    65         if ARCH in k:
    66             return ''
    67         TILDE_ARCH = '~' + ARCH
    68         if TILDE_ARCH in k:
    69             ak = set(ACCEPT_KEYWORDS.split(' '))
    70             if TILDE_ARCH in ak:
    71                 return ''
    72             else:
    73                 return '~arch'
    74         else:
    75             return '**'
    76 
    77     def is_known_use_flag(self, flag):
    78         known = GlobalUseFlags().is_known(flag)
    79         if not known:
    80             print '  skipping private use flag "%s"' % flag
    81         return known
    82 
    83     def _process(self, var_tree, cpv, debug=False):
    84         cat, pkg, ver, rev = catpkgsplit(cpv)
    85         package_name = "%s/%s" % (cat, pkg)
    86         if rev == 'r0':
    87             version_revision = ver
    88         else:
    89             version_revision = "%s-%s" % (ver, rev)
    90 
    91         SLOT, KEYWORDS, repo, IUSE, USE = \
    92             var_tree.dbapi.aux_get(cpv, ['SLOT', 'KEYWORDS', 'repository',
    93             'IUSE', 'USE'])
    94 
    95         # Perform privacy check and filtering
    96         installed_from = [repo, ]
    97         if is_private_package_atom('=' + cpv, installed_from=installed_from,
    98                 debug=debug):
    99             return None
    100         repo = installed_from[0]
    101 
    102         ACCEPT_KEYWORDS = portage.settings['ACCEPT_KEYWORDS']
    103         ARCH = portage.settings['ARCH']
    104         keyword_status = self._keyword_status(ARCH, ACCEPT_KEYWORDS, KEYWORDS)
    105 
    106         unmasked = PackageUnmask().hits(cpv)
    107         # A package that is (1) installed and (2) not unmasked
    108         # cannot be masked so we skip the next line's checks
    109         masked = unmasked and (PackageMask().hits(cpv) or \
    110             ProfilePackageMask().hits(cpv))
    111 
    112         # World set test
    113         if SLOT != '0':
    114             world_set_test = '%s/%s:%s' % (cat, pkg, SLOT)
    115         else:
    116             world_set_test = '%s/%s' % (cat, pkg)
    117         is_in_world = world_set_test in WorldSet().get()
    118 
    119         # Use flags
    120         if self._publish_installed_packages_use_flags:
    121             iuse_list = tuple(x.lstrip("+-") for x in IUSE.split())
    122             count_all = len(set(iuse_list))
    123 
    124             package_use_set = set(filter(self.is_known_use_flag, USE.split()))
    125             package_iuse_set = set(filter(self.is_known_use_flag, iuse_list))
    126             enabled_flags = package_use_set & package_iuse_set
    127             disabled_flags = package_iuse_set - package_use_set
    128             package_flags = sorted(enabled_flags) + ['-' + e for e in sorted(disabled_flags)]
    129 
    130             count_non_private = len(package_flags)
    131             count_private = count_all - count_non_private
    132 
    133             self._private_use_flags = self._private_use_flags + count_private
    134             self._non_private_use_flags = self._non_private_use_flags + count_non_private
    135         else:
    136             package_flags = tuple()
    137 
    138         if not self._publish_repos:
    139             repo = 'WITHHELD'
    140 
    141         entry = [package_name, version_revision, SLOT, keyword_status,
    142             masked, unmasked, is_in_world, repo, package_flags]
    143         return entry
    144 
    145     def total_count(self):
    146         return self._total_count
    147 
    148     def private_count(self):
    149         return self._private_count
    150 
    151     def known_count(self):
    152         return len(self._cpv_flag_list)
    153 
    154     def serialize(self):
    155         return self._cpv_flag_list
    156 
    157     def get_metrics(self, target_dict):
    158         if self._publish_installed_packages:
    159             target_dict['installed_packages'] = (True, \
    160                     self._private_count, \
    161                     self._total_count - self._private_count)
    162         else:
    163             target_dict['installed_packages'] = (False, 0, 0)
    164 
    165         target_dict['installed_packages_use_flags'] = \
    166                 (self._publish_installed_packages_use_flags, \
    167                 self._private_use_flags, \
    168                 self._non_private_use_flags)
    169 
    170     def dump_html(self, lines):
    171         def fix_empty(text):
    172             if text == '':
    173                 return '&nbsp;'
    174             else:
    175                 return text
    176 
    177         lines.append('<h2>Installed packages</h2>')
    178         lines.append('<table border="1" cellspacing="1" cellpadding="4">')
    179         lines.append('<tr>')
    180         for i in ('Package', 'Version', 'Slot', 'Keyword', 'Masked', 'Unmasked', 'World', 'Tree', 'Use flags'):
    181             lines.append('<th>%s</th>' % i)
    182         lines.append('</tr>')
    183         for list in self._cpv_flag_list:
    184             package_name, version_revision, SLOT, keyword_status, \
    185                 masked, unmasked, is_in_world, repo, sorted_flags_list = \
    186                 list
    187 
    188             lines.append('<tr>')
    189             for i in (package_name, version_revision):
    190                 lines.append('<td>%s</td>' % html.escape(i))
    191             for i in (SLOT, ):
    192                 if i == '0':  # Hide default slot
    193                     v = '&nbsp;'
    194                 else:
    195                     v = html.escape(i)
    196                 lines.append('<td>%s</td>' % v)
    197             for i in (keyword_status, ):
    198                 lines.append('<td>%s</td>' % fix_empty(html.escape(i)))
    199             for i in (masked, unmasked, is_in_world):
    200                 v = i and 'X' or '&nbsp;'  # Hide False
    201                 lines.append('<td>%s</td>' % v)
    202             for i in (repo, ):
    203                 lines.append('<td>%s</td>' % fix_empty(html.escape(i)))
    204             final_flag_list = [x.startswith('-') and \
    205                     '<s>%s</s>' % html.escape(x.lstrip('-')) or \
    206                     html.escape(x) for x in \
    207                     compress_use_flags(sorted_flags_list)]
    208             lines.append('<td>%s</td>' % fix_empty(', '.join(final_flag_list)))
    209             lines.append('</tr>')
    210         lines.append('</table>')
    211 
    212     def dump_rst(self, lines):
    213         lines.append('Installed packages')
    214         lines.append('-----------------------------')
    215         for list in self._cpv_flag_list:
    216             package_name, version_revision, SLOT, keyword_status, \
    217                 masked, unmasked, is_in_world, repo, sorted_flags_list = \
    218                 list
    219 
    220             lines.append('- %s-%s' % (package_name, version_revision))
    221 
    222             if SLOT != '0':  # Hide default slot
    223                 lines.append('  - Slot: %s' % (SLOT))
    224             if keyword_status:
    225                 lines.append('  - Keyword status: %s' % keyword_status)
    226 
    227             tag_names = ('masked', 'unmasked', 'world')
    228             values = (masked, unmasked, is_in_world)
    229             tags = []
    230             for i, v in enumerate(values):
    231                 if v:
    232                     tags.append(tag_names[i])
    233             if tags:
    234                 lines.append('  - Tags: %s' % ', '.join(tags))
    235 
    236             if repo:
    237                 lines.append('  - Repository: %s' % (repo))
    238             if sorted_flags_list:
    239                 final_flag_list = [x.startswith('-') and x or ('+' + x) for x in \
    240                         compress_use_flags(sorted_flags_list)]
    241                 lines.append('  - Use flags: %s' % ', '.join(final_flag_list))
    242 
    243     def _dump(self):
    244         lines = []
    245         self.dump_rst(lines)
    246         print '\n'.join(lines)
    247         print
    248 
    249     """
    250     def dump(self):
    251         print 'Installed packages:'
    252         for list in self._cpv_flag_list:
    253             package_name, version_revision, SLOT, keyword_status, \
    254                 masked, unmasked, is_in_world, repository, sorted_flags_list = \
    255                 list
    256             tags = [e for e in [
    257                 masked and 'MASKED' or '',
    258                 unmasked and 'UNMASKED' or '',
    259                 is_in_world and 'WORLD' or ''] if e]
    260             print [package_name, version_revision, SLOT, keyword_status,
    261                 tags, repository, sorted_flags_list]
    262         print
    263         print '  Total: ' + str(self.total_count())
    264         print '    Known: ' + str(self.known_count())
    265         print '    Private: ' + str(self.private_count())
    266         print
    267     """
    268 
    269 if __name__ == '__main__':
    270     def cb_enter(cpv, i, count):
    271         print '[%s/%s] %s' % (i, count, cpv)
    272 
    273     installed_packages = InstalledPackages(debug=True, cb_enter=cb_enter)
    274     installed_packages._dump()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/main.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/main.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/main.py
    deleted file mode 100644
    index 36772f1..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import os
    20 from distros.distro import Distro
    21 import distros.shared.html as html
    22 
    23 
    24 _PRIVACY_METRICS_COLUMN_HEADERS = ('Data class', 'Publish', \
    25         'Count private', 'Count non-private')
    26 
    27 _DATA_CLASS_LABEL_MAP = {
    28     'arch_related':'Architecture-related',
    29     'call_flags_cflags':'Compile flags (CFLAGS)',
    30     'call_flags_cxxflags':'Compile flags (CXXFLAGS)',
    31     'call_flags_ldflags':'Compile flags (LDFLAGS)',
    32     'call_flags_makeopts':'Compile flags (MAKEOPTS)',
    33     'features_profile':'Features (system profile)',
    34     'features_make_conf':'Features (make.conf)',
    35     'features_make_globals':'Features (make.globals)',
    36     'features_final':'Features (combined)',
    37     'global_use_flags_make_conf':'Global use flags (make.conf)',
    38     'global_use_flags_profile':'Global use flags (system profile)',
    39     'global_use_flags_final':'Global use flags (combined)',
    40     'installed_packages':'Installed packages: General',
    41     'installed_packages_use_flags':'Installed packages: Use flags',
    42     'mirrors_distfiles':'Mirrors: Distfiles',
    43     'mirrors_sync':'Mirrors: Package tree',
    44     'package_mask':'Package mask entries',
    45     'repos':'Repositories',
    46     'system_profile':'System profile',
    47 }
    48 
    49 def _data_class_key_to_label(key):
    50     try:
    51         return _DATA_CLASS_LABEL_MAP[key]
    52     except KeyError:
    53         return key
    54 
    55 
    56 class _Gentoo(Distro):
    57     def key(self):
    58         return 'gentoo'
    59 
    60     def detected(self, debug=False):
    61         """
    62         Returns True if we run on top of Gentoo, else False.
    63         """
    64         return os.path.exists('/etc/gentoo-release')
    65 
    66     def gather(self, debug=False):
    67         def _stage(text):
    68             print 'Processing %s' % (text)
    69         # Local imports to not pull missing dependencies in
    70         # on non-Gentoo machines.
    71         from globaluseflags import GlobalUseFlags
    72         from compileflags import CompileFlags
    73         from mirrors import Mirrors
    74         from overlays import Overlays
    75         from packagestar import PackageMask
    76         from systemprofile import SystemProfile
    77         from trivials import Trivials
    78         from features import Features
    79         from installedpackages import InstalledPackages
    80 
    81         _stage('global use flags')
    82         global_use_flags = GlobalUseFlags()
    83 
    84         _stage('compile flags')
    85         compile_flags = CompileFlags()
    86 
    87         _stage('mirrors')
    88         mirrors = Mirrors(debug=debug)
    89 
    90         _stage('overlays')
    91         overlays = Overlays()
    92 
    93         _stage('package.mask entries')
    94         user_package_mask = PackageMask()
    95 
    96         _stage('features')
    97         features = Features()
    98 
    99         _stage('trivials')
    100         trivials = Trivials()
    101 
    102         _stage('installed packages (takes some time)')
    103         if debug:
    104             def cb_enter(cpv, i, count):
    105                 print '[% 3d%%] %s' % (i * 100 / count, cpv)
    106         else:
    107             def cb_enter(*_):
    108                 pass
    109         installed_packages = InstalledPackages(debug=debug, cb_enter=cb_enter)
    110 
    111         machine_data = {}
    112         html_lines = []
    113         rst_lines = []
    114         metrics_dict = {}
    115 
    116         html_lines.append('<h1>Gentoo</h1>')
    117         rst_lines.append('Gentoo')
    118         rst_lines.append('=================================')
    119         rst_lines.append('')
    120         machine_data['protocol'] = '1.2'
    121 
    122         trivials.dump_html(html_lines)
    123         trivials.dump_rst(rst_lines)
    124         rst_lines.append('')
    125         trivials.get_metrics(metrics_dict)
    126 
    127         machine_data['features'] = features.serialize()
    128         features.dump_html(html_lines)
    129         features.dump_rst(rst_lines)
    130         rst_lines.append('')
    131         features.get_metrics(metrics_dict)
    132 
    133         machine_data['call_flags'] = compile_flags.serialize()
    134         compile_flags.dump_html(html_lines)
    135         compile_flags.dump_rst(rst_lines)
    136         rst_lines.append('')
    137         compile_flags.get_metrics(metrics_dict)
    138 
    139         machine_data['mirrors'] = mirrors.serialize()
    140         mirrors.dump_html(html_lines)
    141         mirrors.dump_rst(rst_lines)
    142         rst_lines.append('')
    143         mirrors.get_metrics(metrics_dict)
    144 
    145         machine_data['repos'] = overlays.serialize()
    146         overlays.dump_html(html_lines)
    147         overlays.dump_rst(rst_lines)
    148         rst_lines.append('')
    149         overlays.get_metrics(metrics_dict)
    150 
    151         machine_data['user_package_mask'] = user_package_mask.serialize()
    152         user_package_mask.dump_html(html_lines)
    153         user_package_mask.dump_rst(rst_lines)
    154         rst_lines.append('')
    155         user_package_mask.get_metrics(metrics_dict)
    156 
    157         machine_data['global_use_flags'] = global_use_flags.serialize()
    158         global_use_flags.dump_html(html_lines)
    159         global_use_flags.dump_rst(rst_lines)
    160         rst_lines.append('')
    161         global_use_flags.get_metrics(metrics_dict)
    162 
    163         machine_data['installed_packages'] = installed_packages.serialize()
    164         installed_packages.dump_html(html_lines)
    165         installed_packages.dump_rst(rst_lines)
    166         installed_packages.get_metrics(metrics_dict)
    167 
    168         for container in (trivials, ):
    169             for k, v in container.serialize().items():
    170                 key = k.lower()
    171                 if key in machine_data:
    172                     raise Exception('Unintended key collision')
    173                 machine_data[key] = v
    174 
    175         machine_data['privacy_metrics'] = metrics_dict
    176         self.dump_metrics_html(html_lines, metrics_dict)
    177         rst_lines.append('')
    178         self.dump_metrics_rst(rst_lines, metrics_dict)
    179 
    180         excerpt_lines = []
    181         excerpt_lines.append('ACCEPT_KEYWORDS: ' + ' '.join(trivials.serialize()['accept_keywords']))
    182         excerpt_lines.append('CXXFLAGS: ' + ' '.join(compile_flags.serialize()['cxxflags']))
    183         excerpt_lines.append('MAKEOPTS: ' + ' '.join(compile_flags.serialize()['makeopts']))
    184         excerpt_lines.append('...')
    185 
    186         self._data = machine_data
    187         self._html = '\n'.join(html_lines)
    188         self._rst = '\n'.join(rst_lines)
    189         self._excerpt = '\n'.join(excerpt_lines)
    190 
    191     def dump_metrics_html(self, lines, metrics_dict):
    192         lines.append('<h2>Metrics</h2>')
    193         lines.append('Note: This meta data is also included with the submission.')
    194 
    195         lines.append('<table border="1" cellspacing="1" cellpadding="4">')
    196         lines.append('<tr>')
    197         for i in _PRIVACY_METRICS_COLUMN_HEADERS:
    198             lines.append('<th>%s</th>' % html.escape(i))
    199         lines.append('</tr>')
    200         for k, v in sorted(metrics_dict.items()):
    201             lines.append('<tr>')
    202             published, count_private, count_non_private = v
    203             for i in (_data_class_key_to_label(k), ):
    204                 lines.append('<td>%s</td>' % html.escape(i))
    205             for i in (published, ):
    206                 lines.append('<td align="center">%s</td>' % (i and 'yes' or 'no'))
    207             for i in (count_private, count_non_private):
    208                 lines.append('<td align="right">%s</td>' % html.escape(str(i)))
    209             lines.append('</tr>')
    210         lines.append('</table>')
    211 
    212         lines.append('<br>')
    213         lines.append('<br>')
    214         lines.append('Legend:')
    215         lines.append('<ul>')
    216         lines.append('<li>Data class: Label of the class of data</li>')
    217         lines.append('<li>Publish: Flag if data of this class will be submitted</li>')
    218         lines.append('<li>Count private: Number of entries not to be submitted</li>')
    219         lines.append('<li>Count non-private: Number of entries to be submitted</li>')
    220         lines.append('</ul>')
    221 
    222     def dump_metrics_rst(self, lines, metrics_dict):
    223         max_length = [2, 2, 2, 2]
    224         def final_values(column_values):
    225             res = list(column_values)
    226             res[0] = res[0] + ' '
    227             res[1] = res[1] and 'yes' or 'no'
    228             return tuple(res)
    229 
    230         def measure_line(column_values):
    231             for i, v in enumerate(column_values):
    232                 cur_len = 2 + len(str(v))
    233                 if cur_len > max_length[i]:
    234                     max_length[i] = cur_len
    235         def put_seperator(lines):
    236             lines.append('+%s+' % '+'.join('-'*e for e in max_length))
    237 
    238         def put_line(lines, column_values):
    239             lines.append('|%s|' % '|'.join(\
    240                 (i >= 2) and \
    241                     (' '*(max_length[i] - len(str(v)) - 1) + str(v)) + ' ' \
    242                 or \
    243                     (' ' + (str(v) + ' '*(max_length[i] - len(str(v)) - 1))) \
    244                 for i, v in enumerate(column_values)))
    245 
    246         lines.append('Metrics')
    247         lines.append('-----------------------------')
    248         lines.append('Note: This meta data is also included with the submission.')
    249         measure_line(_PRIVACY_METRICS_COLUMN_HEADERS)
    250         for k, v in metrics_dict.items():
    251             published, count_private, count_non_private = v
    252             measure_line(final_values((_data_class_key_to_label(k), ) + v))
    253         put_seperator(lines)
    254         put_line(lines, _PRIVACY_METRICS_COLUMN_HEADERS)
    255         for k, v in sorted(metrics_dict.items()):
    256             published, count_private, count_non_private = v
    257             put_seperator(lines)
    258             put_line(lines, final_values((_data_class_key_to_label(k), published, count_private, count_non_private)))
    259         put_seperator(lines)
    260         lines.append('')
    261         lines.append('Legend:')
    262         lines.append('- Data class: Label of the class of data')
    263         lines.append('- Publish: Flag if data of this class will be submitted')
    264         lines.append('- Count private: Number of entries not to be submitted')
    265         lines.append('- Count non-private: Number of entries to be submitted')
    266 
    267     def data(self):
    268         return self._data
    269 
    270     def html(self):
    271         return self._html
    272 
    273     def rst(self):
    274         return self._rst
    275 
    276     def rst_excerpt(self):
    277         return self._excerpt
    278 
    279 
    280 _gentoo_instance = None
    281 def Gentoo():
    282     """
    283     Simple singleton wrapper around _Gentoo class
    284     """
    285     global _gentoo_instance
    286     if _gentoo_instance == None:
    287         _gentoo_instance = _Gentoo()
    288     return _gentoo_instance
    289 
    290 
    291 if __name__ == '__main__':
    292     # Enable auto-flushing for stdout
    293     import sys
    294     sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
    295 
    296     Gentoo().gather(debug=True)
    297     """
    298     from simplejson import JSONEncoder
    299     print JSONEncoder(indent=2, sort_keys=True).encode(
    300         Gentoo().data())
    301     """
    302     print Gentoo().rst()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/makeopts.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/makeopts.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/makeopts.py
    deleted file mode 100644
    index 6bff9c4..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import re
    20 import portage
    21 
    22 SHORT_PARA_PATTERN = '-[CfIOW]\\s+\\S+|-[jl](\\s+[^-]\\S*)?|-[^-]\\S+'
    23 LONG_PARA_PATTERN = '--\\S+|--\\S+=\\S+'
    24 PARA_PATTERN = re.compile('(%s|%s)\\b' % (SHORT_PARA_PATTERN, LONG_PARA_PATTERN))
    25 
    26 class MakeOpts:
    27     def __init__(self):
    28         self._makeopts = self._parse(portage.settings['MAKEOPTS'])
    29 
    30     def _parse(self, flags):
    31         list = []
    32         for m in re.finditer(PARA_PATTERN, flags):
    33             text = re.sub('\\s{2,}', ' ', m.group()) # Normalize whitespace
    34             list.append(text)
    35         return list
    36 
    37     def get(self):
    38         return self._makeopts
    39 
    40     def serialize(self):
    41         return self._makeopts
    42 
    43     def dump(self):
    44         print 'MAKEOPTS: ' + str(self.get())
    45         print
    46 
    47 if __name__ == '__main__':
    48     MakeOpts = MakeOpts()
    49     MakeOpts.dump()
    50 
    51 """
    52 Samples
    53 -C dir -f file -I dir -o file -W file -j 3 -l 4 -j -l --always-make
    54 """
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/mirrors.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/mirrors.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/mirrors.py
    deleted file mode 100644
    index 7b46fa5..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import re
    20 import urlparse
    21 import portage
    22 from mirrorselect.mirrorparser3 import MirrorParser3, MIRRORS_3_XML
    23 from tools.syncfile import SyncFile
    24 from xml.parsers.expat import ExpatError
    25 import logging
    26 
    27 import os
    28 import sys
    29 import distros.shared.html as html
    30 from gate import Gate
    31 
    32 try:
    33     set
    34 except NameError:
    35     from sets import Set as set  # Python 2.3 fallback
    36 
    37 
    38 _EXTRA_DISTFILES_MIRRORS_WHITELIST = (
    39     "http://distfiles.gentoo.org",  # main mirror, not in mirrors3.xml
    40     "http://www.ibiblio.org/pub/Linux/distributions/gentoo",  # www != distro
    41 )
    42 _SCHEME_REGEX = re.compile('^[a-zA-Z][a-zA-Z0-9+.-]*:')
    43 
    44 
    45 def _normalize_url(url):
    46     return _SCHEME_REGEX.sub('xxxxx:', url).rstrip('/')
    47 
    48 
    49 class Mirrors:
    50     def __init__(self, debug=False):
    51         self._publish_mirrors_sync = Gate().grants('gentoo', 'mirrors_sync')
    52         self._publish_mirrors_distfiles = Gate().grants('gentoo', 'mirrors_distfiles')
    53 
    54         if self._publish_mirrors_distfiles:
    55             all_urls = self._collect_used_mirror_urls()
    56             self._mirror_urls = [url for url in
    57                     all_urls if
    58                     _normalize_url(url) in self._collect_known_mirror_urls()]
    59             if debug:
    60                 private_mirrors = [url for url in all_urls if
    61                     _normalize_url(url) not in self._collect_known_mirror_urls()]
    62                 for i in private_mirrors:
    63                     print '  distfiles mirror "%s" is private' % (i)
    64 
    65             self._mirrors_distfiles_count_non_private = len(self._mirror_urls)
    66             self._mirrors_distfiles_count_private = len(all_urls) - \
    67                     self._mirrors_distfiles_count_non_private
    68         else:
    69             self._mirror_urls = []
    70             self._mirrors_distfiles_count_non_private = 0
    71             self._mirrors_distfiles_count_private = 0
    72 
    73         if self._publish_mirrors_sync:
    74             self._sync_url = self._get_sync_url(debug=debug)
    75         else:
    76             self._sync_url = 'WITHHELD'
    77 
    78     def _collect_used_mirror_urls(self):
    79         return [e for e in \
    80             portage.settings['GENTOO_MIRRORS'].split(' ') if e != '']
    81 
    82     def _get_sync_url(self, debug=False):
    83         sync_url = portage.settings['SYNC']
    84         if (sync_url == None) or (sync_url.isspace()):
    85             sync_url = '<using non-rsync tree>'
    86         else:
    87             parsed = urlparse.urlparse(sync_url)
    88             if (parsed.hostname == None) or not (\
    89                     parsed.hostname.endswith('gentoo.org') or \
    90                     parsed.hostname.endswith('prefix.freens.org')):
    91                 if debug:
    92                     print '  sync mirror "%s" is private' % (sync_url)
    93                 sync_url = 'WITHHELD'
    94         return sync_url
    95 
    96     def _collect_known_mirror_urls(self):
    97         sync_file = SyncFile(
    98             MIRRORS_3_XML,
    99             'mirrors3.xml')
    100 
    101         # Parse, retry atfer re-sync if errors
    102         try:
    103             for retry in (2, 1, 0):
    104                 file = open(sync_file.path(), 'r')
    105                 content = file.read()
    106                 file.close()
    107                 try:
    108                     parser = MirrorParser3()
    109                     parser.parse(content)
    110                 except ExpatError:
    111                     if retry > 0:
    112                         logging.info('Re-syncing %s due to parse errors' % sync_file.path())
    113                         sync_file.sync()
    114                     else:
    115                         return set()
    116         except IOError:
    117             return set()
    118 
    119         known_mirror_urls = [_normalize_url(e) for e in parser.uris()]
    120         extra_mirror_urls = [_normalize_url(e) for e in \
    121             _EXTRA_DISTFILES_MIRRORS_WHITELIST]
    122         return set(known_mirror_urls + extra_mirror_urls)
    123 
    124     def serialize(self):
    125         res = {
    126             'sync':self._sync_url,
    127             # NOTE:  Keep distfiles mirrors in original order as the order
    128             #        determines how likely/often a mirror is actually hit
    129             'distfiles':self._mirror_urls,
    130         }
    131         return res
    132 
    133     def get_metrics(self, target_dict):
    134         target_dict['mirrors_sync'] = (self._publish_mirrors_sync, \
    135                 0, \
    136                 self._publish_mirrors_sync and 1 or 0)
    137         target_dict['mirrors_distfiles'] = (self._publish_mirrors_distfiles, \
    138                 self._mirrors_distfiles_count_private, \
    139                 self._mirrors_distfiles_count_non_private)
    140 
    141     def dump_html(self, lines):
    142         lines.append('<h2>Mirrors</h2>')
    143 
    144         lines.append('<h3>Sync</h3>')
    145         lines.append('<ul>')
    146         lines.append('<li>%s</li>' % html.escape(self._sync_url))
    147         lines.append('</ul>')
    148 
    149         lines.append('<h3>Distfiles</h3>')
    150         lines.append('<ul>')
    151         for url in self._mirror_urls:
    152             lines.append('<li><a href="%(url)s">%(url)s</a></li>' % {'url':html.escape(url)})
    153         lines.append('</ul>')
    154 
    155     def dump_rst(self, lines):
    156         lines.append('Mirrors')
    157         lines.append('-----------------------------')
    158         lines.append('Package tree')
    159         lines.append('`````````````````````')
    160         lines.append(self._sync_url)
    161         lines.append('')
    162         lines.append('Distfiles')
    163         lines.append('`````````````````````')
    164         for v in self._mirror_urls:
    165             lines.append('- ' + v)
    166 
    167     def _dump(self):
    168         lines = []
    169         self.dump_rst(lines)
    170         print '\n'.join(lines)
    171         print
    172 
    173 if __name__ == '__main__':
    174     mirrors = Mirrors(debug=True)
    175     mirrors._dump()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/mirrorselect/mirrorparser3.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/mirrorselect/__init__.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/mirrorselect/__init__.py
    deleted file mode 100644
    index e69de29..0000000
    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/mirrorselect/mirrorparser3.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/mirrorselect/mirrorparser3.py
    deleted file mode 100644
    index 6efcc3d..0000000
    + -  
    1 #!/usr/bin/python
    2 
    3 # Mirrorselect 1.x
    4 # Tool for selecting Gentoo source and rsync mirrors.
    5 #
    6 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    7 #
    8 # This program is free software; you can redistribute it and/or modify
    9 # it under the terms of the GNU General Public License as published by
    10 # the Free Software Foundation; either version 2 of the License, or
    11 # (at your option) any later version.
    12 #
    13 # This program is distributed in the hope that it will be useful,
    14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16 # GNU General Public License for more details.
    17 #
    18 # You should have received a copy of the GNU General Public License
    19 # along with this program; if not, write to the Free Software
    20 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    21 
    22 from xml.etree import ElementTree as ET
    23 
    24 MIRRORS_3_XML = 'http://www.gentoo.org/main/en/mirrors3.xml'
    25 
    26 class MirrorParser3:
    27     def __init__(self):
    28         self._reset()
    29 
    30     def _reset(self):
    31         self._dict = {}
    32 
    33     def parse(self, text):
    34         self._reset()
    35         for mirrorgroup in ET.XML(text):
    36             for mirror in mirrorgroup:
    37                 name = ''
    38                 for e in mirror:
    39                     if e.tag == 'name':
    40                         name = e.text
    41                     if e.tag == 'uri':
    42                         uri = e.text
    43                         self._dict[uri] = name
    44 
    45     def tuples(self):
    46         return [(url, name) for url, name in self._dict.items()]
    47 
    48     def uris(self):
    49         return [url for url, name in self._dict.items()]
    50 
    51 if __name__ == '__main__':
    52     import urllib
    53     parser = MirrorParser3()
    54     parser.parse(urllib.urlopen(MIRRORS_3_XML).read())
    55     print '===== tuples'
    56     print parser.tuples()
    57     print '===== uris'
    58     print parser.uris()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/overlays.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/overlays.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/overlays.py
    deleted file mode 100644
    index f0e7266..0000000
    + -  
    1 # -*- coding: utf-8 -*-
    2 # smolt - Fedora hardware profiler
    3 #
    4 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    5 #
    6 # This program is free software; you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation; either version 2 of the License, or
    9 # (at your option) any later version.
    10 #
    11 # This program is distributed in the hope that it will be useful,
    12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 # GNU General Public License for more details.
    15 #
    16 # You should have received a copy of the GNU General Public License
    17 # along with this program; if not, write to the Free Software
    18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    19 
    20 import ConfigParser
    21 import portage
    22 from portage.const import REPO_NAME_LOC
    23 import re
    24 import os
    25 from portage import config
    26 from portage.versions import catpkgsplit
    27 from portage.dbapi.porttree import portdbapi
    28 from tools.maintreedir import main_tree_dir
    29 from tools.syncfile import SyncFile
    30 from tools.overlayparser import OverlayParser
    31 from xml.parsers.expat import ExpatError
    32 import logging
    33 
    34 import sys
    35 import distros.shared.html as html
    36 from gate import Gate
    37 from tools.wrappers import get_cp
    38 
    39 _REPO_NAME_WHITELIST = (
    40     "gentoo",  # Gentoo main tree
    41     "funtoo",  # Funtoo main tree
    42     "gentoo_prefix",  # Gentoo prefix main tree
    43 
    44     "g-ctan",  # app-portage/g-ctan target repository
    45 )
    46 
    47 _REPO_NAME_RENAME_MAP = {
    48     "bangert-ebuilds":"bangert",
    49     "china":"gentoo-china",
    50     "dev-jokey":"jokey",
    51     "digital-trauma.de":"trauma",
    52     "Falco's git overlay":"falco",
    53     "gcj-overlay":"java-gcj-overlay",
    54     "geki-overlay":"openoffice-geki",
    55     "gentoo-haskell":"haskell",
    56     "gentoo-lisp-overlay":"lisp",
    57     "kde4-experimental":"kde4-experimental",  # Keep as is (overlay "kde")
    58     "kde":"kde",  # Keep as is (overlay "kde-testing")
    59     "leio-personal":"leio",
    60     "maekke's overlay":"maekke",
    61     "majeru":"oss-overlay",
    62     "mpd-portage":"mpd",
    63     "ogo-lu_zero":"lu_zero",
    64     "pcsx2-overlay":"pcsx2",
    65     "proaudio":"pro-audio",
    66     "scarabeus_local_overlay":"scarabeus",
    67     "soor":"soor-overlay",
    68     "steev_github":"steev",
    69     "suka's dev overlay - experimental stuff of all sorts":"suka",
    70     "tante_overlay":"tante",
    71     "vdr-xine-overlay":"vdr-xine",
    72     "webapp-experimental":"webapps-experimental",
    73     "x-njw-gentoo-local":"njw",
    74 }
    75 
    76 class _Overlays:
    77     def __init__(self):
    78         self._publish = Gate().grants('gentoo', 'repositories')
    79         self._fill_overlays()
    80         tree_config = config()
    81         tree_config['PORTDIR_OVERLAY'] = ' '.join(self._get_active_paths())
    82         tree_config['PORTDIR'] = main_tree_dir()
    83         self._dbapi = portdbapi(main_tree_dir(), tree_config)
    84 
    85     def _parse_overlay_meta(self, filename):
    86         parser = OverlayParser()
    87         file = open(filename, 'r')
    88         parser.parse(file.read())
    89         file.close()
    90         return parser.get()
    91 
    92     def _get_known_overlay_map(self):
    93         sync_file = SyncFile(
    94                 'http://www.gentoo.org/proj/en/overlays/layman-global.txt',
    95                 'layman-global.txt')
    96 
    97         # Parse, retry atfer re-sync if errors
    98         try:
    99             for retry in (2, 1, 0):
    100                 try:
    101                     return self._parse_overlay_meta(sync_file.path())
    102                 except ExpatError:
    103                     if retry > 0:
    104                         logging.info('Re-syncing %s due to parse errors' % sync_file.path())
    105                         sync_file.sync()
    106         except IOError:
    107             pass
    108         return {}
    109 
    110     def _fill_overlays(self):
    111         self._global_overlays_dict = self._get_known_overlay_map()
    112         enabled_installed_overlays = \
    113                 portage.settings['PORTDIR_OVERLAY'].split(' ')
    114 
    115         def overlay_name(overlay_location):
    116             repo_name_file = os.path.join(overlay_location, REPO_NAME_LOC)
    117             file = open(repo_name_file, 'r')
    118             name = file.readline().strip()
    119             file.close()
    120             return name
    121 
    122         def is_non_private(overlay_location):
    123             try:
    124                 name = overlay_name(overlay_location)
    125             except:
    126                 return False
    127 
    128             # TODO improve
    129             return name in ('g-ctan', ) or \
    130                     (name in self._global_overlays_dict)
    131 
    132         def fix_repo_name(repo_name):
    133             try:
    134                 return _REPO_NAME_RENAME_MAP[repo_name]
    135             except KeyError:
    136                 return repo_name
    137 
    138         non_private_active_overlay_paths = [e for e in
    139                 enabled_installed_overlays if is_non_private(e)]
    140         non_private_active_overlay_names = [fix_repo_name(overlay_name(e)) \
    141                 for e in non_private_active_overlay_paths]
    142 
    143         # Dirty hack to get the main tree's name in, too
    144         main_tree_name = fix_repo_name(overlay_name(main_tree_dir()))
    145         enabled_installed_overlays.append(main_tree_name)
    146         if not self.is_private_overlay_name(main_tree_name):
    147             non_private_active_overlay_names.append(main_tree_name)
    148 
    149         self._active_overlay_paths = non_private_active_overlay_paths
    150         if self._publish:
    151             self._active_overlay_names = non_private_active_overlay_names
    152             self._repo_count_non_private = len(non_private_active_overlay_names)
    153             self._repo_count_private = len(enabled_installed_overlays) - \
    154                     self._repo_count_non_private
    155         else:
    156             self._active_overlay_names = []
    157             self._repo_count_non_private = 0
    158             self._repo_count_private = 0
    159 
    160     def _get_active_paths(self):
    161         return self._active_overlay_paths
    162 
    163     def is_private_package_atom(self, atom):
    164         cp = get_cp(atom)
    165         return not self._dbapi.cp_list(cp)
    166 
    167     def is_private_overlay_name(self, overlay_name):
    168         if not overlay_name:
    169             return True
    170 
    171         if overlay_name in _REPO_NAME_WHITELIST:
    172             return False
    173 
    174         if overlay_name in _REPO_NAME_RENAME_MAP:
    175             return False
    176 
    177         return not overlay_name in self._global_overlays_dict
    178 
    179     def serialize(self):
    180         return sorted(set(self._active_overlay_names))
    181 
    182     def get_metrics(self, target_dict):
    183         target_dict['repos'] = (self._publish, \
    184                 self._repo_count_private, \
    185                 self._repo_count_non_private)
    186 
    187     def dump_html(self, lines):
    188         lines.append('<h2>Repositories</h2>')
    189         lines.append('<ul>')
    190         for name in self.serialize():
    191             lines.append('<li><a href="http://gentoo-overlays.zugaina.org/%(name)s/">%(name)s</a></li>' % {'name':html.escape(name)})
    192         lines.append('</ul>')
    193 
    194     def dump_rst(self, lines):
    195         lines.append('Repositories')
    196         lines.append('-----------------------------')
    197         for v in self.serialize():
    198             lines.append('- ' + v)
    199 
    200     def _dump(self):
    201         lines = []
    202         self.dump_rst(lines)
    203         print '\n'.join(lines)
    204         print
    205 
    206     """
    207     def dump(self):
    208         print 'Active overlays:'
    209         print '  Names:'
    210         print self.get_active_names()
    211         print '  Paths:'
    212         print self._get_active_paths()
    213         print '  Total: ' + str(self.total_count())
    214         print '    Known: ' + str(self.known_count())
    215         print '    Private: ' + str(self.private_count())
    216         print
    217     """
    218 
    219 
    220 _overlays_instance = None
    221 def Overlays():
    222     """
    223     Simple singleton wrapper around _Overlays class
    224     """
    225     global _overlays_instance
    226     if _overlays_instance == None:
    227         _overlays_instance = _Overlays()
    228     return _overlays_instance
    229 
    230 
    231 if __name__ == '__main__':
    232     overlays = Overlays()
    233     overlays._dump()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/packageprivacy.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/packageprivacy.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/packageprivacy.py
    deleted file mode 100644
    index 821d905..0000000
    + -  
    1 # -*- coding: utf-8 -*-
    2 # smolt - Fedora hardware profiler
    3 #
    4 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    5 #
    6 # This program is free software; you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation; either version 2 of the License, or
    9 # (at your option) any later version.
    10 #
    11 # This program is distributed in the hope that it will be useful,
    12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 # GNU General Public License for more details.
    15 #
    16 # You should have received a copy of the GNU General Public License
    17 # along with this program; if not, write to the Free Software
    18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    19 
    20 import portage
    21 from portage.versions import catsplit
    22 from generatedpackages import GeneratedPackages
    23 from overlays import Overlays
    24 from tools.wrappers import get_cp
    25 
    26 def is_private_package_atom(atom, installed_from=None, debug=False):
    27     cat = catsplit(get_cp(atom))[0]
    28     if GeneratedPackages().is_generated_cat(cat):
    29         if GeneratedPackages().is_private_cat(cat):
    30             if debug:
    31                 print '  skipping "%s" (%s, %s)' % \
    32                     (atom, 'was generated', 'is currently blacklisted')
    33             return True
    34         else:
    35             if installed_from and \
    36                     installed_from[0] != '' and \
    37                     not GeneratedPackages().is_dedicated_repo_name(
    38                         installed_from[0]):
    39                 if debug:
    40                     print '  removing %s source tree "%s" for atom "%s"' % \
    41                     ('misleading', installed_from[0], atom)
    42                 installed_from[0] = ''
    43 
    44     if installed_from != None:
    45         """
    46         -   We collect private packages iff they come from a non-private
    47             overlay, because that means they were in there before and are
    48             actually not private.  An example would be media-sound/xmms.
    49 
    50         -   We collect packages from private overlays iff the package also
    51             exists in a non-private overlay.  An example would be that
    52             you posted your ebuild to bugs.gentoo.org and somebody added
    53             it to the tree in the meantime.
    54         """
    55         if not Overlays().is_private_overlay_name(installed_from[0]):
    56             return False
    57         if not Overlays().is_private_package_atom(atom):
    58             if installed_from and installed_from[0] != '':
    59                 if debug:
    60                     print '  removing %s source tree "%s" for atom "%s"' % \
    61                     ('private', installed_from[0], atom)
    62                 installed_from[0] = ''
    63             return False
    64         if debug:
    65             print '  skipping "%s" (%s, %s)' % \
    66                 (atom, 'was installed from private tree',
    67                 'is currently not in non-private tree')
    68         return True
    69     else:
    70         not_in_public_trees = Overlays().is_private_package_atom(atom)
    71         if debug and not_in_public_trees:
    72             print '  skipping "%s" (not in public trees)' % atom
    73         return not_in_public_trees
    74 
    75 
    76 if __name__ == '__main__':
    77     print is_private_package_atom('=cat/pkg-1.2', debug=True)
    78     print is_private_package_atom('=cat/pkg-1.2', installed_from=['gentoo', ],
    79         debug=True)
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/packagestar.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/packagestar.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/packagestar.py
    deleted file mode 100644
    index 8370637..0000000
    + -  
    1 # -*- coding: utf-8 -*-
    2 # smolt - Fedora hardware profiler
    3 #
    4 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    5 #
    6 # This program is free software; you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation; either version 2 of the License, or
    9 # (at your option) any later version.
    10 #
    11 # This program is distributed in the hope that it will be useful,
    12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 # GNU General Public License for more details.
    15 #
    16 # You should have received a copy of the GNU General Public License
    17 # along with this program; if not, write to the Free Software
    18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    19 
    20 from collections import defaultdict
    21 import os
    22 import portage
    23 from packageprivacy import is_private_package_atom
    24 
    25 import sys
    26 import distros.shared.html as html
    27 from gate import Gate
    28 from tools.wrappers import get_cp
    29 
    30 class _PackageStar:
    31     def __init__(self):
    32         pass
    33 
    34     def _init(self, section, metrics_key, privacy_filter):
    35         self._section = section
    36         self._metrics_key = metrics_key
    37         self._privacy_filter = privacy_filter
    38 
    39         self._publish = Gate().grants('gentoo', self._metrics_key)
    40         self._collect()
    41 
    42     def _locations(self):
    43         return [os.path.join(
    44             portage.settings["PORTAGE_CONFIGROOT"],
    45             portage.USER_CONFIG_PATH.lstrip(os.path.sep))]
    46 
    47     def _collect(self):
    48         self._non_private_cp_to_atoms = defaultdict(list)
    49         self._private_cp_to_atoms = defaultdict(list)
    50         self._total_count = 0
    51         self._private_count = 0
    52         for location in self._locations():
    53             for x in portage.grabfile_package(
    54                     os.path.join(location, self._section), recursive = 1):
    55                 self._total_count = self._total_count + 1
    56                 if x.startswith('-'):
    57                     print '  no proper support for "-cat/pkg" style entry "%s" yet, sorry.' % x.strip()
    58                     continue
    59                 cp = get_cp(x)
    60                 if self._privacy_filter and is_private_package_atom(cp):
    61                     self._private_count = self._private_count + 1
    62                     dict_ref = self._private_cp_to_atoms
    63                 else:
    64                     dict_ref = self._non_private_cp_to_atoms
    65 
    66                 merge_with = set([x])
    67                 if cp in dict_ref:
    68                     dict_ref[cp] = dict_ref[cp].union(merge_with)
    69                 else:
    70                     dict_ref[cp] = merge_with
    71 
    72     def total_count(self):
    73         return self._total_count
    74 
    75     def private_count(self):
    76         return self._private_count
    77 
    78     def known_count(self):
    79         return self.total_count() - self.private_count()
    80 
    81     def _hits(self, cpv, dict_ref):
    82         test_atom = '=' + cpv
    83         cp = get_cp(test_atom)
    84         if cp not in dict_ref:
    85             return False
    86         for a in dict_ref[cp]:
    87             if portage.dep.get_operator(a) == None:
    88                 return True
    89             elif not not portage.dep.match_from_list(test_atom, [a]):
    90                 return True
    91         return False
    92 
    93     def hits(self, cpv):
    94         for dict_ref in (self._non_private_cp_to_atoms, self._private_cp_to_atoms):
    95             if self._hits(cpv, dict_ref):
    96                 return True
    97         return False
    98 
    99     def serialize(self):
    100         res = {}
    101         if self._publish:
    102             for cp, atoms in self._non_private_cp_to_atoms.items():
    103                 res[cp] = sorted(atoms)
    104         return res
    105 
    106     def get_metrics(self, target_dict):
    107         if self._publish:
    108             target_dict[self._metrics_key] = (True, \
    109                     self._private_count, \
    110                     self._total_count - self._private_count)
    111         else:
    112             target_dict[self._metrics_key] = (False, 0, 0)
    113 
    114     def dump_html(self, lines):
    115         lines.append('<h2>%s</h2>' % html.escape(self._section))
    116         lines.append('<ul>')
    117         for atoms in self.serialize().values():
    118             for v in atoms:
    119                 lines.append('<li>%s</li>' % html.escape(v))
    120         lines.append('</ul>')
    121 
    122     def dump_rst(self, lines):
    123         lines.append(self._section)
    124         len_a = len('-----------------------------')
    125         len_b = len(self._section)
    126         lines.append('-' * max(len_a, len_b))
    127         for atoms in self.serialize().values():
    128             for v in atoms:
    129                 lines.append('- %s' % v)
    130 
    131     def _dump(self):
    132         lines = []
    133         self.dump_rst(lines)
    134         print '\n'.join(lines)
    135         print
    136 
    137 
    138 class _PackageMask(_PackageStar):
    139     def __init__(self):
    140         self._init('package.mask', 'package_mask', privacy_filter=True)
    141 
    142 
    143 class _PackageUnmask(_PackageStar):
    144     def __init__(self):
    145         self._init('package.unmask', 'package_unmask', privacy_filter=True)
    146 
    147 
    148 class _ProfilePackageMask(_PackageStar):
    149     def __init__(self):
    150         self._init('package.mask', 'profile_package_mask', privacy_filter=False)
    151 
    152     def _locations(self):
    153         main_tree_profiles = [os.path.join(portage.settings["PORTDIR"],
    154             "profiles")] + list(portage.settings.profiles)  # TODO break potential
    155         overlay_profiles = [os.path.join(e, "profiles") for e in \
    156             portage.settings["PORTDIR_OVERLAY"].split()]
    157         return[e for e in main_tree_profiles + overlay_profiles if \
    158             os.path.isdir(e)]
    159 
    160 
    161 _package_unmask_instance = None
    162 def PackageUnmask():
    163     """
    164     Simple singleton wrapper around _PackageUnmask class
    165     """
    166     global _package_unmask_instance
    167     if _package_unmask_instance == None:
    168         _package_unmask_instance = _PackageUnmask()
    169     return _package_unmask_instance
    170 
    171 
    172 _package_mask_instance = None
    173 def PackageMask():
    174     """
    175     Simple singleton wrapper around _PackageMask class
    176     """
    177     global _package_mask_instance
    178     if _package_mask_instance == None:
    179         _package_mask_instance = _PackageMask()
    180     return _package_mask_instance
    181 
    182 
    183 _profile_package_mask_instance = None
    184 def ProfilePackageMask():
    185     """
    186     Simple singleton wrapper around _ProfilePackageMask class
    187     """
    188     global _profile_package_mask_instance
    189     if _profile_package_mask_instance == None:
    190         _profile_package_mask_instance = _ProfilePackageMask()
    191     return _profile_package_mask_instance
    192 
    193 
    194 if __name__ == '__main__':
    195     package_mask = PackageMask()
    196     package_mask._dump()
    197     """
    198     package_unmask = PackageUnmask()
    199     package_unmask._dump()
    200     profile_package_mask = ProfilePackageMask()
    201     profile_package_mask._dump()
    202     """
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/systemprofile.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/systemprofile.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/systemprofile.py
    deleted file mode 100644
    index d6d464b..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import os
    20 import re
    21 import portage
    22 from tools.maintreedir import main_tree_dir
    23 
    24 class SystemProfile:
    25     def __init__(self):
    26         self._profile = self._filter(self._get_profile())
    27 
    28     def _get_profile(self):
    29         # expand make.profile symlink
    30         return os.path.realpath(portage.settings.profile_path)
    31 
    32     def _collect_known_profiles(self):
    33         # TODO extract to parser class?
    34         f = open('%s/profiles/profiles.desc' % main_tree_dir(), 'r')
    35         subst_pattern = re.compile('^[^ #]+\s+(\S+)\s+\S+\s*$')
    36         lines = [re.sub(subst_pattern, '\\1', l) for l in
    37                 f.readlines() if re.match(subst_pattern, l)]
    38         f.close()
    39         return set(lines)
    40 
    41     def _filter(self, profile):
    42         known_profiles_set = self._collect_known_profiles()
    43         for p in known_profiles_set:
    44             if profile.endswith('/' + p):
    45                 return p
    46         return '<private profile>'
    47 
    48     def get(self):
    49         return self._profile
    50 
    51     def dump(self):
    52         print 'System profile: ' + self._profile
    53         print
    54 
    55 if __name__ == '__main__':
    56     systemprofile = SystemProfile()
    57     systemprofile.dump()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/conf.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/__init__.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/__init__.py
    deleted file mode 100644
    index e69de29..0000000
    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/conf.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/conf.py
    deleted file mode 100644
    index db352bd..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import os
    20 
    21 # TODO move somewhere else?
    22 SMOLT_CONFIG_DIR = os.path.expanduser('~/.smolt')
    23 
    24 def get_user_config_dir():
    25     return SMOLT_CONFIG_DIR
    26 
    27 def get_system_config_dir():
    28     return '/etc/smolt'
    29 
    30 def ensure_user_config_dir_exists():
    31     # TODO improve
    32     DIR_EXISTS_ERRNO = 17
    33     try:
    34         os.mkdir(SMOLT_CONFIG_DIR, 0700)
    35     except OSError, e:
    36         if e.errno != DIR_EXISTS_ERRNO:
    37             raise e
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/maintreedir.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/maintreedir.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/maintreedir.py
    deleted file mode 100644
    index c9dd9f9..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import portage
    20 
    21 def main_tree_dir():
    22     portdir = portage.settings['PORTDIR']
    23     if (portdir != None) and not portdir.isspace():
    24         portdir = portdir.strip().rstrip('/')
    25         if portdir != '':
    26             return portdir
    27     return '/usr/portage'
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/overlayparser.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/overlayparser.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/overlayparser.py
    deleted file mode 100644
    index 3dcf098..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 from xml.etree import ElementTree as ET
    20 
    21 class OverlayParser:
    22     def __init__(self):
    23         pass
    24 
    25     def parse(self, text):
    26         self._overlay_name_to_url_map = {}
    27         for i in ET.XML(text):
    28             try:
    29                 overlay_url = i.attrib['src']
    30                 overlay_name = i.attrib['name']
    31                 self._overlay_name_to_url_map[overlay_name] = overlay_url
    32             except KeyError:
    33                 pass
    34 
    35     def get(self):
    36         return self._overlay_name_to_url_map
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/syncfile.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/syncfile.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/syncfile.py
    deleted file mode 100644
    index e44977a..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import os
    20 from stat import *
    21 import conf
    22 import urllib2
    23 from datetime import date, datetime
    24 
    25 MAX_AGE_IN_SECONDS = 5 * 60
    26 
    27 def resolve_basename(local_basename):
    28     return '%s/%s' % (conf.get_user_config_dir(), local_basename)
    29 
    30 class SyncFile:
    31     def __init__(self, url, local_basename):
    32         self.remote_location = url
    33         self.local_location = resolve_basename(local_basename)
    34         conf.ensure_user_config_dir_exists()
    35         if self._sync_needed():
    36             self.sync()
    37 
    38     def path(self):
    39         return self.local_location
    40 
    41     def _sync_needed(self):
    42         try:
    43             mod_datetime = datetime.fromtimestamp(
    44                     os.stat(self.local_location)[ST_MTIME])
    45             age_in_seconds = (datetime.now() - mod_datetime).seconds
    46             if age_in_seconds < MAX_AGE_IN_SECONDS:
    47                 return False
    48         except:
    49             pass
    50         return True
    51 
    52     def sync(self):
    53         opener = urllib2.build_opener()
    54         try:
    55             remote_file = opener.open(self.remote_location)
    56             local_file = open(self.local_location, 'w')
    57             local_file.write(remote_file.read())
    58             local_file.close()
    59             remote_file.close()
    60         except urllib2.HTTPError:
    61             pass
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/wrappers.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/wrappers.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/tools/wrappers.py
    deleted file mode 100644
    index b39d420..0000000
    + -  
    1 # -*- coding: utf-8 -*-
    2 # smolt - Fedora hardware profiler
    3 #
    4 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    5 #
    6 # This program is free software; you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation; either version 2 of the License, or
    9 # (at your option) any later version.
    10 #
    11 # This program is distributed in the hope that it will be useful,
    12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 # GNU General Public License for more details.
    15 #
    16 # You should have received a copy of the GNU General Public License
    17 # along with this program; if not, write to the Free Software
    18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    19 
    20 import portage
    21 
    22 def get_cp(atom):
    23     if isinstance(atom, portage.dep.Atom):
    24         instance = atom
    25     else:
    26         instance = portage.dep.Atom(atom)
    27     return instance.cp
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/trivials.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/trivials.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/trivials.py
    deleted file mode 100644
    index d746c40..0000000
    + -  
    1 # smolt - Fedora hardware profiler
    2 #
    3 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    4 #
    5 # This program is free software; you can redistribute it and/or modify
    6 # it under the terms of the GNU General Public License as published by
    7 # the Free Software Foundation; either version 2 of the License, or
    8 # (at your option) any later version.
    9 #
    10 # This program is distributed in the hope that it will be useful,
    11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13 # GNU General Public License for more details.
    14 #
    15 # You should have received a copy of the GNU General Public License
    16 # along with this program; if not, write to the Free Software
    17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    18 
    19 import portage
    20 from systemprofile import SystemProfile
    21 
    22 import os
    23 import sys
    24 import distros.shared.html as html
    25 from gate import Gate
    26 
    27 class Trivials:
    28     def __init__(self):
    29         self._publish_arch_related = Gate().grants('gentoo', 'arch_related')
    30         self._publish_system_profile = Gate().grants('gentoo', 'system_profile')
    31 
    32         self._trivials = {}
    33 
    34         self._trivial_scalars = {}
    35         for upper in ('ARCH', 'CHOST'):
    36             value = portage.settings[upper].strip()
    37             lower = upper.lower()
    38             if self._publish_arch_related:
    39                 self._trivial_scalars[lower] = value
    40             else:
    41                 self._trivial_scalars[lower] = 'WITHHELD'
    42             self._trivials[lower] = self._trivial_scalars[lower]
    43 
    44         if self._publish_system_profile:
    45             system_profile = SystemProfile().get()
    46         else:
    47             system_profile = 'WITHHELD'
    48         self._trivial_scalars['system_profile'] = system_profile
    49         self._trivials['system_profile'] = self._trivial_scalars['system_profile']
    50 
    51         self._trivial_vectors = {}
    52         self._trivial_vectors['accept_keywords'] = \
    53             self._accept_keywords()
    54         self._trivials['accept_keywords'] = \
    55             self._trivial_vectors['accept_keywords']
    56 
    57     def _accept_keywords(self):
    58         if not self._publish_arch_related:
    59             return []
    60 
    61         # Let '~arch' kill 'arch' so we don't get both
    62         list = portage.settings['ACCEPT_KEYWORDS'].split(' ')
    63         unstable = set(e for e in list if e.startswith('~'))
    64         return [e for e in list if not ('~' + e) in unstable]
    65 
    66     def serialize(self):
    67         return self._trivials
    68 
    69     def get_metrics(self, target_dict):
    70         target_dict['arch_related'] = (self._publish_arch_related, \
    71                 0, \
    72                 self._publish_arch_related and 3 or 0)
    73         target_dict['system_profile'] = (self._publish_system_profile, \
    74                 0, \
    75                 self._publish_system_profile and 1 or 0)
    76 
    77     def dump_html(self, lines):
    78         lines.append('<h2>General</h2>')
    79         key_data = {
    80             'arch':'ARCH',
    81             'chost':'CHOST',
    82             'accept_keywords':'ACCEPT_KEYWORDS',
    83             'system_profile':'System Profile',
    84         }
    85         for k, label in sorted(key_data.items()):
    86             v = self._trivials[k]
    87             lines.append('<dl>')
    88             lines.append('<dt>%s</dt>' % html.escape(label))
    89             if type(v).__name__ == 'list':
    90                 lines.append('<dd>%s</dd>' % html.escape(', '.join(v)))
    91             else:
    92                 lines.append('<dd>%s</dd>' % html.escape(v))
    93             lines.append('</dl>')
    94 
    95     def dump_rst(self, lines):
    96         lines.append('General')
    97         lines.append('-----------------------------')
    98         key_data = {
    99             'arch':'ARCH',
    100             'chost':'CHOST',
    101             'accept_keywords':'ACCEPT_KEYWORDS',
    102             'system_profile':'System Profile',
    103         }
    104         for k, label in sorted(key_data.items()):
    105             v = self._trivials[k]
    106             lines.append(label)
    107             if type(v).__name__ == 'list':
    108                 lines.append('  %s' % ', '.join(v))
    109             else:
    110                 lines.append('  %s' % str(v))
    111             lines.append('')
    112 
    113     def _dump(self):
    114         lines = []
    115         self.dump_rst(lines)
    116         print '\n'.join(lines)
    117         print
    118 
    119     """
    120     def dump(self):
    121         print 'Trivial scalars:'
    122         for k, v in self._trivial_scalars.items():
    123             print '  %s: %s' % (k, v)
    124         print 'Trivial vectors:'
    125         for k, v in self._trivial_vectors.items():
    126             print '  %s: %s' % (k, v)
    127         print
    128     """
    129 
    130 if __name__ == '__main__':
    131     trivials = Trivials()
    132     trivials._dump()
  • deleted file mythtv/programs/scripts/hardwareprofile/distros/gentoo/worldset.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/gentoo/worldset.py b/mythtv/programs/scripts/hardwareprofile/distros/gentoo/worldset.py
    deleted file mode 100644
    index fcab7fd..0000000
    + -  
    1 # -*- coding: utf-8 -*-
    2 # smolt - Fedora hardware profiler
    3 #
    4 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    5 #
    6 # This program is free software; you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation; either version 2 of the License, or
    9 # (at your option) any later version.
    10 #
    11 # This program is distributed in the hope that it will be useful,
    12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 # GNU General Public License for more details.
    15 #
    16 # You should have received a copy of the GNU General Public License
    17 # along with this program; if not, write to the Free Software
    18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    19 
    20 import os
    21 import portage
    22 from portage.const import WORLD_FILE
    23 from packageprivacy import is_private_package_atom
    24 
    25 class _WorldSet:
    26     def __init__(self):
    27         self._collect()
    28 
    29     def _collect(self):
    30         config_root = portage.settings["PORTAGE_CONFIGROOT"]
    31         world_file = os.path.join(config_root, WORLD_FILE)
    32         file = open(world_file, 'r')
    33         self._all_cps = [line.rstrip("\r\n") for line in file]
    34         self._total_count = len(self._all_cps)
    35         self._known_cps = set([e for e in self._all_cps if \
    36             not is_private_package_atom(e)])
    37         self._private_count = self._total_count - len(self._known_cps)
    38         file.close()
    39 
    40     def get(self):
    41         """
    42         Returns a set of <cat-pkg> and <cat-pkg-slot> atoms
    43         """
    44         return self._known_cps
    45 
    46     def contains(self, cat, pkg, slot):
    47         if slot in (None, '', '0'):
    48             world_set_test = '%s/%s' % (cat, pkg)
    49         else:
    50             world_set_test = '%s/%s:%s' % (cat, pkg, slot)
    51         return world_set_test in self._all_cps
    52 
    53     def total_count(self):
    54         return self._total_count
    55 
    56     def private_count(self):
    57         return self._private_count
    58 
    59     def known_count(self):
    60         return self.total_count() - self.private_count()
    61 
    62     def dump(self):
    63         print 'World:'
    64         for i in self._known_cps:
    65             print i
    66         print 'Total: ' + str(self.total_count())
    67         print '  Known: ' + str(self.known_count())
    68         print '  Private: ' + str(self.private_count())
    69         print
    70 
    71 
    72 _world_set_instance = None
    73 def WorldSet():
    74     """
    75     Simple singleton wrapper around _WorldSet class
    76     """
    77     global _world_set_instance
    78     if _world_set_instance == None:
    79         _world_set_instance = _WorldSet()
    80     return _world_set_instance
    81 
    82 
    83 if __name__ == '__main__':
    84     worldset = WorldSet()
    85     worldset.dump()
  • new file mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/data_mythtv.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/__init__.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/data_mythtv.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/data_mythtv.py
    new file mode 100755
    index 0000000..75bef18
    - +  
     1# -*- coding: utf-8 -*-
     2# smolt - Fedora hardware profiler
     3#
     4# Copyright (C) 2011 Raymond Wagner <raymond@wagnerrp.com>
     5# Copyright (C) 2011 james meyer <james.meyer@operamail.com>
     6#
     7# This program is free software; you can redistribute it and/or modify
     8# it under the terms of the GNU General Public License as published by
     9# the Free Software Foundation; either version 2 of the License, or
     10# (at your option) any later version.
     11#
     12# This program is distributed in the hope that it will be useful,
     13# but WITHOUT ANY WARRANTY; without even the implied warranty of
     14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15# GNU General Public License for more details.
     16#
     17# You should have received a copy of the GNU General Public License
     18# along with this program; if not, write to the Free Software
     19# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     20
     21
     22import os
     23import re
     24import statvfs
     25from i18n import _
     26from datetime import timedelta
     27
     28from orddict import OrdDict
     29from uuiddb import UuidDb
     30
     31import MythTV
     32from user import home
     33
     34_DB = MythTV.MythDB()
     35_BE = MythTV.MythBE(db=_DB)
     36_SETTINGS = _DB.settings[_DB.gethostname()]
     37prefix = 'mythtv'
     38
     39class _Mythtv_data:
     40    def __init__(self, gate):
     41        self.get_data(gate)
     42       
     43    def isBackend(self):
     44        return (_SETTINGS.BackendServerIP is not None)
     45
     46    def ProcessVersion(self):
     47        data = OrdDict()
     48        for name in ['version', 'branch', 'protocol', 'libapi', 'qtversion']:
     49            data[name] = 'Unknown'
     50
     51        try:
     52            mbe = MythTV.System(MythTV.static.INSTALL_PREFIX + '/bin/mythbackend')
     53            res = mbe.command('--version')
     54        except:
     55            return data
     56
     57        names = {'MythTV Version'  : 'version',
     58                'MythTV Branch'   : 'branch',
     59                'Network Protocol': 'protocol',
     60                'Library API'     : 'libapi',
     61                'QT Version'      : 'qtversion'}
     62
     63        for line in res.split('\n'):
     64            try:
     65                prop, val = line.split(':')
     66                data[names[prop.strip()]] = val.strip()
     67            except:
     68                pass
     69        return data
     70
     71    def td_to_secs(self,td): return td.days*86400 + td.seconds
     72
     73    def ProcessPrograms(self):
     74        rdata = OrdDict()
     75        edata = OrdDict()
     76        ldata = OrdDict()
     77        udata = OrdDict()
     78
     79        data = {'scheduled': rdata,
     80                'expireable': edata,
     81                'livetv': ldata,
     82                'upcoming': udata}
     83
     84        progs = list(MythTV.Recorded.getAllEntries())
     85        upcoming = list(_BE.getUpcomingRecordings())
     86        livetv = [prog for prog in progs if prog.recgroup == 'LiveTV']
     87        recs = [prog for prog in progs if prog.recgroup != 'LiveTV']
     88        expireable = [prog for prog in recs if prog.autoexpire]
     89
     90        times = []
     91        for dataset in (recs, expireable, livetv, upcoming):
     92            if len(dataset):
     93                try:
     94                    deltas = [rec.endtime-rec.starttime for rec in dataset]
     95                except:
     96                    deltas = [rec.recendts-rec.recstartts for rec in dataset]
     97                secs = self.td_to_secs(deltas.pop())
     98                for delta in deltas:
     99                    secs += self.td_to_secs(delta)
     100                times.append(secs)
     101            else:
     102                times.append(0)
     103
     104        rdata.count = len(recs)
     105        rdata.size  = sum([rec.filesize for rec in recs])
     106        rdata.time  = times[0]
     107
     108        edata.count = len(expireable)
     109        edata.size  = sum([rec.filesize for rec in expireable])
     110        edata.time  = times[1]
     111
     112        ldata.count = len(livetv)
     113        ldata.size  = sum([rec.filesize for rec in livetv])
     114        ldata.time  = times[2]
     115
     116        udata.count = len(upcoming)
     117        udata.time  = times[3]
     118
     119        return {'recordings': data}
     120
     121    def ProcessHistorical(self):
     122        data = OrdDict()
     123        data.db_age     = 0
     124        data.rectime    = 0
     125        data.reccount   = 0
     126        data.showcount  = 0
     127
     128        recs = list(MythTV.OldRecorded.getAllEntries())
     129        if len(recs) == 0:
     130            return data
     131
     132        oldest = recs[0]
     133        shows = []
     134
     135        for rec in recs:
     136            if rec.starttime < oldest.starttime:
     137                oldest = rec
     138            data.rectime += self.td_to_secs(rec.endtime - rec.starttime)
     139            if rec.recstatus == -3:
     140                shows.append(rec.title)
     141                data.reccount += 1
     142
     143        data.db_age = self.td_to_secs(MythTV.utility.datetime.now() - oldest.starttime)
     144        data.showcount = len(set(shows))
     145        return {'historical': data}
     146
     147    def ProcessSource(self):
     148        class CardInput( MythTV.database.DBData ): pass
     149        class VideoSource( MythTV.database.DBData ): pass
     150
     151        data = OrdDict()
     152        usedsources = list(set([inp.sourceid for inp in CardInput.getAllEntries()]))
     153        grabbers = list(set([VideoSource(id).xmltvgrabber for id in usedsources]))
     154        data.sourcecount = len(usedsources)
     155        data.grabbers = grabbers
     156        return data
     157
     158    def ProcessTimeZone(self):
     159        data = OrdDict()
     160        data.timezone = 'Unknown'
     161        data.tzoffset = 0
     162
     163        res = _BE.backendCommand('QUERY_TIME_ZONE').split('[]:[]')
     164        data.timezone = res[0]
     165        data.tzoffset = int(res[1])
     166        return data
     167
     168    def ProcessStorage(self):
     169        def processdirs(paths):
     170            total = 0
     171            free  = 0
     172
     173            for path in paths:
     174                stat = os.statvfs(path)
     175                bsize = stat[statvfs.F_FRSIZE]
     176                total += stat[statvfs.F_BLOCKS]*bsize
     177                free  += stat[statvfs.F_BFREE]*bsize
     178
     179            return (total, free)
     180
     181        data = OrdDict()
     182        data.rectotal = 0
     183        data.recfree  = 0
     184        data.videototal     = 0
     185        data.videofree      = 0
     186
     187        if not self.isBackend():
     188            return data
     189
     190        sgnames  = [rec.storagegroup for rec in MythTV.Recorded.getAllEntries()]
     191        sgnames += [rec.storagegroup for rec in MythTV.Record.getAllEntries()]
     192        sgnames  = list(set(sgnames))
     193
     194        sgs = []
     195        for host in set([_DB.gethostname(), _BE.hostname]):
     196            for sgname in sgnames:
     197                for sg in _DB.getStorageGroup(sgname, host):
     198                    if sg.local:
     199                        sgs.append(sg.dirname)
     200        data.rectotal, data.recfree = processdirs(sgs)
     201
     202        sgs = [sg.dirname for sg in _DB.getStorageGroup('Videos', _DB.gethostname()) if sg.local]
     203        data.videototal, data.videofree = processdirs(sgs)
     204
     205        return {'storage': data}
     206
     207    def ProcessAudio(self):
     208        def _bool(val):
     209            if val is None:
     210                return False
     211            return bool(int(val))
     212
     213        def _read_file(filename):
     214            firstline=[]
     215            try:
     216                with open(filename,'r') as f:
     217                        line = f.readline()
     218                        firstline = line.split()
     219            except:
     220                pass
     221            return firstline
     222             
     223           
     224        def _oss_alsa():
     225            snd_type = "unknown"
     226            version = "unknown"
     227            alsasnd = "/proc/asound/version"
     228            osssnd = "/dev/sndstat"
     229           
     230            if os.path.exists(alsasnd):
     231                snd_type = "ALSA"
     232                version = _read_file(alsasnd)[-1].rstrip(".")
     233               
     234            elif os.path.exists(osssnd):
     235                version = _read_file(osssnd)[1]
     236                snd_type = "OSS"
     237               
     238            return snd_type , version
     239
     240        def _process_search(processname):
     241            foundit = False
     242            for line in os.popen("ps xa"):
     243                fields = line.split()
     244                pid = fields[0]
     245                process = fields[4].split("/")
     246                if processname in process :
     247                    foundit = True
     248                    break
     249            return foundit
     250
     251        def _jack():
     252            if _process_search("jackd") or _process_search("jackdbus"):
     253                foundit = 1
     254            else:
     255                foundit = 0
     256            return foundit
     257
     258        def _pulse():
     259            if _process_search("pulseaudio"):
     260                foundit = 1
     261            else:
     262                foundit = 0
     263            return foundit
     264           
     265       
     266        data = OrdDict()
     267        data.device           = _SETTINGS.AudioOutputDevice
     268        data.passthrudevice   = _SETTINGS.PassThruOutputDevice
     269        data.passthruoverride = _bool(_SETTINGS.PassThruDeviceOverride)
     270        data.stereopcm        = _bool(_SETTINGS.StereoPCM)
     271        data.sr_override      = _bool(_SETTINGS.Audio48kOverride)
     272        data.maxchannels      = _SETTINGS.MaxChannels
     273        data.defaultupmix     = _bool(_SETTINGS.AudioDefaultUpmix)
     274        data.upmixtype        = _SETTINGS.AudioUpmixType
     275        p = []
     276        for k,v in (('AC3PassThru', 'ac3'),         ('DTSPassThru', 'dts'),
     277                    ('HBRPassthru', 'hbr'),         ('EAC3PassThru', 'eac3'),
     278                    ('TrueHDPassThru', 'truehd'),   ('DTSHDPassThru', 'dtshd')):
     279            if _bool(_SETTINGS[k]):
     280                p.append(v)
     281        data.passthru         = p
     282        data.volcontrol       = _bool(_SETTINGS.MythControlsVolume)
     283        data.mixerdevice      = _SETTINGS.MixerDevice
     284        data.mixercontrol     = _SETTINGS.MixerControl
     285        data.jack             = _jack()
     286        data.pulse            = _pulse()
     287        data.audio_sys, data.audio_sys_version    = _oss_alsa()
     288       
     289        return {'audio': data}
     290
     291    def ProcessVideoProfile(self):
     292        class DisplayProfileGroups( MythTV.database.DBData ): pass
     293        class DisplayProfiles( OrdDict ):
     294            def __new__(cls, *args, **kwargs):
     295                inst = super(DisplayProfiles, cls).__new__(cls, *args, **kwargs)
     296                inst.__dict__['_profilegroupid'] = None
     297                inst.__dict__['_profileid'] = None
     298                inst.__dict__['_db'] = None
     299                return inst
     300
     301            def __init__(self, profilegroupid, profileid, db=None):
     302                self._db             = MythTV.database.DBCache(db=db)
     303                self._profilegroupid = profilegroupid
     304                self._profileid      = profileid
     305                with db as cursor:
     306                    cursor.execute("""SELECT value,data FROM displayprofiles
     307                                    WHERE profilegroupid=%s
     308                                    AND profileid=%s""",
     309                                    (profilegroupid, profileid))
     310                    for k,v in cursor.fetchall():
     311                        self[k] = v
     312
     313            @classmethod
     314            def fromProfileGroup(cls, profilegroupid, db=None):
     315                db = MythTV.database.DBCache(db=db)
     316                with db as cursor:
     317                    cursor.execute("""SELECT DISTINCT(profileid)
     318                                    FROM displayprofiles
     319                                    WHERE profilegroupid=%s""",
     320                                    profilegroupid)
     321                    for profileid in cursor.fetchall():
     322                        yield cls(profilegroupid, profileid[0], db)
     323
     324        data = OrdDict()
     325        data.name = _SETTINGS.DefaultVideoPlaybackProfile
     326        data.profiles = []
     327
     328        profilegroupid = DisplayProfileGroups((data.name, _DB.gethostname()), _DB)\
     329                                .profilegroupid
     330        for profile in DisplayProfiles.fromProfileGroup(profilegroupid, _DB):
     331            d = OrdDict()
     332            d.decoder   = profile.pref_decoder
     333            d.deint_pri = profile.pref_deint0
     334            d.deint_sec = profile.pref_deint1
     335            d.renderer  = profile.pref_videorenderer
     336            d.filters   = profile.pref_filters
     337            data.profiles.append(d)
     338
     339        return {'playbackprofile':data}
     340
     341    def ProcessMySQL(self):
     342        data = OrdDict()
     343
     344        c = _DB.cursor()
     345        c.execute("""SELECT VERSION()""")
     346        data.version = c.fetchone()[0]
     347
     348        c.execute("""SHOW ENGINES""")
     349        data.engines = [r[0] for r in c.fetchall()]
     350
     351        c.execute("""SHOW TABLE STATUS WHERE NAME='settings'""")
     352        data.usedengine = c.fetchone()[1]
     353
     354        data.schema = OrdDict()
     355        c.execute("""SELECT value,data FROM settings
     356                    WHERE value LIKE '%SchemaVer'""")
     357        for k,v in c.fetchall():
     358            data.schema[k] = v
     359
     360        return {'database':data}
     361
     362    def ProcessScheduler(self):
     363        def stddev(data):
     364            avg = sum(data)/len(data)
     365            return avg, (sum([(d-avg)**2 for d in data])/len(data))**.5
     366
     367        data = OrdDict()
     368        data.count = 0
     369        data.match_avg = 0
     370        data.match_stddev = 0
     371        data.place_avg = 0
     372        data.place_stddev = 0
     373
     374        r = re.compile('Scheduled ([0-9]*) items in [0-9.]* = ([0-9.]*) match \+ ([0-9.]*) place')
     375        data = OrdDict()
     376
     377        c = _DB.cursor()
     378        c.execute("""SELECT details FROM mythlog
     379                    WHERE module='scheduler'
     380                    AND message='Scheduled items'""")
     381
     382        runs = [r.match(d[0]).groups() for d in c.fetchall()]
     383
     384        if len(runs) == 0:
     385            return {'scheduler': data}
     386
     387        a,s = stddev([float(r[2]) for r in runs])
     388        for i,r in reversed(list(enumerate(runs))):
     389            if abs(float(r[2]) - a) > (3*s):
     390                runs.pop(i)
     391
     392        data = OrdDict()
     393
     394        count = [float(r[0]) for r in runs]
     395        match = [float(r[1]) for r in runs]
     396        place = [float(r[2]) for r in runs]
     397
     398        data.count = int(sum(count)/len(count))
     399        data.match_avg, data.match_stddev = stddev(match)
     400        data.place_avg, data.place_stddev = stddev(place)
     401
     402        return {'scheduler': data}
     403
     404
     405    def Processtuners(self):
     406        data = OrdDict()
     407
     408        c = _DB.cursor()
     409        c.execute("""select cardtype,count(cardtype)
     410                    from capturecard group by cardtype""")
     411        for k,v in c.fetchall():
     412            data[k] = v
     413         
     414
     415        return {'tuners':data}
     416       
     417    def ProcessSmoltInfo(self):
     418        smoltfile=home+"/.mythtv/smolt.info"
     419        config = {}
     420        try:
     421            config_file= open(smoltfile)
     422            for line in config_file:
     423                line = line.strip()
     424                if line and line[0] is not "#" and line[-1] is not "=":
     425                    var,val = line.rsplit("=",1)
     426                    config[var.strip()] = val.strip("\"")
     427        except:
     428            pass
     429
     430        try:
     431            myth_systemrole = config["systemtype" ]
     432        except:
     433            myth_systemrole = '0'
     434
     435        try:
     436            mythremote  = config["remote" ]
     437        except:
     438            mythremote = 'unknown'
     439
     440
     441        return myth_systemrole , mythremote
     442
     443
     444
     445
     446
     447    def get_data(self,gate):
     448        self._data = OrdDict()
     449        self._data.update(self.ProcessVersion())
     450        self._data.update(self.ProcessPrograms())
     451        self._data.update(self.ProcessHistorical())
     452        self._data.update(self.ProcessSource())
     453        self._data.update(self.ProcessTimeZone())
     454        self._data.update(self.ProcessStorage())
     455        self._data.update(self.ProcessAudio())
     456        self._data.update(self.ProcessVideoProfile())
     457        self._data.update(self.ProcessMySQL())
     458        self._data.update(self.ProcessScheduler())
     459        self._data.update(self.Processtuners())
     460       
     461        self._data.theme          = _SETTINGS.Theme
     462        self._data.country          = _SETTINGS.Country
     463        self._data.channel_count  = len([c for c in MythTV.Channel.getAllEntries() if c.visible])
     464        self._data.language       = _SETTINGS.Language.lower()
     465        self._data.mythtype, self._data.remote = self.ProcessSmoltInfo()
     466
     467        if _DB.settings.NULL.SystemUUID is None:
     468            _DB.settings.NULL.SystemUUID = UuidDb().gen_uuid()
     469        self._data.uuid           = _DB.settings.NULL.SystemUUID
     470
     471       
     472       
     473
     474    def serialize(self):
     475        res = self._data
     476        return res
     477
     478    def _dump_rst_section(self, lines, title, data, line_break=True):
     479        lines.append(title)
     480        for k,v in sorted(data.items()):
     481            lines.append('- %s:\n      %s \n' %(k,v))
     482           
     483        if line_break:
     484            lines.append('')
     485
     486    def dump_rst(self, lines):
     487        serialized = self.serialize()
     488        lines.append('MythTV Features')
     489        lines.append('-----------------------------')
     490        self._dump_rst_section(lines, '', serialized)
     491
     492
     493    def _dump(self):
     494        lines = []
     495        self.dump_rst(lines)
     496        print '\n'.join(lines)
     497        print
     498
     499
     500def create_mythtv_data(gate):
     501    return _Mythtv_data(gate)
     502   
     503
     504
     505if __name__ == '__main__':
     506    import pprint
     507    pp = pprint.PrettyPrinter()
     508    pp.pprint(get_data())
  • new file mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/main.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/main.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/main.py
    new file mode 100644
    index 0000000..a69fe85
    - +  
     1# smolt - Fedora hardware profiler
     2#
     3# Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
     4# Copyright (C) 2011 James Meyer <james.meyer@operamail.com>
     5#
     6# This program is free software; you can redistribute it and/or modify
     7# it under the terms of the GNU General Public License as published by
     8# the Free Software Foundation; either version 2 of the License, or
     9# (at your option) any later version.
     10#
     11# This program is distributed in the hope that it will be useful,
     12# but WITHOUT ANY WARRANTY; without even the implied warranty of
     13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14# GNU General Public License for more details.
     15#
     16# You should have received a copy of the GNU General Public License
     17# along with this program; if not, write to the Free Software
     18# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     19
     20import os
     21from distros.distro import Distro
     22import distros.shared.html as html
     23
     24
     25
     26class _Mythtv(Distro):
     27    def key(self):
     28        return 'mythtv'
     29
     30    def detected(self, debug=False):
     31       
     32        #return False
     33        return True
     34       
     35
     36    def gather(self, gate, debug=False):
     37        def _stage(text):
     38            print 'Processing %s' % (text)
     39        from data_mythtv import create_mythtv_data
     40
     41        _stage('MythTV Data')
     42        features = create_mythtv_data(gate)
     43
     44        machine_data = {}
     45        html_lines = []
     46        rst_lines = []
     47        metrics_dict = {}
     48
     49        rst_lines.append('MythTV data')
     50        rst_lines.append('=================================')
     51        machine_data['protocol'] = '1.2'
     52
     53       
     54        machine_data['features'] = features.serialize()
     55        features.dump_rst(rst_lines)
     56        rst_lines.append('')
     57
     58        excerpt_lines = []
     59        excerpt_lines.append('...')
     60
     61        self._data = machine_data
     62        self._html = '\n'.join(html_lines)
     63        self._rst = '\n'.join(rst_lines)
     64        self._excerpt = '\n'.join(excerpt_lines)
     65
     66    def data(self):
     67        return self._data
     68
     69    def html(self):
     70        return self._html
     71
     72    def rst(self):
     73        return self._rst
     74
     75    def rst_excerpt(self):
     76        return self._excerpt
     77
     78
     79def create_mythtv():
     80    return _Mythtv()
     81
     82
     83if __name__ == '__main__':
     84    # Enable auto-flushing for stdout
     85    import sys
     86    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
     87
     88    from gate import create_passing_gate
     89    mythtv = create_mythtv()
     90    mythtv.gather(create_passing_gate(), debug=True)
     91
     92    print mythtv.rst()
  • new file mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/makeopts.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/makeopts.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/makeopts.py
    new file mode 100644
    index 0000000..64cdc36
    - +  
     1# smolt - Fedora hardware profiler
     2#
     3# Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
     4#
     5# This program is free software; you can redistribute it and/or modify
     6# it under the terms of the GNU General Public License as published by
     7# the Free Software Foundation; either version 2 of the License, or
     8# (at your option) any later version.
     9#
     10# This program is distributed in the hope that it will be useful,
     11# but WITHOUT ANY WARRANTY; without even the implied warranty of
     12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13# GNU General Public License for more details.
     14#
     15# You should have received a copy of the GNU General Public License
     16# along with this program; if not, write to the Free Software
     17# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     18
     19import re
     20import portage
     21
     22SHORT_PARA_PATTERN = '-[CfIOW]\\s+\\S+|-[jl](\\s+[^-]\\S*)?|-[^-]\\S+'
     23LONG_PARA_PATTERN = '--\\S+|--\\S+=\\S+'
     24PARA_PATTERN = re.compile('(%s|%s)\\b' % (SHORT_PARA_PATTERN, LONG_PARA_PATTERN))
     25
     26class MakeOpts:
     27    def __init__(self, value=None):
     28        """
     29        >>> m = MakeOpts("-C dir -f file -I dir -o file -W file -j 3 -l 4 -j -j3 -l --always-make")
     30        >>> m.get()
     31        ['-C dir', '-f file', '-I dir', '-W file', '-j 3', '-l 4', '-j', '-j3', '-l', '--always-make']
     32        """
     33        if value is None:
     34            value = portage.settings['MAKEOPTS']
     35        self._makeopts = self._parse(value)
     36
     37    def _parse(self, flags):
     38        list = []
     39        for m in re.finditer(PARA_PATTERN, flags):
     40            text = re.sub('\\s{2,}', ' ', m.group()) # Normalize whitespace
     41            list.append(text)
     42        return list
     43
     44    def get(self):
     45        return self._makeopts
     46
     47    def serialize(self):
     48        return self._makeopts
     49
     50    def dump(self):
     51        print 'MAKEOPTS: ' + str(self.get())
     52        print
     53
     54
     55if __name__ == '__main__':
     56    import doctest
     57    doctest.testmod(verbose=True)
  • new file mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/orddict.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/orddict.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/orddict.py
    new file mode 100755
    index 0000000..6929037
    - +  
     1# -*- coding: utf-8 -*-
     2# smolt - Fedora hardware profiler
     3#
     4# Copyright (C) 2011 Raymond Wagner <raymond@wagnerrp.com>
     5#
     6# This program is free software; you can redistribute it and/or modify
     7# it under the terms of the GNU General Public License as published by
     8# the Free Software Foundation; either version 2 of the License, or
     9# (at your option) any later version.
     10#
     11# This program is distributed in the hope that it will be useful,
     12# but WITHOUT ANY WARRANTY; without even the implied warranty of
     13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14# GNU General Public License for more details.
     15#
     16# You should have received a copy of the GNU General Public License
     17# along with this program; if not, write to the Free Software
     18# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     19
     20__doc__="""This is an ordered dictionary implementation to be used to
     21store client data before transmission to the server."""
     22
     23from itertools import imap, izip
     24
     25class OrdDict( dict ):
     26    """
     27    OrdData.__init__(raw) -> OrdData object
     28
     29    A modified dictionary, that maintains the order of items.
     30        Data can be accessed as attributes or items.
     31    """
     32
     33    def __new__(cls, *args, **kwargs):
     34        inst = super(OrdDict, cls).__new__(cls, *args, **kwargs)
     35        inst.__dict__['_field_order'] = []
     36        return inst
     37
     38    def __getattr__(self, name):
     39        try:
     40            return super(OrdDict, self).__getattr__(name)
     41        except AttributeError:
     42            try:
     43                return self[name]
     44            except KeyError:
     45                raise AttributeError(str(name))
     46
     47    def __setattr__(self, name, value):
     48        if name in self.__dict__:
     49            super(OrdDict, self).__setattr__(name, value)
     50        else:
     51            self[name] = value
     52
     53    def __delattr__(self, name):
     54        try:
     55            super(OrdDict, self).__delattr__(name)
     56        except AttributeError:
     57            del self[name]
     58
     59    def __setitem__(self, name, value):
     60        if name not in self:
     61            self._field_order.append(name)
     62        super(OrdDict, self).__setitem__(name, value)
     63
     64    def __delitem__(self, name):
     65        super(OrdDict, self).__delitem__(name)
     66        self._field_order.remove(key)
     67
     68    def update(self, *data, **kwdata):
     69        if len(data) == 1:
     70            try:
     71                for k,v in data[0].iteritems():
     72                    self[k] = v
     73            except AttributeError:
     74                for k,v in iter(data[0]):
     75                    self[k] = v
     76        if len(kwdata):
     77            for k,v in kwdata.iteritems():
     78                self[k] = v
     79
     80    def __iter__(self):
     81        return self.iterkeys()
     82
     83    def iterkeys(self):
     84        return iter(self._field_order)
     85
     86    def keys(self):
     87        return list(self.iterkeys())
     88
     89    def itervalues(self):
     90        return imap(self.get, self.iterkeys())
     91
     92    def values(self):
     93        return list(self.itervalues())
     94
     95    def iteritems(self):
     96        return izip(self.iterkeys(), self.itervalues())
     97
     98    def items(self):
     99        return list(self.iteritems())
     100
     101    def copy(self):
     102        c = self.__class__()
     103        for k,v in self.items():
     104            try:
     105                c[k] = v.copy()
     106            except AttributeError:
     107                c[k] = v
     108        for k,v in self.__dict__.items():
     109            try:
     110                c[k] = v.copy()
     111            except AttributeError:
     112                c.__dict__[k] = v
     113        return c
     114
     115    def clear(self):
     116        super(OrdDict, self).clear()
     117        self._field_order = []
     118
     119# This sets up a factory for urllib2.Request objects, automatically
     120# providing the base url, user agent, and proxy information.
     121# The object returned is slightly modified, with a shortcut to urlopen.
  • new file mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/request.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/request.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/request.py
    new file mode 100755
    index 0000000..21916c2
    - +  
     1# -*- coding: utf-8 -*-
     2# smolt - Fedora hardware profiler
     3#
     4# Copyright (C) 2011 Raymond Wagner <sebastian@pipping.org>
     5#
     6# This program is free software; you can redistribute it and/or modify
     7# it under the terms of the GNU General Public License as published by
     8# the Free Software Foundation; either version 2 of the License, or
     9# (at your option) any later version.
     10#
     11# This program is distributed in the hope that it will be useful,
     12# but WITHOUT ANY WARRANTY; without even the implied warranty of
     13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14# GNU General Public License for more details.
     15#
     16# You should have received a copy of the GNU General Public License
     17# along with this program; if not, write to the Free Software
     18# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     19
     20# This sets up a factory for urllib2.Request objects, automatically
     21# providing the base url, user agent, and proxy information.
     22# The object returned is slightly modified, with a shortcut to urlopen.
     23
     24import urllib2
     25import urlparse
     26
     27class _Request( urllib2.Request ):
     28    timeout = None
     29    def open(self):
     30        if self.timeout:
     31            return urllib2.urlopen(self, None, self.timeout)
     32        return urllib2.urlopen(self)
     33
     34class _RequestFactory( object ):
     35    def __init__(self, baseurl, user_agent, timeout, proxy):
     36        self.base_url = baseurl
     37        self.user_agent = user_agent
     38        self.timeout = timeout
     39        self.proxy = proxy
     40
     41    def __call__(self, *args, **kwargs):
     42        return self.new_request(*args, **kwargs)
     43
     44    def new_request(self, url):
     45        url = urlparse.urljoin(self.base_url, url)
     46        req = _Request(url)
     47        req.timeout = self.timeout
     48        if self.proxy:
     49            req.set_proxy(self.proxy, 'http')
     50        if self.user_agent:
     51            req.add_header('User-Agent', self.user_agent)
     52        return req
     53
     54_request = None
     55
     56def ConnSetup(baseurl, user_agent=None, timeout=120, proxy=None):
     57    global _request
     58    if _request is None:
     59        _request = _RequestFactory(baseurl, user_agent, timeout, proxy)
     60
     61def Request(url=None):
     62    global _request
     63    if _request is None:
     64        raise Exception("Request Factory not yet spawned")
     65    if url:
     66        return _request(url)
     67    return _request.base_url
  • new file mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/uuiddb.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/uuiddb.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/uuiddb.py
    new file mode 100755
    index 0000000..b7535de
    - +  
     1# smolt - Fedora hardware profiler
     2#
     3# Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
     4#
     5# This program is free software; you can redistribute it and/or modify
     6# it under the terms of the GNU General Public License as published by
     7# the Free Software Foundation; either version 2 of the License, or
     8# (at your option) any later version.
     9#
     10# This program is distributed in the hope that it will be useful,
     11# but WITHOUT ANY WARRANTY; without even the implied warranty of
     12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13# GNU General Public License for more details.
     14#
     15# You should have received a copy of the GNU General Public License
     16# along with this program; if not, write to the Free Software
     17# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     18
     19import ConfigParser
     20import logging
     21import os , sys
     22sys.path.extend(map(os.path.abspath, ['../../']))
     23from smolt_config import get_config_attr
     24from request import Request
     25
     26_SECTION = 'MAIN'
     27
     28
     29def _get_option_name(hw_uuid, host):
     30    return '%s__%s' % (hw_uuid, host)
     31
     32class UUIDError(Exception):
     33    def __init__(self, message):
     34        self.msg = message
     35
     36    def __str__(self):
     37        return str(self.msg)
     38
     39class PubUUIDError(Exception):
     40    def __init__(self, message):
     41        self.msg = message
     42
     43    def __str__(self):
     44        return str(self.msg)
     45
     46class _UuidDb:
     47    hw_uuid = None
     48
     49    def __init__(self, database_filename):
     50        self._database_filename = database_filename
     51        self._config = ConfigParser.RawConfigParser()
     52        self._config.read(self._database_filename)
     53        if not self._config.has_section(_SECTION):
     54            self._config.add_section(_SECTION)
     55        self.hw_uuid_file = get_config_attr('HW_UUID', '/etc/smolt/hw-uuid')
     56
     57    def _flush(self):
     58        try:
     59            smolt_user_config_dir = os.path.expanduser('~/.smolt/')
     60            if not os.path.exists(smolt_user_config_dir):
     61                os.mkdir(smolt_user_config_dir, 0700)
     62            f = open(self._database_filename, 'w')
     63            self._config.write(f)
     64            f.close()
     65        except:
     66            logging.error('Flushing UUID database failed')
     67
     68    def get_pub_uuid(self, hw_uuid, host):
     69        try:
     70            pub_uuid = self._config.get(_SECTION, _get_option_name(hw_uuid, host))
     71            logging.info('Public UUID "%s" read from database' % pub_uuid)
     72            return pub_uuid
     73        except ConfigParser.NoOptionError:
     74            try:
     75                req = Request('/client/pub_uuid/%s' % self.get_priv_uuid())
     76                pudict = json.loads(req.open().read())
     77                self.set_pub_uuid(self.hw_uuid, Request(), pudict['pub_uuid'])
     78                return pudict['pub_uuid']
     79            except Exception, e:
     80                error(_('Error determining public UUID: %s') % e)
     81                sys.stderr.write(_("Unable to determine Public UUID!  This could be a network error or you've\n"))
     82                sys.stderr.write(_("not submitted your profile yet.\n"))
     83                raise PubUUIDError, 'Could not determine Public UUID!\n'
     84
     85    def set_pub_uuid(self, hw_uuid, host, pub_uuid):
     86        for i in (hw_uuid, host, pub_uuid):
     87            if not i:
     88                raise Exception('No paramater allowed to be None.')
     89        self._config.set(_SECTION, _get_option_name(hw_uuid, host), pub_uuid)
     90        logging.info('Public UUID "%s" written to database' % pub_uuid)
     91        self._flush()
     92
     93    def gen_uuid(self):
     94        try:
     95            return file('/proc/sys/kernel/random/uuid').read().strip()
     96        except IOError:
     97            try:
     98                import uuid
     99                return uuid.uuid4()
     100            except:
     101                raise UUIDError('Could not generate new UUID!')
     102
     103    def get_priv_uuid(self):
     104        if self.hw_uuid:
     105            return self.hw_uuid
     106
     107        try:
     108            self.hw_uuid = file(self.hw_uuid_file).read().strip()
     109        except IOError:
     110            try:
     111                self.hw_uuid = self.genUUID()
     112            except UUIDError:
     113                raise UUIDError('Unable to determine UUID of system!')
     114            try:
     115                # make sure directory exists, create if not
     116                file(self.hw_uuid_file).write(self.hw_uuid)
     117            except Exception, e:
     118                raise UUIDError('Unable to save UUID to %s. Please run once as root.' % self.hw_uuid_file)
     119
     120        return self.hw_uuid
     121
     122_uuid_db_instance = None
     123def UuidDb():
     124    """Simple singleton wrapper with lazy initialization"""
     125    global _uuid_db_instance
     126    if _uuid_db_instance == None:
     127        import config
     128        from smolt import get_config_attr
     129        _uuid_db_instance =  _UuidDb(get_config_attr("UUID_DB", os.path.expanduser('~/.smolt/uuiddb.cfg')))
     130    return _uuid_db_instance
  • mythtv/programs/scripts/hardwareprofile/gate.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/gate.py b/mythtv/programs/scripts/hardwareprofile/gate.py
    index dacaac0..13f7e46 100644
    a b import ConfigParser 
    2121import os
    2222import logging
    2323
    24 class _Gate:
    25     def __init__(self, the_only_config_file):
    26         config_files = (the_only_config_file == None) and \
    27                 ['/etc/smolt/client.cfg',
    28                     os.path.expanduser('~/.smolt/client.cfg')] or \
    29                 [the_only_config_file]
     24
     25class _GateBase:
     26    def process(self, data_set, value_if_granted, value_else):
     27        if self.grants(data_set):
     28            return value_if_granted
     29        else:
     30            return value_else
     31
     32
     33class _Gate(_GateBase):
     34    def __init__(self, config_files=None):
     35        if config_files is None:
     36            config_files = [
     37                '/etc/smolt/client.cfg',
     38                os.path.expanduser('~/.smolt/client.cfg'),
     39            ]
    3040        self.config = ConfigParser.ConfigParser()
    3141        self.config.read(config_files)
    3242
    class _Gate: 
    5161            # Allow if in doubt - backwards compat
    5262            return True
    5363
    54     def process(self, data_set, value_if_granted, value_else):
    55         if self.grants(data_set):
    56             return value_if_granted
    57         else:
    58             return value_else
    5964
    60 _gate = None
    61 
    62 def Gate():
    63     """Simple singleton wrapper with lazy initialization"""
    64     global _gate
    65     if _gate == None:
    66         _gate = _Gate(None)
    67     return _gate
    68 
    69 def GateFromConfig(the_only_config_file):
    70     """Simple singleton wrapper with lazy initialization"""
    71     global _gate
    72     if _gate == None:
    73         _gate = _Gate(the_only_config_file)
    74     return _gate
     65class _FakeGate(_GateBase):
     66    def __init__(self, grant):
     67        """
     68        >>> gate = _FakeGate(grant=True)
     69        >>> gate.grants("whatever")
     70        True
     71        >>> gate = _FakeGate(grant=False)
     72        >>> gate.grants("whatever")
     73        False
     74        """
     75        self._granted = grant
     76
     77    def grants(self, *args):
     78        return self._granted
     79
     80
     81def create_default_gate():
     82    return _Gate()
     83
     84
     85def create_gate_from_file(filename):
     86    return _Gate([filename, ])
     87
     88
     89def create_passing_gate():
     90    """
     91    >>> create_passing_gate().grants("whatever")
     92    True
     93    """
     94    return _FakeGate(grant=True)
     95
     96
     97def create_blocking_gate():
     98    """
     99    >>> create_blocking_gate().grants("whatever")
     100    False
     101    """
     102    return _FakeGate(grant=False)
  • mythtv/programs/scripts/hardwareprofile/getLink.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/getLink.py b/mythtv/programs/scripts/hardwareprofile/getLink.py
    index 12b0925..4f507a0 100644
    a b  
     1# -*- coding: utf-8 -*-
     2
     3# smolt - Fedora hardware profiler
     4#
     5# Copyright (C) 2008 Yaakov M. Nemoy <loupgaroublond@gmail.com>
     6# Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>
     7#
     8# This program is free software; you can redistribute it and/or modify
     9# it under the terms of the GNU General Public License as published by
     10# the Free Software Foundation; either version 2 of the License, or
     11# (at your option) any later version.
     12#
     13# This program is distributed in the hope that it will be useful,
     14# but WITHOUT ANY WARRANTY; without even the implied warranty of
     15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16# GNU General Public License for more details.
     17#
     18# You should have received a copy of the GNU General Public License
     19# along with this program; if not, write to the Free Software
     20# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     21
    122import sys
    223from optparse import OptionParser
    324from urlparse import urljoin
    4 import json
    5 import urllib2
     25import urlgrabber.grabber
     26import simplejson
    627
    728sys.path.append('/usr/share/smolt/client')
    829
    import smolt 
    1132from smolt import debug
    1233from smolt import error
    1334from scan import scan
    14 from request import Request, ConnSetup
    1535
    1636parser = OptionParser(version = smolt.smoltProtocol)
    1737
    parser.add_option('--uuidFile', 
    4161                  help = _('specify which uuid to use, useful for debugging and testing mostly.'))
    4262
    4363(opts, args) = parser.parse_args()
    44 ConnSetup(opts.smoonURL, opts.user_agent, opts.timeout, None)
    4564
    4665def main():
    47     profile = smolt.get_profile()
     66    from gate import create_default_gate
     67    profile = smolt.create_profile(create_default_gate(), smolt.read_uuid())
     68    grabber = urlgrabber.grabber.URLGrabber(user_agent=opts.user_agent, timeout=opts.timeout)
    4869    #first find out the server desired protocol
    4970    try:
    5071        #fli is a file like item
    51         req = Request('/client/pub_uuid?uuid=%s' % profile.host.UUID)
    52         pub_uuid_fli.open()
    53     except urllib2.URLError, e:
     72        pub_uuid_fli = grabber.urlopen(urljoin(opts.smoonURL + "/", '/client/pub_uuid?uuid=%s' % profile.host.UUID, False))
     73    except urlgrabber.grabber.URLGrabError, e:
    5474        error(_('Error contacting Server: %s') % e)
    5575        return 1
    5676    pub_uuid_str = pub_uuid_fli.read()
    5777    try:
    5878        try:
    59             pub_uuid_obj = json.loads(pub_uuid_str)
     79            pub_uuid_obj = simplejson.loads(pub_uuid_str)
    6080            print _('To view your profile visit: %s') % smolt.get_profile_link(opts.smoonURL, pub_uuid_obj["pub_uuid"])
    6181        except ValueError, e:
    6282            error(_('Something went wrong fetching the public UUID'))
  • mythtv/programs/scripts/hardwareprofile/hwdata.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/hwdata.py b/mythtv/programs/scripts/hardwareprofile/hwdata.py
    index bb52b79..8299f1a 100644
    a b  
     1# -*- coding: utf-8 -*-
     2
     3# smolt - Fedora hardware profiler
     4#
     5# Copyright (C) 2010 Mike McGrath <mmcgrath@redhat.com>
     6# Copyright (C) 2011 Alexandre Rostovtsev <tetromino@gmail.com>
     7#
     8# This program is free software; you can redistribute it and/or modify
     9# it under the terms of the GNU General Public License as published by
     10# the Free Software Foundation; either version 2 of the License, or
     11# (at your option) any later version.
     12#
     13# This program is distributed in the hope that it will be useful,
     14# but WITHOUT ANY WARRANTY; without even the implied warranty of
     15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16# GNU General Public License for more details.
     17#
     18# You should have received a copy of the GNU General Public License
     19# along with this program; if not, write to the Free Software
     20# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     21
     22from smolt_config import get_config_attr
    123
    224class myVendor(object):
    325    def __init__(self):
    class DeviceMap: 
    2042        self.vendors['usb'] = self.device_map('usb')
    2143
    2244    def device_map(self, bus='pci'):
    23         fns = ['/usr/share/%s.ids' % bus,
    24                '/usr/share/hwdata/%s.ids' % bus,
    25                '/usr/share/misc/%s.ids' % bus]
    26         for fn in fns:
    27             try:
    28                 fo = open(fn, 'r')
    29                 break
    30             except IOError:
    31                 pass
     45        import os
     46        HWDATA_DIRS = [ get_config_attr("HWDATA_DIR"), '/usr/share/hwdata','/usr/share/misc' ]
     47        for hwd_file in HWDATA_DIRS:
     48            fn = "%s/%s.ids" % (hwd_file, bus)
     49            if os.path.isfile(fn + ".gz"):
     50                import gzip
     51                try:
     52                    fo = gzip.open(fn + ".gz", 'r')
     53                    break
     54                except IOError:
     55                    pass
     56            else:
     57                try:
     58                    fo = open(fn, 'r')
     59                    break
     60                except IOError:
     61                    pass
    3262        else:
    33             raise Exception('Hardware data not found')
    34        
    35         fo = open(fn, 'r')
     63            raise Exception('Hardware data file not found.  Please set the location HWDATA_DIR in config.py')
     64         
     65           
     66           
    3667        vendors = {}
    3768        curvendor = None
    3869        curdevice = None
  • mythtv/programs/scripts/hardwareprofile/os_detect.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/os_detect.py b/mythtv/programs/scripts/hardwareprofile/os_detect.py
    index 20d8c37..5b30bf3 100644
    a b  
     1#!/usr/bin/python
     2# -*- coding: utf-8 -*-
     3
     4# smolt - Fedora hardware profiler
     5#
     6# Copyright (C) 2008 James Meyer <james.meyer@operamail.com>
     7# Copyright (C) 2008 Yaakov M. Nemoy <loupgaroublond@gmail.com>
     8# Copyright (C) 2009 Carlos Gonçalves <mail@cgoncalves.info>
     9# Copyright (C) 2009 François Cami <fcami@fedoraproject.org>
     10# Copyright (C) 2010 Mike McGrath <mmcgrath@redhat.com>
     11#
     12# This program is free software; you can redistribute it and/or modify
     13# it under the terms of the GNU General Public License as published by
     14# the Free Software Foundation; either version 2 of the License, or
     15# (at your option) any later version.
     16#
     17# This program is distributed in the hope that it will be useful,
     18# but WITHOUT ANY WARRANTY; without even the implied warranty of
     19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20# GNU General Public License for more details.
     21#
     22# You should have received a copy of the GNU General Public License
     23# along with this program; if not, write to the Free Software
     24# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
     25
    126import os
    227import re
    328from UserDict import UserDict
    def get_os_info(): 
    112137          text = text
    113138        elif path_to_file.endswith('version'):
    114139          text = distro_name + ' ' + text
     140          #check /etc/issue for signs of ubuntu
     141          if distro_name == "Debian GNU/Linux":
     142                fd = open('/etc/issue.net')
     143                text_u = fd.read().strip()
     144                fd.close()
     145                if text.find("Ubuntu"):
     146                        text = text_u
     147
    115148        elif path_to_file.endswith('aurox-release'):
    116149          text = distro_name
    117150        elif path_to_file.endswith('lfs-release'):
    118151          text = distro_name + ' ' + text
     152        elif path_to_file.endswith('arch-release'):
     153          text = "Arch Linux"
    119154        elif path_to_file.endswith('SuSE-release'):
    120155          text = file(path_to_file).read().split('\n')[0].strip()
    121156          retext = re.compile('\(\w*\)$')
  • mythtv/programs/scripts/hardwareprofile/scan.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/scan.py b/mythtv/programs/scripts/hardwareprofile/scan.py
    index 037fee0..fb831b0 100644
    a b  
    11# smolt - Fedora hardware profiler
    22#
    33# Copyright (C) 2007 Mike McGrath
     4# Copyright (C) 2011 Sebastian Pipping <sebastian@pipping.org>
    45#
    56# This program is free software; you can redistribute it and/or modify
    67# it under the terms of the GNU General Public License as published by
     
    1718# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    1819
    1920import smolt
    20 from request import ConnSetup, Request
    21 
    22 import json
    23 import urllib
    24 import urllib2
     21import simplejson, urllib
    2522from i18n import _
    26 import config
    27 
    28 h = None
     23from smolt_config import get_config_attr
    2924
    30 def hardware():
    31     # Singleton pattern
    32     global h
    33     if h == None:
    34         h = smolt.Hardware()
    35     return h
    36 
    37 def get_config_attr(attr, default=""):
    38     if hasattr(config, attr):
    39         return getattr(config, attr)
    40     else:
    41         return default
    42 
    43 def rating(profile, smoonURL):
     25def rating(profile, smoonURL, gate):
    4426    print ""
    4527    print _("Current rating for vendor/model.")
    4628    print ""
    47     req = Request('/client/host_rating?vendor=%s&system=%s' % (urllib.quote(hardware().host.systemVendor),
    48                                                                urllib.quote(hardware().host.systemModel)))
    49     r = json.load(req.open())['ratings']
     29    scanURL='%s/client/host_rating?vendor=%s&system=%s' % (smoonURL, urllib.quote(profile.host.systemVendor), urllib.quote(profile.host.systemModel))
     30    r = simplejson.load(urllib.urlopen(scanURL))['ratings']
    5031    rating_system = { '0' : _('Unrated/Unknown'),
    5132                      '1' : _('Non-working'),
    5233                      '2' : _('Partially-working'),
    def rating(profile, smoonURL): 
    5940    for rate in r:
    6041        print "\t%s\t%s" % (r[rate], rating_system[rate])
    6142
    62 def scan(profile, smoonURL):
     43def scan(profile, smoonURL, gate):
    6344    print _("Scanning %s for known errata.\n" % smoonURL)
    6445    devices = []
    65     for VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description in hardware().deviceIter():
     46    for VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description in profile.deviceIter():
    6647        if VendorID:
    6748            devices.append('%s/%04x/%04x/%04x/%04x' % (Bus,
    6849                                             int(VendorID or 0),
    def scan(profile, smoonURL): 
    7051                                             int(SubsysVendorID or 0),
    7152                                             int(SubsysDeviceID or 0)) )
    7253    searchDevices = 'NULLPAGE'
    73     devices.append('System/%s/%s' % ( urllib.quote(hardware().host.systemVendor), urllib.quote(hardware().host.systemModel) ))
     54    devices.append('System/%s/%s' % ( urllib.quote(profile.host.systemVendor), urllib.quote(profile.host.systemModel) ))
    7455    for dev in devices:
    7556        searchDevices = "%s|%s" % (searchDevices, dev)
     57    scanURL='%s/smolt-w/api.php' % smoonURL
     58    scanData = 'action=query&titles=%s&format=json' % searchDevices
    7659    try:
    77         req = Request('/smolt-w/api.php')
    78         req.add_data('action=query&titles=%s&format=json' % searchDevices)
    79         r = json.load(req.open())
    80     except urllib2.HTTPError:
     60         r = simplejson.load(urllib.urlopen(scanURL, scanData))
     61    except ValueError:
    8162        print "Could not wiki for errata!"
    8263        return
    8364    found = []
    def scan(profile, smoonURL): 
    9879        print _("\tbenefit")
    9980     
    10081if __name__ == "__main__": 
    101     # read the profile
     82    from gate import create_passing_gate
     83    gate = create_passing_gate()
    10284    smoonURL = get_config_attr("SMOON_URL", "http://smolts.org/")
    103     ConnSetup(smoonURL)
    104     try:
    105         profile = smolt.Hardware()
    106     except smolt.SystemBusError, e:
    107         error(_('Error:') + ' ' + e.msg)
    108         if e.hint is not None:
    109             error('\t' + _('Hint:') + ' ' + e.hint)
    110         sys.exit(8)
    111     scan(profile, smoonURL)
    112     rating(profile, smoonURL)
    113 
     85    profile = smolt.create_profile(gate, smolt.read_uuid())
     86    scan(profile, smoonURL, gate)
     87    rating(profile, smoonURL, gate)
  • mythtv/programs/scripts/hardwareprofile/sendProfile.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/sendProfile.py b/mythtv/programs/scripts/hardwareprofile/sendProfile.py
    old mode 100755
    new mode 100644
    index baa3784..6e3a5b3
    a b  
    44# smolt - Fedora hardware profiler
    55#
    66# Copyright (C) 2007 Mike McGrath
     7# Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    78#
    89# This program is free software; you can redistribute it and/or modify
    910# it under the terms of the GNU General Public License as published by
     
    2021# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    2122
    2223import sys
    23 from optparse import OptionParser
    2424import time
    25 from urlparse import urljoin
    2625import os
    27 import random
    2826import getpass
    29 from tempfile import NamedTemporaryFile
    3027
    31 try:
    32     import subprocess
    33 except ImportError, e:
    34     pass
    35 
    36 sys.path.append('/usr/share/smolt/client')
    37 
    38 from i18n import _
    39 import smolt
    40 from smolt import debug
    41 from smolt import error, ServerError
    42 from smolt import get_config_attr
    43 from smolt import to_ascii
    44 from scan import scan, rating
    45 from gate import GateFromConfig
    46 from request import ConnSetup
    47 
    48 parser = OptionParser(version = smolt.clientVersion)
    49 
    50 parser.add_option('-d', '--debug',
    51                   dest = 'DEBUG',
    52                   default = False,
    53                   action = 'store_true',
    54                   help = _('enable debug information'))
    55 parser.add_option('--config',
    56                   dest = 'the_only_config_file',
    57                   default = None,
    58                   metavar = 'file.cfg',
    59                   help = _('specify the location of the (only) config file to use'))
    60 parser.add_option('-s', '--server',
    61                   dest = 'smoonURL',
    62                   default = smolt.smoonURL,
    63                   metavar = 'smoonURL',
    64                   help = _('specify the URL of the server (default "%default")'))
    65 parser.add_option('--username',
    66                   dest = 'userName',
    67                   default = None,
    68                   metavar = 'userName',
    69                   help = _('(optional) Fedora Account System registration'))
    70 parser.add_option('--password',
    71                   dest = 'password',
    72                   default = None,
    73                   metavar = 'password',
    74                   help = _('password, will prompt if not specified'))
    75 parser.add_option('-p', '--printOnly',
    76                   dest = 'printOnly',
    77                   default = False,
    78                   action = 'store_true',
    79                   help = _('print information only, do not send'))
    80 parser.add_option('-a', '--autoSend',
    81                   dest = 'autoSend',
    82                   default = False,
    83                   action = 'store_true',
    84                   help = _('don\'t prompt to send, just send'))
    85 parser.add_option('-r', '--retry',
    86                   dest = 'retry',
    87                   default = False,
    88                   action = 'store_true',
    89                   help = _('continue to send until success'))
    90 parser.add_option('-u', '--useragent', '--user_agent',
    91                   dest = 'user_agent',
    92                   default = smolt.user_agent,
    93                   metavar = 'USERAGENT',
    94                   help = _('specify HTTP user agent (default "%default")'))
    95 parser.add_option('-t', '--timeout',
    96                   dest = 'timeout',
    97                   type = 'float',
    98                   default = smolt.timeout,
    99                   help = _('specify HTTP timeout in seconds (default %default seconds)'))
    100 parser.add_option('-c', '--checkin',
    101                   dest = 'checkin',
    102                   default = False,
    103                   action = 'store_true',
    104                   help = _('do an automated checkin as when run from cron (implies --autoSend)'))
    105 parser.add_option('-S', '--scanOnly',
    106                   dest = 'scanOnly',
    107                   default = False,
    108                   action = 'store_true',
    109                   help = _('only scan this machine for known hardware errata, do not send profile.'))
    110 parser.add_option('--submitOnly',
    111                   dest = 'submitOnly',
    112                   default = False,
    113                   action = 'store_true',
    114                   help = _('do not scan this machine for know hardware errata, only submit profile.'))
    115 parser.add_option('--uuidFile',
    116                   dest = 'uuidFile',
    117                   default = smolt.hw_uuid_file,
    118                   help = _('specify which uuid to use, useful for debugging and testing mostly.'))
    119 #parser.add_option('-b', '--bodhi',
    120 #                  dest = 'bodhi',
    121 #                  default = False,
    122 #                  action = 'store_true',
    123 #                  help = _('Submit this profile to Bodhi as well, for Fedora Developmnent'))
    124 parser.add_option('-n', '--newPublicUUID',
    125                   dest = 'new_pub',
    126                   default = False,
    127                   action = 'store_true',
    128                   help = _('Request a new public UUID'))
    129 parser.add_option('--http-proxy',
    130                   dest = 'httpproxy',
    131                   default = None,
    132                   help = _('HTTP proxy'))
    133 
    134 
    135 (opts, args) = parser.parse_args()
    136 
    137 if opts.the_only_config_file != None:
    138     GateFromConfig(opts.the_only_config_file)
    139 
    140 smolt.DEBUG = opts.DEBUG
    141 smolt.hw_uuid_file = opts.uuidFile
    142 if opts.httpproxy == None:
    143     proxies = None
    144 else:
    145     proxies = {'http':opts.httpproxy}
    146 
    147 ConnSetup(opts.smoonURL, opts.user_agent, opts.timeout, opts.httpproxy)
    148 
    149 if opts.checkin:
    150     # Smolt is set to run
    151     opts.autoSend = True
    152 
    153 # read the profile
    154 try:
    155     profile = smolt.get_profile()
    156 except smolt.UUIDError, e:
    157     sys.stderr.write(_('%s\n' % e))
    158     sys.exit(9)
    159 
    160 if opts.new_pub:
    161     try:
    162         pub_uuid = profile.regenerate_pub_uuid(smoonURL=opts.smoonURL)
    163     except ServerError, e:
    164         error(_('Error contacting server: %s') % str(e))
    165         sys.exit(1)
    16628
    167     print _('Success!  Your new public UUID is: %s' % pub_uuid)
    168     sys.exit(0)
    169 
    170 if opts.scanOnly:
    171     scan(profile, opts.smoonURL)
    172     rating(profile, opts.smoonURL)
    173     sys.exit(0)
    174 
    175 if not opts.autoSend:
    176     if opts.printOnly:
    177         for line in profile.getProfile():
    178             if not line.startswith('#'):
    179                 print line.encode('utf-8')
    180         sys.exit(0)
     29def ensure_code_reachability():
     30    _code_location = '/usr/share/smolt/client'
     31    if sys.path[-1] == _code_location:
     32        return
     33    sys.path.append(_code_location)
     34
     35
     36def command_line():
     37    ensure_code_reachability()
     38    from i18n import _
     39    import smolt
     40
     41    from optparse import OptionParser
     42    parser = OptionParser(version = smolt.clientVersion)
     43
     44    parser.add_option('-d', '--debug',
     45                    dest = 'DEBUG',
     46                    default = False,
     47                    action = 'store_true',
     48                    help = _('enable debug information'))
     49    parser.add_option('--config',
     50                    dest = 'the_only_config_file',
     51                    default = None,
     52                    metavar = 'file.cfg',
     53                    help = _('specify the location of the (only) config file to use'))
     54    parser.add_option('-s', '--server',
     55                    dest = 'smoonURL',
     56                    default = smolt.smoonURL,
     57                    metavar = 'smoonURL',
     58                    help = _('specify the URL of the server (default "%default")'))
     59    parser.add_option('--username',
     60                    dest = 'userName',
     61                    default = None,
     62                    metavar = 'userName',
     63                    help = _('(optional) Fedora Account System registration'))
     64    parser.add_option('--password',
     65                    dest = 'password',
     66                    default = None,
     67                    metavar = 'password',
     68                    help = _('password, will prompt if not specified'))
     69    parser.add_option('-p', '--printOnly',
     70                    dest = 'printOnly',
     71                    default = False,
     72                    action = 'store_true',
     73                    help = _('print information only, do not send'))
     74    parser.add_option('-a', '--autoSend',
     75                    dest = 'autoSend',
     76                    default = False,
     77                    action = 'store_true',
     78                    help = _('don\'t prompt to send, just send'))
     79    parser.add_option('-r', '--retry',
     80                    dest = 'retry',
     81                    default = False,
     82                    action = 'store_true',
     83                    help = _('continue to send until success'))
     84    parser.add_option('-u', '--useragent', '--user_agent',
     85                    dest = 'user_agent',
     86                    default = smolt.user_agent,
     87                    metavar = 'USERAGENT',
     88                    help = _('specify HTTP user agent (default "%default")'))
     89    parser.add_option('-t', '--timeout',
     90                    dest = 'timeout',
     91                    type = 'float',
     92                    default = smolt.timeout,
     93                    help = _('specify HTTP timeout in seconds (default %default seconds)'))
     94    parser.add_option('-c', '--checkin',
     95                    dest = 'cron_mode',
     96                    default = False,
     97                    action = 'store_true',
     98                    help = _('do an automated checkin as when run from cron (implies --autoSend)'))
     99    parser.add_option('-S', '--scanOnly',
     100                    dest = 'send_profile',
     101                    default = True,
     102                    action = 'store_false',
     103                    help = _('only scan this machine for known hardware errata, do not send profile.'))
     104    parser.add_option('--submitOnly',
     105                    dest = 'scan_remote',
     106                    default = True,
     107                    action = 'store_false',
     108                    help = _('do not scan this machine for know hardware errata, only submit profile.'))
     109    parser.add_option('--uuidFile',
     110                    dest = 'uuidFile',
     111                    default = smolt.hw_uuid_file,
     112                    help = _('specify which uuid to use, useful for debugging and testing mostly.'))
     113    #parser.add_option('-b', '--bodhi',
     114    #                  dest = 'bodhi',
     115    #                  default = False,
     116    #                  action = 'store_true',
     117    #                  help = _('Submit this profile to Bodhi as well, for Fedora Developmnent'))
     118    parser.add_option('-n', '--newPublicUUID',
     119                    dest = 'new_pub',
     120                    default = False,
     121                    action = 'store_true',
     122                    help = _('Request a new public UUID'))
     123    parser.add_option('--http-proxy',
     124                    dest = 'httpproxy',
     125                    default = None,
     126                    help = _('HTTP proxy'))
     127
     128    (opts, args) = parser.parse_args()
     129
     130    if opts.cron_mode:
     131        # Smolt is set to run
     132        opts.autoSend = True
     133
     134    return opts, args
     135
     136
     137def make_display_excerpts(profile):
     138    ensure_code_reachability()
     139    from i18n import _
     140    from smolt import to_ascii
    181141
    182142    def inner_indent(text):
    183143        return ('\n' + 5 * ' ').join(text.split('\n'))
    if not opts.autoSend: 
    198158        'file_system':inner_indent(to_ascii(profile.get_file_system_info_excerpt())),
    199159        'distro':inner_indent(to_ascii(profile.get_distro_info_excerpt())),
    200160    }
     161    return excerpts
    201162
    202     submit = False
    203     while not submit:
    204         print """\
     163
     164def dump_excerpts(excerpts):
     165    print """\
    205166=====================================================
    206167%(label_intro)s
    207168
    208   %(label_general)s
     169%(label_general)s
    209170     %(general)s
    210171
    211   %(label_devices)s
     172%(label_devices)s
    212173     %(devices)s
    213174
    214   %(label_fs_related)s
     175%(label_fs_related)s
    215176     %(file_system)s
    216177
    217   %(label_distro_specific)s
     178%(label_distro_specific)s
    218179     %(distro)s
    219180
    220181=====================================================
    221182%(label_question)s
    222   %(label_question_view)s
    223   %(label_question_send)s
    224   %(label_question_quit)s
     183%(label_question_view)s
     184%(label_question_send)s
     185%(label_question_quit)s
    225186""" % excerpts
     187
     188
     189def present_and_require_confirmation(profile):
     190    import subprocess
     191    from tempfile import NamedTemporaryFile
     192
     193    ensure_code_reachability()
     194    from i18n import _
     195    from smolt import error
     196
     197    excerpts = make_display_excerpts(profile)
     198
     199    submit = False
     200    while not submit:
     201        dump_excerpts(excerpts)
     202
    226203        try:
    227204            choice = raw_input(_('Your choice (s)end (v)iew (q)uit: ')).strip()
    228205        except KeyboardInterrupt:
    if not opts.autoSend: 
    263240            sys.exit(4)
    264241
    265242
    266 if opts.retry:
    267     while 1:
    268         result, pub_uuid, admin = profile.send(smoonURL=opts.smoonURL,
    269                               batch=opts.checkin)
    270         if not result:
    271             sys.exit(0)
    272         error(_('Retry Enabled - Retrying'))
    273         time.sleep(30)
    274 else:
    275     result, pub_uuid, admin = profile.send(smoonURL=opts.smoonURL,
    276                                     batch=opts.checkin)
    277 
    278     if result:
    279         print _('Could not send - Exiting')
    280         sys.exit(1)
     243def do_send_profile(uuiddb, uuid, profile, opts, proxies):
     244    (error_code, pub_uuid, admin) = profile.send(uuiddb, uuid, user_agent=opts.user_agent,
     245                        smoonURL=opts.smoonURL,
     246                        timeout=opts.timeout,
     247                        proxies=proxies,
     248                        batch=opts.cron_mode)
     249    return (error_code, pub_uuid, admin)
     250
     251
     252def send_profile(uuiddb, uuid, profile, opts, proxies):
     253    ensure_code_reachability()
     254    from i18n import _
     255    from smolt import error
     256
     257    if opts.retry:
     258        while 1:
     259            (error_code, pub_uuid, admin) = do_send_profile(uuiddb, uuid, profile, opts, proxies)
     260            if not error_code:
     261                break
     262            error(_('Retry Enabled - Retrying'))
     263            time.sleep(30)
     264    else:
     265        (error_code, pub_uuid, admin) = do_send_profile(uuiddb, uuid, profile, opts, proxies)
     266        if error_code:
     267            print _('Could not send - Exiting')
     268            sys.exit(1)
     269
     270    return (error_code, pub_uuid, admin)
     271
     272
     273def mention_profile_web_view(opts, pub_uuid, admin):
     274    ensure_code_reachability()
     275    import smolt
     276    from i18n import _
     277
     278    pubUrl = smolt.get_profile_link(opts.smoonURL, pub_uuid)
     279    print
     280    print _('To share your profile: \n\t%s (public)') % pubUrl
     281    if not smolt.secure:
     282        print _('\tAdmin Password: %s') % admin
     283
     284
     285def get_proxies(opts):
     286    if opts.httpproxy == None:
     287        proxies = None
     288    else:
     289        proxies = {'http':opts.httpproxy}
     290    return proxies
     291
     292
     293def read_profile(gate, uuid):
     294    ensure_code_reachability()
     295    from i18n import _
     296    import smolt
     297
     298    try:
     299        profile = smolt.create_profile(gate, uuid)
     300    except smolt.UUIDError, e:
     301        sys.stderr.write(_('%s\n' % e))
     302        sys.exit(9)
     303    return profile
     304
     305
     306def register_with_fedora_account_system(opts):
     307    ensure_code_reachability()
     308    from i18n import _
    281309
    282 if opts.userName:
    283310    if not opts.password:
    284311        password = getpass.getpass('\n' + _('Password:') + ' ')
    285312    else:
    286313        password = opts.password
    287314
    288     if profile.register(userName=opts.userName, password=password, smoonURL=opts.smoonURL):
     315    if profile.register(userName=opts.userName, password=password, user_agent=opts.user_agent, smoonURL=opts.smoonURL, timeout=opts.timeout):
    289316        print _('Registration Failed, Try again')
    290 if not opts.submitOnly and not opts.checkin:
    291     scan(profile, opts.smoonURL)
     317
     318
     319def do_scan_remote(profile, opts, gate):
     320    ensure_code_reachability()
     321    from scan import scan, rating
     322
     323    scan(profile, opts.smoonURL, gate)
    292324    try:
    293         rating(profile, opts.smoonURL)
     325        rating(profile, opts.smoonURL, gate)
    294326    except ValueError:
    295327        print "Could not get rating!"
    296 print
    297328
    298 if pub_uuid:
    299     pubUrl = smolt.get_profile_link(opts.smoonURL, pub_uuid)
    300     print _('To share your profile: \n\t%s (public)') % pubUrl
    301     hw_uuid_file = get_config_attr("HW_PUBID", "/etc/smolt/hw-uuid.pub")
    302     hw_uuid_pub = os.path.basename(pubUrl)
    303     if not smolt.secure:
    304         print _('\tAdmin Password: %s') % admin
    305329
    306 elif not opts.checkin:
     330def mention_missing_uuid():
     331    ensure_code_reachability()
     332    from i18n import _
     333    print
    307334    print _('No Public UUID found!  Please re-run with -n to generate a new public uuid')
    308335
     336
     337def main_request_new_public_uuid(uuiddb, uuid, profile, opts):
     338    ensure_code_reachability()
     339    from i18n import _
     340    from smolt import error, ServerError
     341
     342    try:
     343        pub_uuid = profile.regenerate_pub_uuid(uuiddb, uuid, user_agent=opts.user_agent,
     344                            smoonURL=opts.smoonURL,
     345                            timeout=opts.timeout)
     346    except ServerError, e:
     347        error(_('Error contacting server: %s') % str(e))
     348        sys.exit(1)
     349
     350    print _('Success!  Your new public UUID is: %s' % pub_uuid)
     351    sys.exit(0)
     352
     353
     354def main_scan_only(profile, opts, gate):
     355    do_scan_remote(profile, opts, gate)
     356    sys.exit(0)
     357
     358
     359def main_print_only(profile):
     360    for line in profile.getProfile():
     361        if not line.startswith('#'):
     362            print line.encode('utf-8')
     363    sys.exit(0)
     364
     365
     366def main_send_profile(uuiddb, uuid, profile, opts, gate):
     367    proxies = get_proxies(opts)
     368
     369    if not opts.autoSend:
     370        present_and_require_confirmation(profile)
     371
     372    (error_code, pub_uuid, admin) = send_profile(uuiddb, uuid, profile, opts, proxies)
     373
     374    if opts.userName:
     375        register_with_fedora_account_system(opts)
     376
     377    if opts.scan_remote and not opts.cron_mode:
     378        do_scan_remote(profile, opts, gate)
     379
     380    if pub_uuid:
     381        mention_profile_web_view(opts, pub_uuid, admin)
     382    elif not opts.cron_mode:
     383        mention_missing_uuid()
     384
     385
     386def main():
     387    ensure_code_reachability()
     388    from i18n import _
     389    import smolt
     390    from gate import create_default_gate, create_gate_from_file
     391    from uuiddb import create_default_uuiddb
     392
     393    (opts, args) = command_line()
     394
     395    if opts.the_only_config_file is None:
     396        gate = create_default_gate()
     397    else:
     398        gate = create_gate_from_file(opts.the_only_config_file)
     399
     400    smolt.DEBUG = opts.DEBUG
     401    smolt.hw_uuid_file = opts.uuidFile
     402
     403    profile = read_profile(gate, smolt.read_uuid())
     404
     405    if opts.new_pub:
     406        uuiddb = create_default_uuiddb()
     407        uuid = smolt.read_uuid()
     408        main_request_new_public_uuid(uuiddb, uuid, profile, opts)
     409    elif not opts.send_profile:
     410        main_scan_only(profile, opts)
     411    elif opts.printOnly and not opts.autoSend:
     412        main_print_only(profile)
     413    else:
     414        uuiddb = create_default_uuiddb()
     415        uuid = smolt.read_uuid()
     416        main_send_profile(uuiddb, uuid, profile, opts, gate)
     417
     418
     419if __name__ == '__main__':
     420    main()
  • mythtv/programs/scripts/hardwareprofile/smolt.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/smolt.py b/mythtv/programs/scripts/hardwareprofile/smolt.py
    index afe1cc3..eef73a8 100644
    a b  
    33# smolt - Fedora hardware profiler
    44#
    55# Copyright (C) 2007 Mike McGrath
     6# Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    67#
    78# This program is free software; you can redistribute it and/or modify
    89# it under the terms of the GNU General Public License as published by
    from i18n import _ 
    3637import platform
    3738import software
    3839import commands
     40import urlgrabber.grabber
    3941import sys
    4042import os
    4143from urlparse import urljoin
    4244from urlparse import urlparse
    4345from urllib import urlencode
    4446import urllib
    45 import urllib2
    46 import json
    47 from json import JSONEncoder
     47import simplejson
     48from simplejson import JSONEncoder, JSONDecodeError
    4849import datetime
    4950import logging
    5051
    import config 
    5253from smolt_config import get_config_attr
    5354from fs_util import get_fslist
    5455from devicelist import cat
    55 from request import Request
    5656
    57 from gate import Gate
    5857from devicelist import get_device_list
    59 from uuiddb import UuidDb
    6058import logging
    6159from logging.handlers import RotatingFileHandler
    6260import codecs
    timeout = 120.0 
    9391proxies = None
    9492DEBUG = False
    9593
    96 #note this is located here so that smoltProtocol, can be imported into smolt_mythtv
    97 if Gate().grants("MythTV"):
    98     import smolt_mythtv
    99 
    10094
    10195PCI_BASE_CLASS_STORAGE =        1
    10296PCI_CLASS_STORAGE_SCSI =        0
    def to_ascii(o, current_encoding='utf-8'): 
    205199        s = unicode(o, current_encoding)
    206200    return s
    207201
    208 class Device:
    209     def __init__(self, props, hardware):
    210         self.UUID = getUUID()
    211         self.type = classify_hal(props)
    212         try:
    213             self.description = props['info.product'].strip()
    214         except KeyError:
    215             self.description = 'No Description'
    216         if self.type == "PRINTER":
    217             try:
    218                 vendor = props['printer.vendor'].strip()
    219                 product = props['printer.product'].strip()
    220                 if product.startswith (vendor + ' '):
    221                     product = product[len (vendor) + 1:]
    222                 self.description = "%s %s" % (vendor, product)
    223             except KeyError:
    224                 pass
    225 
    226             try:
    227                 # The USB vendor and product IDs are in the device UDI,
    228                 # whereas we are looking at the interface UDI.  Fetch the
    229                 # parent device UDI and use that for the remaining fields.
    230                 parent_udi = props['info.parent']
    231                 parent_props = hardware.get_properties_for_udi (parent_udi)
    232                 props = parent_props
    233             except KeyError:
    234                 pass
    235 
    236         try:
    237             self.bus = props['linux.subsystem'].strip()
    238         except KeyError:
    239             try:
    240                 self.bus = props['info.bus'].strip()
    241             except KeyError:
    242                 self.bus = 'Unknown'
    243         try:
    244             self.vendorid = props['%s.vendor_id' % self.bus]
    245         except KeyError:
    246             self.vendorid = None
    247         try:
    248             self.deviceid = props['%s.product_id' % self.bus]
    249         except KeyError:
    250             self.deviceid = None
    251         try:
    252             self.subsysvendorid = props['%s.subsys_vendor_id' % self.bus]
    253         except KeyError:
    254             self.subsysvendorid = None
    255         try:
    256             self.subsysdeviceid = props['%s.subsys_product_id' % self.bus]
    257         except KeyError:
    258             self.subsysdeviceid = None
    259         try:
    260             self.driver = props['info.linux.driver'].strip()
    261         except KeyError:
    262             try:
    263                 self.driver = props['net.linux.driver'].strip()
    264             except KeyError:
    265                 self.driver = 'Unknown'
    266202
    267203class Host:
    268     def __init__(self):
     204    def __init__(self, gate, uuid):
    269205        cpuInfo = read_cpuinfo()
    270206        memory = read_memory()
    271         self.UUID = getUUID()
    272         self.os = Gate().process('distro', software.read_os(), WITHHELD_MAGIC_STRING)
    273         self.defaultRunlevel = Gate().process('run_level', software.read_runlevel(), -1)
    274 
    275         self.bogomips = Gate().process('cpu', cpuInfo.get('bogomips', 0), 0)
    276         self.cpuVendor = Gate().process('cpu', cpuInfo.get('type', ''), WITHHELD_MAGIC_STRING)
    277         self.cpuModel = Gate().process('cpu', cpuInfo.get('model', ''), WITHHELD_MAGIC_STRING)
    278         self.cpu_stepping = Gate().process('cpu', cpuInfo.get('cpu_stepping', 0), 0)
    279         self.cpu_family = Gate().process('cpu', cpuInfo.get('cpu_family', ''), '')
    280         self.cpu_model_num = Gate().process('cpu', cpuInfo.get('cpu_model_num', 0), 0)
    281         self.numCpus = Gate().process('cpu', cpuInfo.get('count', 0), 0)
    282         self.cpuSpeed = Gate().process('cpu', cpuInfo.get('speed', 0), 0)
    283 
    284         self.systemMemory = Gate().process('ram_size', memory['ram'], 0)
    285         self.systemSwap = Gate().process('swap_size', memory['swap'], 0)
    286         self.kernelVersion = Gate().process('kernel', os.uname()[2], WITHHELD_MAGIC_STRING)
    287         if Gate().grants('language'):
     207        self.UUID = uuid
     208        self.os = gate.process('distro', software.read_os(), WITHHELD_MAGIC_STRING)
     209        self.defaultRunlevel = gate.process('run_level', software.read_runlevel(), -1)
     210
     211        self.bogomips = gate.process('cpu', cpuInfo.get('bogomips', 0), 0)
     212        self.cpuVendor = gate.process('cpu', cpuInfo.get('type', ''), WITHHELD_MAGIC_STRING)
     213        self.cpuModel = gate.process('cpu', cpuInfo.get('model', ''), WITHHELD_MAGIC_STRING)
     214        self.cpu_stepping = gate.process('cpu', cpuInfo.get('cpu_stepping', 0), 0)
     215        self.cpu_family = gate.process('cpu', cpuInfo.get('cpu_family', ''), '')
     216        self.cpu_model_num = gate.process('cpu', cpuInfo.get('cpu_model_num', 0), 0)
     217        self.numCpus = gate.process('cpu', cpuInfo.get('count', 0), 0)
     218        self.cpuSpeed = gate.process('cpu', cpuInfo.get('speed', 0), 0)
     219
     220        self.systemMemory = gate.process('ram_size', memory['ram'], 0)
     221        self.systemSwap = gate.process('swap_size', memory['swap'], 0)
     222        self.kernelVersion = gate.process('kernel', os.uname()[2], WITHHELD_MAGIC_STRING)
     223        if gate.grants('language'):
    288224            try:
    289225                self.language = os.environ['LANG']
    290226            except KeyError:
    class Host: 
    300236            self.language = WITHHELD_MAGIC_STRING
    301237
    302238        tempform = platform.machine()
    303         self.platform = Gate().process('arch', tempform, WITHHELD_MAGIC_STRING)
     239        self.platform = gate.process('arch', tempform, WITHHELD_MAGIC_STRING)
    304240
    305         if Gate().grants('vendor'):
     241        if gate.grants('vendor'):
    306242            #self.systemVendor = hostInfo.get('system.vendor'
    307             self.systemVendor = cat('/sys/devices/virtual/dmi/id/sys_vendor')[0].strip()
    308             if not self.systemVendor:
     243            try:
     244                self.systemVendor = cat('/sys/devices/virtual/dmi/id/sys_vendor')[0].strip()
     245            except:
    309246                self.systemVendor = 'Unknown'
    310247        else:
    311248            self.systemVendor = WITHHELD_MAGIC_STRING
    312249
    313         if Gate().grants('model'):
    314             self.systemModel = cat('/sys/devices/virtual/dmi/id/product_name')[0].strip() + ' ' + cat('/sys/devices/virtual/dmi/id/product_version')[0].strip()
    315             if not self.systemModel:
    316                 self.systemModel = hostInfo.get('system.hardware.product')
    317                 if hostInfo.get('system.hardware.version'):
    318                     self.systemModel += ' ' + hostInfo.get('system.hardware.version')
    319             if not self.systemModel:
     250        if gate.grants('model'):
     251            try:
     252                self.systemModel = cat('/sys/devices/virtual/dmi/id/product_name')[0].strip() + ' ' + cat('/sys/devices/virtual/dmi/id/product_version')[0].strip()
     253            except:
    320254                self.systemModel = 'Unknown'
     255            #hostInfo was removed with the hal restructure
     256            #if not self.systemModel:
     257                #self.systemModel = hostInfo.get('system.hardware.product')
     258                #if hostInfo.get('system.hardware.version'):
     259                    #self.systemModel += ' ' + hostInfo.get('system.hardware.version')
     260            #if not self.systemModel:
     261                #self.systemModel = 'Unknown'
    321262        else:
    322263            self.systemModel = WITHHELD_MAGIC_STRING
    323264
    324         if Gate().grants('form_factor'):
     265        if gate.grants('form_factor'):
    325266            try:
    326267                formfactor_id = int(cat('/sys/devices/virtual/dmi/id/chassis_type')[0].strip())
    327268                self.formfactor = FORMFACTOR_LIST[formfactor_id]
    class Host: 
    347288                }
    348289                try:
    349290                    model_name = model_map[model]
    350                     self.systemModel = Gate().process('model', model_name)
    351                     self.formfactor = Gate().process('form_factor', 'Blade')
     291                    self.systemModel = gate.process('model', model_name)
     292                    self.formfactor = gate.process('form_factor', 'Blade')
    352293                except KeyError:
    353294                    pass
    354295
    355         if Gate().grants('selinux'):
     296        if gate.grants('selinux'):
    356297            try:
    357298                import selinux
    358299                try:
    class Host: 
    387328            self.selinux_policy = WITHHELD_MAGIC_STRING
    388329            self.selinux_enforce = WITHHELD_MAGIC_STRING
    389330
    390     #MYTHTV STUFF
    391         if Gate().grants("MythTV"):
    392             self.mythRemote = "Not Installed"
    393             self.mythTheme = "Not Installed"
    394             self.mythPlugins = "Not Installed"
    395             self.mythRole = "Not Installed"
    396             self.mythTuner = "Not Installed"
    397 
    398             if Gate().grants('MythRemote'):
    399                 self.mythRemote = smolt_mythtv.runMythRemote()
    400             if Gate().grants('MythTheme'):
    401                 self.mythTheme = smolt_mythtv.runMythTheme()
    402             if Gate().grants('MythPlugins'):
    403                 self.mythPlugins = smolt_mythtv.runMythPlugins()
    404             if Gate().grants('MythRole'):
    405                 self.mythRole = smolt_mythtv.runMythRole()
    406             if Gate().grants('MythTuner'):
    407                 self.mythTuner = smolt_mythtv.runMythTuner()
    408 
    409 
    410 
    411 def get_file_systems():
    412     if not Gate().grants('file_systems'):
     331
     332def get_file_systems(gate):
     333    if not gate.grants('file_systems'):
    413334        return []
    414335
    415336    if fs_t_filter:
    class PubUUIDError(Exception): 
    511432    def __str__(self):
    512433        return str(self.msg)
    513434
    514 class _Hardware:
     435class _HardwareProfile:
    515436    devices = {}
    516     def __init__(self):
     437    def __init__(self, gate, uuid):
    517438#        try:
    518439#            systemBus = dbus.SystemBus()
    519440#        except:
    class _Hardware: 
    527448#
    528449#        self.systemBus = systemBus
    529450
    530         if Gate().grants('devices'):
     451        if gate.grants('devices'):
    531452                self.devices = get_device_list()
    532453#        for udi in all_dev_lst:
    533454#            props = self.get_properties_for_udi (udi)
    class _Hardware: 
    589510#                        elif boardproduct is not None and boardproduct is not None:
    590511#                            props['system.vendor'] = boardvendor
    591512#                            props['system.product'] = boardproduct
    592                 self.host = Host()
     513                self.host = Host(gate, uuid)
    593514
    594         self.fss = get_file_systems()
     515        self.fss = get_file_systems(gate)
    595516
    596         self.distro_specific = self.get_distro_specific_data()
     517        self.distro_specific = self.get_distro_specific_data(gate)
    597518
    598     def get_distro_specific_data(self):
     519    def get_distro_specific_data(self, gate):
    599520        dist_dict = {}
    600         import distros.all
     521        try:
     522            import distros.all
     523        except:
     524            return dist_dict
     525           
    601526        for d in distros.all.get():
    602527            key = d.key()
    603528            if d.detected():
    604529                logging.info('Distro "%s" detected' % (key))
    605                 d.gather(debug=True)
     530                d.gather(gate, debug=True)
    606531                dist_dict[key] = {
    607532                    'data':d.data(),
    608533                    'html':d.html(),
    class _Hardware: 
    684609    def get_sendable_fss(self, protocol_version=smoltProtocol):
    685610        return [fs.to_dict() for fs in self.fss]
    686611
    687     def write_pub_uuid(self,smoonURL,pub_uuid):
     612    def write_pub_uuid(self, uuiddb, smoonURL, pub_uuid, uuid):
    688613        smoonURLparsed=urlparse(smoonURL)
    689614        if pub_uuid is None:
    690615            return
    691616
    692617        try:
    693             UuidDb().set_pub_uuid(getUUID(), smoonURLparsed[1], pub_uuid)
     618            uuiddb.set_pub_uuid(uuid, smoonURLparsed[1], pub_uuid)
    694619        except Exception, e:
    695620            sys.stderr.write(_('\tYour pub_uuid could not be written.\n\n'))
    696621        return
    class _Hardware: 
    726651                lines.append(v['html'])
    727652        return '\n'.join(lines)
    728653
    729     def send(self, smoonURL=smoonURL, batch=False):
     654    def send(self, uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout, proxies=proxies, batch=False):
    730655        def serialize(object, human=False):
    731656            if human:
    732657                indent = 2
    class _Hardware: 
    737662            return JSONEncoder(indent=indent, sort_keys=sort_keys).encode(object)
    738663
    739664        reset_resolver()
     665        grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout, proxies=proxies)
    740666        #first find out the server desired protocol
    741667        try:
    742             req = Request('/tokens/token_json?uuid=%s' % self.host.UUID)
    743             token = req.open()
    744         except urllib2.URLError, e:
     668            token = grabber.urlopen(urljoin(smoonURL + "/", '/tokens/token_json?uuid=%s' % self.host.UUID, False))
     669        except urlgrabber.grabber.URLGrabError, e:
    745670            error(_('Error contacting Server: %s') % e)
    746671            return (1, None, None)
    747672        tok_str = token.read()
    748673        try:
    749674            try:
    750                 tok_obj = json.loads(tok_str)
     675                tok_obj = simplejson.loads(tok_str)
    751676                if tok_obj['prefered_protocol'] in supported_protocols:
    752677                    prefered_protocol = tok_obj['prefered_protocol']
    753678                else:
    class _Hardware: 
    827752                pub_uuid = None
    828753            else:
    829754                pub_uuid = server_response
    830             self.write_pub_uuid(smoonURL, pub_uuid)
     755            self.write_pub_uuid(uuiddb, smoonURL, pub_uuid, uuid)
    831756
    832757            try:
    833                 req = Request('/tokens/admin_token_json?uuid=%s' % self.host.UUID)
    834                 admin_token = req.open()
    835             except urllib2.URLError, e:
     758                admin_token = grabber.urlopen(urljoin(smoonURL + "/", '/tokens/admin_token_json?uuid=%s' % self.host.UUID, False))
     759            except urlgrabber.grabber.URLGrabError, e:
    836760                error(_('An error has occured while contacting the server: %s' % e))
    837761                sys.exit(1)
    838762            admin_str = admin_token.read()
    839             admin_obj = json.loads(admin_str)
     763            admin_obj = simplejson.loads(admin_str)
    840764            if admin_obj['prefered_protocol'] in supported_protocols:
    841765                prefered_protocol = admin_obj['prefered_protocol']
    842766            else:
    class _Hardware: 
    848772                self.write_admin_token(smoonURL,admin,admin_token_file)
    849773        return (0, pub_uuid, admin)
    850774
    851     def regenerate_pub_uuid(self, smoonURL=smoonURL):
     775    def regenerate_pub_uuid(self, uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout):
     776        grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout)
    852777        try:
    853             req = Request('/client/regenerate_pub_uuid?uuid=%s' % self.host.UUID)
    854             new_uuid = req.open()
    855         except urllib2.URLError, e:
     778            new_uuid = grabber.urlopen(urljoin(smoonURL + "/", '/client/regenerate_pub_uuid?uuid=%s' % self.host.UUID))
     779        except urlgrabber.grabber.URLGrabError, e:
    856780            raise ServerError, str(e)
    857781
    858782        response = new_uuid.read()  # Either JSON or an error page in (X)HTML
    859783        try:
    860             response_dict = json.loads(response)
    861         except Exception, e:
     784            response_dict = simplejson.loads(response)
     785        except JSONDecodeError, e:
    862786            serverMessage(response)
    863787            raise ServerError, _('Reply from server could not be interpreted')
    864788        else:
    class _Hardware: 
    866790                pub_uuid = response_dict['pub_uuid']
    867791            except KeyError:
    868792                raise ServerError, _('Reply from server could not be interpreted')
    869             self.write_pub_uuid(smoonURL,pub_uuid)
     793            self.write_pub_uuid(uuiddb, smoonURL, pub_uuid, uuid)
    870794            return pub_uuid
    871795
    872796
    class _Hardware: 
    998922                yield VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description
    999923
    1000924
    1001 _hardware_instance = None
    1002 def Hardware():
    1003     """Simple singleton wrapper with lazy initialization"""
    1004     global _hardware_instance
    1005     if _hardware_instance == None:
    1006         _hardware_instance = _Hardware()
    1007         #if enabled then insert the myth specific items into hardware
    1008         if Gate().grants("MythTV"):
    1009             _Hardware.get_sendable_host = smolt_mythtv.hardware_get_sendable_host
    1010             _Hardware.hostIter = smolt_mythtv.hardware_hostIter
    1011 
    1012     return _hardware_instance
    1013 
    1014 
    1015 # From RHN Client Tools
    1016 
    1017 def classify_hal(node):
    1018     # NETWORK
    1019     if node.has_key('net.interface'):
    1020         return 'NETWORK'
    1021 
    1022     if node.has_key('pci.device_class'):
    1023         if node['pci.device_class'] == PCI_BASE_CLASS_NETWORK:
    1024             return 'NETWORK'
    1025 
    1026 
    1027     if node.has_key('info.product') and node.has_key('info.category'):
    1028         if node['info.category'] == 'input':
    1029             # KEYBOARD <-- do this before mouse, some keyboards have built-in mice
    1030             if 'keyboard' in node['info.product'].lower():
    1031                 return 'KEYBOARD'
    1032             # MOUSE
    1033             if 'mouse' in node['info.product'].lower():
    1034                 return 'MOUSE'
    1035 
    1036     if node.has_key('pci.device_class'):
    1037         #VIDEO
    1038         if node['pci.device_class'] == PCI_BASE_CLASS_DISPLAY:
    1039             return 'VIDEO'
    1040         #USB
    1041         if (node['pci.device_class'] ==  PCI_BASE_CLASS_SERIAL
    1042                 and node['pci.device_subclass'] == PCI_CLASS_SERIAL_USB):
    1043             return 'USB'
    1044 
    1045         if node['pci.device_class'] == PCI_BASE_CLASS_STORAGE:
    1046             #IDE
    1047             if node['pci.device_subclass'] == PCI_CLASS_STORAGE_IDE:
    1048                 return 'IDE'
    1049             #SCSI
    1050             if node['pci.device_subclass'] == PCI_CLASS_STORAGE_SCSI:
    1051                 return 'SCSI'
    1052             #RAID
    1053             if node['pci.device_subclass'] == PCI_CLASS_STORAGE_RAID:
    1054                 return 'RAID'
    1055         #MODEM
    1056         if (node['pci.device_class'] == PCI_BASE_CLASS_COMMUNICATION
    1057                 and node['pci.device_subclass'] == PCI_CLASS_COMMUNICATION_MODEM):
    1058             return 'MODEM'
    1059         #SCANNER
    1060         if (node['pci.device_class'] == PCI_BASE_CLASS_INPUT
    1061                 and node['pci.device_subclass'] == PCI_CLASS_INPUT_SCANNER):
    1062             return 'SCANNER'
    1063 
    1064         if node['pci.device_class'] == PCI_BASE_CLASS_MULTIMEDIA:
    1065             #CAPTURE -- video capture card
    1066             if node['pci.device_subclass'] == PCI_CLASS_MULTIMEDIA_VIDEO:
    1067                 return 'CAPTURE'
    1068             #AUDIO
    1069             if (node['pci.device_subclass'] == PCI_CLASS_MULTIMEDIA_AUDIO
    1070                     or node['pci.device_subclass'] == PCI_CLASS_MULTIMEDIA_HD_AUDIO):
    1071                 return 'AUDIO'
    1072 
    1073         #FIREWIRE
    1074         if (node['pci.device_class'] == PCI_BASE_CLASS_SERIAL
    1075                 and node['pci.device_subclass'] == PCI_CLASS_SERIAL_FIREWIRE):
    1076             return 'FIREWIRE'
    1077         #SOCKET -- PCMCIA yenta socket stuff
    1078         if (node['pci.device_class'] == PCI_BASE_CLASS_BRIDGE
    1079                 and (node['pci.device_subclass'] == PCI_CLASS_BRIDGE_PCMCIA
    1080                 or node['pci.device_subclass'] == PCI_CLASS_BRIDGE_CARDBUS)):
    1081             return 'SOCKET'
    1082 
    1083     if node.has_key('storage.drive_type'):
    1084         return node['storage.drive_type'].upper()
    1085 
    1086     #PRINTER
    1087     if node.has_key('printer.product'):
    1088         return 'PRINTER'
    1089 
    1090     #Catchall for specific devices, only do this after all the others
    1091     if (node.has_key('pci.product_id') or
    1092             node.has_key('usb.product_id')):
    1093         return 'OTHER'
    1094 
    1095     # No class found
    1096     return None
    1097 
    1098925# This has got to be one of the ugliest fucntions alive
    1099926def read_cpuinfo():
    1100927    def get_entry(a, entry):
    def read_memory_2_6(): 
    14091236    memdict['swap'] = str(swap_megs)
    14101237    return memdict
    14111238
     1239
     1240def create_profile_nocatch(gate, uuid):
     1241    return _HardwareProfile(gate, uuid)
     1242
     1243
    14121244## For refactoring, I'll probably want to make a library
    14131245## Of command line tool functions
    14141246## This is one of them
    1415 def get_profile():
     1247def create_profile(gate, uuid):
    14161248    try:
    1417         return Hardware()
     1249        return create_profile_nocatch(gate, uuid)
    14181250    except SystemBusError, e:
    14191251        error(_('Error:') + ' ' + e.msg)
    14201252        if e.hint is not None:
    def get_profile(): 
    14251257def get_profile_link(smoonURL, pub_uuid):
    14261258    return urljoin(smoonURL, '/client/show/%s' % pub_uuid)
    14271259
    1428 hw_uuid = None
    1429 def getUUID():
    1430     global hw_uuid
    1431     if hw_uuid != None:
    1432         return hw_uuid
    1433 
     1260def read_uuid():
    14341261    try:
    14351262        UUID = file(hw_uuid_file).read().strip()
    14361263    except IOError:
    def getUUID(): 
    14431270        except IOError:
    14441271            sys.stderr.write(_('Unable to determine UUID of system!\n'))
    14451272            raise UUIDError, 'Could not determine UUID of system!\n'
    1446     hw_uuid = UUID
    14471273    return UUID
    14481274
    1449 def getPubUUID(smoonURL=smoonURL):
    1450     smoonURLparsed=urlparse(smoonURL)
    1451     res = UuidDb().get_pub_uuid(getUUID(), smoonURLparsed[1])
    1452     if res:
    1453         return res
    1454 
    1455     try:
    1456         req = Request('/client/pub_uuid/%s' % getUUID())
    1457         o = req.open()
    1458         pudict = json.loads(o.read())
    1459         o.close()
    1460         UuidDb().set_pub_uuid(getUUID(), smoonURLparsed[1], pudict["pub_uuid"])
    1461         return pudict["pub_uuid"]
    1462     except Exception, e:
    1463         error(_('Error determining public UUID: %s') % e)
    1464         sys.stderr.write(_("Unable to determine Public UUID!  This could be a network error or you've\n"))
    1465         sys.stderr.write(_("not submitted your profile yet.\n"))
    1466         raise PubUUIDError, 'Could not determine Public UUID!\n'
     1275def read_pub_uuid(uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout, silent=False):
     1276        smoonURLparsed=urlparse(smoonURL)
     1277        res = uuiddb.get_pub_uuid(uuid, smoonURLparsed[1])
     1278        if res:
     1279                return res
     1280
     1281        grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout, proxies=proxies)
     1282        try:
     1283                o = grabber.urlopen(urljoin(smoonURL + "/", '/client/pub_uuid/%s' % uuid))
     1284                pudict = simplejson.loads(o.read())
     1285                o.close()
     1286                uuiddb.set_pub_uuid(uuid, smoonURLparsed[1], pudict["pub_uuid"])
     1287                return pudict["pub_uuid"]
     1288        except Exception, e:
     1289                if not silent:
     1290                        error(_('Error determining public UUID: %s') % e)
     1291                        sys.stderr.write(_("Unable to determine Public UUID!  This could be a network error or you've\n"))
     1292                        sys.stderr.write(_("not submitted your profile yet.\n"))
     1293                raise PubUUIDError, 'Could not determine Public UUID!\n'
  • mythtv/programs/scripts/hardwareprofile/software.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/software.py b/mythtv/programs/scripts/hardwareprofile/software.py
    index 378aa9b..ed6a48f 100644
    a b  
    11# smolt - Fedora hardware profiler
    22#
    33# Copyright (C) 2007 Mike McGrath
     4# Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
    45#
    56# This program is free software; you can redistribute it and/or modify
    67# it under the terms of the GNU General Public License as published by
    import commands 
    2122import re
    2223import sys
    2324import smolt_config
    24 from gate import Gate
     25
    2526
    2627def read_lsb_release():
    2728    if os.access('/usr/bin/lsb_release', os.X_OK):
  • mythtv/programs/scripts/hardwareprofile/uuiddb.py

    diff --git a/mythtv/programs/scripts/hardwareprofile/uuiddb.py b/mythtv/programs/scripts/hardwareprofile/uuiddb.py
    index 62de6c0..10d80b4 100644
    a b class _UuidDb: 
    6363        self._flush()
    6464
    6565
    66 _uuid_db_instance = None
    67 def UuidDb():
    68     """Simple singleton wrapper with lazy initialization"""
    69     global _uuid_db_instance
    70     if _uuid_db_instance == None:
    71         import config
    72         from smolt import get_config_attr
    73         _uuid_db_instance =  _UuidDb(get_config_attr("UUID_DB", os.path.expanduser('~/.smolt/uuiddb.cfg')))
    74     return _uuid_db_instance
     66def create_default_uuiddb():
     67    from smolt_config import get_config_attr
     68    _database_filename = get_config_attr("UUID_DB", os.path.expanduser('~/.smolt/uuiddb.cfg'))
     69    return _UuidDb(_database_filename)