00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 import os
00028
00029 class OrderedType( type ):
00030
00031
00032 nextorder = 0
00033 def __new__(mcs, name, bases, attrs):
00034 attrs['_order'] = mcs.nextorder
00035 mcs.nextorder += 1
00036 return type.__new__(mcs, name, bases, attrs)
00037
00038 class OS( object ):
00039 __metaclass__ = OrderedType
00040 _requires_func = True
00041 def __init__(self, ostype=-1, func=None, inst=None):
00042 if callable(ostype):
00043
00044 func = ostype
00045 ostype = None
00046
00047
00048 self.ostype = ostype if ostype != -1 else 'posix'
00049
00050 if (func is not None) and not callable(func):
00051 raise TypeError((self.__class__.__name__ + "() requires a " \
00052 "provided function be callable."))
00053
00054 self.func = func
00055 self.inst = inst
00056
00057 if func:
00058 self.__doc__ = func.__doc__
00059 self.__name__ = func.__name__
00060 self.__module__ = func.__module__
00061
00062 def __get__(self, inst, owner):
00063 if inst is None:
00064
00065 return inst
00066 func = self.func.__get__(inst, owner) if self.func else None
00067 return self.__class__(self.ostype, func, inst)
00068
00069 def __call__(self, func=None):
00070 if self.inst is None:
00071
00072
00073
00074 if self.func is not None:
00075 raise TypeError((self.__class__.__name__ + "() has already " \
00076 "been given a processing function"))
00077 if (func is None) or not callable(func):
00078 raise TypeError((self.__class__.__name__ + "() takes exactly " \
00079 "one callable as a function, (0 given)"))
00080 self.func = func
00081 else:
00082 if self._requires_func and (self.func is None):
00083 raise RuntimeError((self.__class__.__name__ + "() has not " \
00084 "been given a callable function"))
00085
00086
00087
00088 if (self.ostype is not None) and (os.name != self.ostype):
00089
00090 return False
00091
00092 return self.do_test()
00093
00094 def do_test(self, *args, **kwargs):
00095 try:
00096
00097 res = self.func(*args, **kwargs)
00098 except:
00099 return False
00100 else:
00101 if res:
00102
00103 self.inst.name = res
00104 return True
00105
00106 return False
00107
00108 class OSWithFile( OS ):
00109 _requires_func = False
00110 def __init__(self, filename, ostype='posix', func=None, inst=None):
00111 self.filename = filename
00112 super(OSWithFile, self).__init__(ostype, func, inst)
00113
00114 def __get__(self, inst, owner):
00115 if inst is None:
00116 return inst
00117 func = self.func.__get__(inst, owner) if self.func else None
00118 return self.__class__(self.filename, self.ostype, func, inst)
00119
00120 def do_test(self, *args, **kwargs):
00121 if not os.path.exists(self.filename):
00122
00123 return False
00124
00125 text = open(self.filename).read().strip()
00126 if self.func:
00127
00128 return super(OSWithFile, self).do_test(text)
00129 else:
00130
00131 self.inst.name = text
00132 return True
00133
00134 class OSFromUname( OS ):
00135 @property
00136 def uname(self):
00137
00138 try: return self._uname
00139 except AttributeError: pass
00140
00141 try:
00142
00143 from subprocess import Popen, PIPE
00144 except ImportError:
00145 return {}
00146
00147
00148
00149 path = '/usr/bin/uname'
00150 if not os.path.exists(path):
00151 return {}
00152
00153 self._uname = {}
00154
00155 for k,v in (('OS', '-s'),
00156 ('version', '-r')):
00157 p = Popen([path, v], stdout=PIPE)
00158 p.wait()
00159 self._uname[k] = p.stdout.read().strip()
00160
00161 return self._uname
00162
00163 def do_test(self, *args, **kwargs):
00164 if len(self.uname) == 0:
00165 return False
00166 return super(OSFromUname, self).do_test(**self.uname)
00167
00168 class OSInfoType( type ):
00169 def __new__(mcs, name, bases, attrs):
00170 OSs = []
00171 for k,v in attrs.items():
00172 if isinstance(v, OS):
00173
00174 OSs.append((v._order, k))
00175
00176 attrs['_oslist'] = [i[1] for i in sorted(OSs)]
00177 return type.__new__(mcs, name, bases, attrs)
00178
00179 def __call__(cls):
00180 obj = cls.__new__(cls)
00181 obj.__init__()
00182 for attr in obj._oslist:
00183
00184 if getattr(obj, attr)():
00185
00186 return obj.name
00187 else:
00188
00189 return 'Unknown'
00190
00191 class get_os_info( object ):
00192 __metaclass__ = OSInfoType
00193
00194 @OS('nt')
00195 def windows(self):
00196 win_version = {
00197 (1, 4, 0): '95',
00198 (1, 4, 10): '98',
00199 (1, 4, 90): 'ME',
00200 (2, 4, 0): 'NT',
00201 (2, 5, 0): '2000',
00202 (2, 5, 1): 'XP'
00203 }[os.sys.getwindowsversion()[3],
00204 os.sys.getwindowsversion()[0],
00205 os.sys.getwindowsversion()[1] ]
00206 return "Windows " + win_version
00207
00208 blag_linux = OSWithFile('/etc/blag-release')
00209 mythvantage = OSWithFile('/etc/mythvantage-release')
00210 knoppmyth = OSWithFile('/etc/KnoppMyth-version')
00211 linhes = OSWithFile('/etc/LinHES-release')
00212 mythdora = OSWithFile('/etc/mythdora-release')
00213
00214 @OSWithFile('/etc/arch-release')
00215 def archlinux(self, text):
00216 return 'Arch Linux'
00217
00218 @OSWithFile('/etc/aurox-release')
00219 def auroxlinux(self, text):
00220 return 'Aurox Linux'
00221
00222 conectiva = OSWithFile('/etc/conectiva-release')
00223 debian = OSWithFile('/etc/debian_release')
00224
00225 @OSWithFile('/etc/debian_version')
00226 def ubuntu(self, text):
00227 text = open('/etc/issue.net').read().strip()
00228 if text.find('Ubuntu'):
00229 try:
00230 mtext = open('/var/log/installer/media-info').read().strip()
00231 except:
00232 pass
00233 else:
00234 if 'Mythbuntu' in mtext:
00235 text.replace('Ubuntu', 'Mythbuntu')
00236 return text
00237 return False
00238
00239 debian2 = OSWithFile('/etc/debian_version')
00240 fedora = OSWithFile('/etc/fedora-release')
00241 gentoo = OSWithFile('/etc/gentoo-release')
00242 lfsfile = OSWithFile('/etc/lfs-release')
00243 mandrake = OSWithFile('/etc/mandrake-release')
00244 mandriva = OSWithFile('/etc/mandriva-release')
00245 pardus = OSWithFile('/etc/pardus-release')
00246 slackware = OSWithFile('/etc/slackware-release')
00247 solaris = OSWithFile('/etc/release')
00248 sunjds = OSWithFile('/etc/sun-release')
00249 pldlinux = OSWithFile('/etc/pld-release')
00250
00251 @OSWithFile('/etc/SuSE-release')
00252 def suselinux(self, text):
00253 import re
00254 text = text.split('\n')[0].strip()
00255 return re.sub('\(\w*\)$', '', text)
00256
00257 yellowdog = OSWithFile('/etc/yellowdog-release')
00258 redhat = OSWithFile('/etc/redhat-release')
00259
00260 @OSFromUname
00261 def freebsd(self, OS, version):
00262 if OS == 'FreeBSD':
00263 return 'FreeBSD '+version
00264 return False
00265
00266 @OSFromUname
00267 def OSX(self, OS, version):
00268 if OS != 'Darwin':
00269 return False
00270 major,minor,point = [int(a) for a in version.split('.')]
00271 return 'OS X 10.%s.%s' % (major-4, minor)
00272
00273 @OS
00274 def linuxstandardbase(self):
00275 from subprocess import Popen, PIPE
00276 executable = 'lsb_release'
00277 for path in os.environ['PATH'].split(':'):
00278 fullpath = os.path.join(path, executable)
00279 if os.path.exists(fullpath):
00280 break
00281 else:
00282 return False
00283
00284 p = Popen([fullpath, '--id', '--codename', '--release', '--short'],
00285 stdout=PIPE, close_fds=True)
00286 p.wait()
00287 return p.stdout.read().strip().replace('\n', ' ')
00288