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