MythTV  master
os_detect.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 
3 # smolt - Fedora hardware profiler
4 #
5 # Copyright (C) 2008 James Meyer <james.meyer@operamail.com>
6 # Copyright (C) 2008 Yaakov M. Nemoy <loupgaroublond@gmail.com>
7 # Copyright (C) 2009 Carlos Goncalves <mail@cgoncalves.info>
8 # Copyright (C) 2009 Francois Cami <fcami@fedoraproject.org>
9 # Copyright (C) 2010 Mike McGrath <mmcgrath@redhat.com>
10 # Copyright (C) 2012 Raymond Wagner <rwagner@mythtv.org>
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 
26 from __future__ import print_function
27 from builtins import object
28 import os
29 from future.utils import with_metaclass
30 
31 class OrderedType( type ):
32  # provide global sequencing for OS class and subclasses to ensure
33  # the be tested in proper order
34  nextorder = 0
35  def __new__(mcs, name, bases, attrs):
36  attrs['_order'] = mcs.nextorder
37  mcs.nextorder += 1
38  return type.__new__(mcs, name, bases, attrs)
39 
40 class OS( with_metaclass(OrderedType, object) ):
41  _requires_func = True
42  def __init__(self, ostype=-1, func=None, inst=None):
43  if callable(ostype):
44  # assume function being supplied directly
45  func = ostype
46  ostype = None
47 
48  # use None to ignore os.type() check, or -1 to default to 'posix'
49  self.ostype = ostype if ostype != -1 else 'posix'
50 
51  if (func is not None) and not callable(func):
52  raise TypeError((self.__class__.__name__ + "() requires a " \
53  "provided function be callable."))
54 
55  self.func = func
56  self.inst = inst
57 
58  if func:
59  self.__doc__ = func.__doc__
60  self.__name__ = func.__name__
61  self.__module__ = func.__module__
62 
63  def __get__(self, inst, owner):
64  if inst is None:
65  # class attribute, return self
66  return inst
67  func = self.func.__get__(inst, owner) if self.func else None
68  return self.__class__(self.ostype, func, inst)
69 
70  def __call__(self, func=None):
71  if self.inst is None:
72  # this is being called as a classmethod, prior to the class
73  # being initialized into an object. we want to operate as a
74  # descriptor, and receive a function as an argument
75  if self.func is not None:
76  raise TypeError((self.__class__.__name__ + "() has already " \
77  "been given a processing function"))
78  if (func is None) or not callable(func):
79  raise TypeError((self.__class__.__name__ + "() takes exactly " \
80  "one callable as a function, (0 given)"))
81  self.func = func
82  else:
83  if self._requires_func and (self.func is None):
84  raise RuntimeError((self.__class__.__name__ + "() has not " \
85  "been given a callable function"))
86 
87  # return boolean as to whether match was successful
88 
89  if (self.ostype is not None) and (os.name != self.ostype):
90  # os.type checking is enabled, and does not match
91  return False
92 
93  return self.do_test()
94 
95  def do_test(self, *args, **kwargs):
96  try:
97  # wrap function to handle failure for whatever reason
98  res = self.func(*args, **kwargs)
99  except:
100  return False
101  else:
102  if res:
103  # function returned positive, store it and return True
104  self.inst.name = res
105  return True
106  # function returned negative, return False so loop proceeds
107  return False
108 
109 class OSWithFile( OS ):
110  _requires_func = False
111  def __init__(self, filename, ostype='posix', func=None, inst=None):
112  self.filename = filename
113  super(OSWithFile, self).__init__(ostype, func, inst)
114 
115  def __get__(self, inst, owner):
116  if inst is None:
117  return inst
118  func = self.func.__get__(inst, owner) if self.func else None
119  return self.__class__(self.filename, self.ostype, func, inst)
120 
121  def do_test(self, *args, **kwargs):
122  if not os.path.exists(self.filename):
123  # filename does not exist, so assume no match
124  return False
125 
126  text = open(self.filename).read().strip()
127  if self.func:
128  # pass text into function for further processing
129  return super(OSWithFile, self).do_test(text)
130  else:
131  # store text as version string, and report success
132  self.inst.name = text
133  return True
134 
135 class OSFromUname( OS ):
136  @property
137  def uname(self):
138  # only bother running this once, store the result
139  try: return self._uname
140  except AttributeError: pass
141 
142  try:
143  # requires subprocess to operate
144  from subprocess import Popen, PIPE
145  except ImportError:
146  return {}
147 
148  # requires uname. if need be, this can be modified to try PATH
149  # searching in the environment.
150  path = '/usr/bin/uname'
151  if not os.path.exists(path):
152  return {}
153 
154  self._uname = {}
155  # pull OS name and release from uname. more can be added if needed
156  for k,v in (('OS', '-s'),
157  ('version', '-r')):
158  p = Popen([path, v], stdout=PIPE)
159  p.wait()
160  self._uname[k] = p.stdout.read().strip()
161 
162  return self._uname
163 
164  def do_test(self, *args, **kwargs):
165  if len(self.uname) == 0:
166  return False
167  return super(OSFromUname, self).do_test(**self.uname)
168 
169 class OSInfoType( type ):
170  def __new__(mcs, name, bases, attrs):
171  OSs = []
172  for k,v in list(attrs.items()):
173  if isinstance(v, OS):
174  # build list of stored OS types
175  OSs.append((v._order, k))
176  # sort by ordering value inserted by OrderedType metaclass
177  attrs['_oslist'] = [i[1] for i in sorted(OSs)]
178  return type.__new__(mcs, name, bases, attrs)
179 
180  def __call__(cls):
181  obj = cls.__new__(cls)
182  obj.__init__()
183  for attr in obj._oslist:
184  # loop through all availble OS types in specified order
185  if getattr(obj, attr)():
186  # if type returns success, return value
187  return obj.name
188  else:
189  # fall through to Unknown
190  return 'Unknown'
191 
192 class get_os_info( with_metaclass(OSInfoType, object) ):
193  @OS('nt')
194  def windows(self):
195  win_version = {
196  (1, 4, 0): '95',
197  (1, 4, 10): '98',
198  (1, 4, 90): 'ME',
199  (2, 4, 0): 'NT',
200  (2, 5, 0): '2000',
201  (2, 5, 1): 'XP'
202  }[os.sys.getwindowsversion()[3],
203  os.sys.getwindowsversion()[0],
204  os.sys.getwindowsversion()[1] ]
205  return "Windows " + win_version
206 
207  blag_linux = OSWithFile('/etc/blag-release')
208  mythvantage = OSWithFile('/etc/mythvantage-release')
209  knoppmyth = OSWithFile('/etc/KnoppMyth-version')
210  linhes = OSWithFile('/etc/LinHES-release')
211  mythdora = OSWithFile('/etc/mythdora-release')
212 
213  @OSWithFile('/etc/arch-release')
214  def archlinux(self, text):
215  return 'Arch Linux'
216 
217  @OSWithFile('/etc/aurox-release')
218  def auroxlinux(self, text):
219  return 'Aurox Linux'
220 
221  conectiva = OSWithFile('/etc/conectiva-release')
222  debian = OSWithFile('/etc/debian_release')
223 
224  @OSWithFile('/etc/debian_version')
225  def ubuntu(self, text):
226  text = open('/etc/issue.net').read().strip()
227  if text.find('Ubuntu'):
228  try:
229  mtext = open('/var/log/installer/media-info').read().strip()
230  except:
231  pass
232  else:
233  if 'Mythbuntu' in mtext:
234  text.replace('Ubuntu', 'Mythbuntu')
235  return text
236  return False
237 
238  debian2 = OSWithFile('/etc/debian_version')
239  fedora = OSWithFile('/etc/fedora-release')
240  gentoo = OSWithFile('/etc/gentoo-release')
241  lfsfile = OSWithFile('/etc/lfs-release')
242  mandrake = OSWithFile('/etc/mandrake-release')
243  mandriva = OSWithFile('/etc/mandriva-release')
244  pardus = OSWithFile('/etc/pardus-release')
245  slackware = OSWithFile('/etc/slackware-release')
246  solaris = OSWithFile('/etc/release')
247  sunjds = OSWithFile('/etc/sun-release')
248  pldlinux = OSWithFile('/etc/pld-release')
249 
250  @OSWithFile('/etc/SuSE-release')
251  def suselinux(self, text):
252  import re
253  text = text.split('\n')[0].strip()
254  return re.sub('\(\w*\)$', '', text)
255 
256  yellowdog = OSWithFile('/etc/yellowdog-release')
257  redhat = OSWithFile('/etc/redhat-release')
258 
259  @OSFromUname
260  def freebsd(self, OS, version):
261  if OS == 'FreeBSD':
262  return 'FreeBSD '+version
263  return False
264 
265  @OSFromUname
266  def OSX(self, OS, version):
267  if OS != 'Darwin':
268  return False
269  major,minor,point = [int(a) for a in version.split('.')]
270  return 'OS X 10.%s.%s' % (major-4, minor)
271 
272  @OS
273  def linuxstandardbase(self):
274  from subprocess import Popen, PIPE
275  executable = 'lsb_release'
276  for path in os.environ['PATH'].split(':'):
277  fullpath = os.path.join(path, executable)
278  if os.path.exists(fullpath):
279  break
280  else:
281  return False
282 
283  p = Popen([fullpath, '--id', '--codename', '--release', '--short'],
284  stdout=PIPE, close_fds=True)
285  p.wait()
286  return p.stdout.read().decode().strip().replace('\n', ' ')
287 
288  @OSFromUname
289  def Linux(self, OS, version):
290  if OS == 'Linux':
291  return 'Unknown Linux '+version
292  return False
293 
294 
295 if __name__ == '__main__':
296  results = get_os_info()
297  print('Test results="{}"'.format(results))
hardwareprofile.os_detect.get_os_info.ubuntu
def ubuntu(self, text)
Definition: os_detect.py:225
hardwareprofile.os_detect.OS._requires_func
bool _requires_func
Definition: os_detect.py:41
hardwareprofile.os_detect.OSFromUname.uname
def uname(self)
Definition: os_detect.py:137
hardwareprofile.os_detect.get_os_info.windows
def windows(self)
Definition: os_detect.py:194
hardwareprofile.os_detect.OS
Definition: os_detect.py:40
hardwareprofile.os_detect.OS.__init__
def __init__(self, ostype=-1, func=None, inst=None)
Definition: os_detect.py:42
discid.disc.read
def read(device=None, features=[])
Definition: disc.py:35
hardwareprofile.os_detect.OS.__call__
def __call__(self, func=None)
Definition: os_detect.py:70
hardwareprofile.os_detect.OS.ostype
ostype
Definition: os_detect.py:49
hardwareprofile.os_detect.OS.__module__
__module__
Definition: os_detect.py:61
hardwareprofile.os_detect.OS.__doc__
__doc__
Definition: os_detect.py:59
hardwareprofile.os_detect.OSWithFile.__get__
def __get__(self, inst, owner)
Definition: os_detect.py:115
decode
static int decode(unsigned char *vbiline, int scale0, int scale1)
Definition: cc.cpp:67
hardwareprofile.os_detect.OS.do_test
def do_test(self, *args, **kwargs)
Definition: os_detect.py:95
hardwareprofile.os_detect.OrderedType
Definition: os_detect.py:31
hardwareprofile.os_detect.OS.__name__
__name__
Definition: os_detect.py:60
hardwareprofile.os_detect.OSWithFile.filename
filename
Definition: os_detect.py:112
hardwareprofile.os_detect.get_os_info.archlinux
def archlinux(self, text)
Definition: os_detect.py:214
hardwareprofile.os_detect.get_os_info.suselinux
def suselinux(self, text)
Definition: os_detect.py:251
hardwareprofile.os_detect.OSFromUname._uname
_uname
Definition: os_detect.py:154
hardwareprofile.os_detect.OSWithFile.do_test
def do_test(self, *args, **kwargs)
Definition: os_detect.py:121
hardwareprofile.os_detect.OSWithFile.__init__
def __init__(self, filename, ostype='posix', func=None, inst=None)
Definition: os_detect.py:111
hardwareprofile.os_detect.get_os_info.Linux
def Linux(self, OS, version)
Definition: os_detect.py:289
hardwareprofile.os_detect.get_os_info.freebsd
def freebsd(self, OS, version)
Definition: os_detect.py:260
print
static void print(const QList< uint > &raw_minimas, const QList< uint > &raw_maximas, const QList< float > &minimas, const QList< float > &maximas)
Definition: vbi608extractor.cpp:29
hardwareprofile.os_detect.OSFromUname
Definition: os_detect.py:135
hardwareprofile.os_detect.OrderedType.__new__
def __new__(mcs, name, bases, attrs)
Definition: os_detect.py:35
hardwareprofile.os_detect.get_os_info
Definition: os_detect.py:192
hardwareprofile.os_detect.get_os_info.linuxstandardbase
def linuxstandardbase(self)
Definition: os_detect.py:273
hardwareprofile.os_detect.OS.func
func
Definition: os_detect.py:55
hardwareprofile.os_detect.OS.inst
inst
Definition: os_detect.py:56
hardwareprofile.os_detect.OSInfoType
Definition: os_detect.py:169
hardwareprofile.os_detect.OSFromUname.do_test
def do_test(self, *args, **kwargs)
Definition: os_detect.py:164
hardwareprofile.os_detect.OSInfoType.__call__
def __call__(cls)
Definition: os_detect.py:180
hardwareprofile.os_detect.OS.__get__
def __get__(self, inst, owner)
Definition: os_detect.py:63
hardwareprofile.os_detect.get_os_info.auroxlinux
def auroxlinux(self, text)
Definition: os_detect.py:218
hardwareprofile.os_detect.get_os_info.OSX
def OSX(self, OS, version)
Definition: os_detect.py:266
hardwareprofile.os_detect.OSWithFile
Definition: os_detect.py:109
hardwareprofile.os_detect.OSInfoType.__new__
def __new__(mcs, name, bases, attrs)
Definition: os_detect.py:170