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