diff options
Diffstat (limited to 'system_profiler.py')
-rw-r--r-- | system_profiler.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/system_profiler.py b/system_profiler.py new file mode 100644 index 0000000..81dfb69 --- /dev/null +++ b/system_profiler.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- + +import json +import shelve +import logging +import os.path +import tempfile +import datetime +import plistlib +import subprocess + +from datetime import datetime, timedelta + + +DEFAULT_DT = 'Hardware' +CACHE_EXPIRE = timedelta(seconds=60*60*1) +PROFILER_PATH = '/usr/sbin/system_profiler' + + +class SystemProfile(object): + def __init__(self, dt=DEFAULT_DT): + types = subprocess.check_output([PROFILER_PATH, '-listDataTypes']).strip() + self.types = [x[2:].replace('DataType', '') for x in types.split("\n") if x.startswith('SP')] + self.types.sort() + + if dt not in self.types: + raise ValueError('Invalid type %s. Should be one of %s' % (dt, ', '.join(self.types))) + + tmp = tempfile.mkstemp() + self.dt = 'SP%sDataType' % dt + + shelf_path = os.path.join(tempfile.gettempdir(), '%s.system_profiler' % self.dt) + shelf = shelve.open(shelf_path) + + if shelf.get(dt) and shelf.get('expires'): + if shelf.get('expires') > datetime.now(): + self._data = shelf[dt] + return + + try: + subprocess.call([PROFILER_PATH, self.dt, '-detaillevel', 'full', '-xml'], stdout=tmp[0]) + except Exception as e: + raise Exception('Failed to fetch system profile: %s' % e) + + xml = plistlib.readPlist(tmp[1]) + self._data = xml[0]['_items'] + logging.debug(self._data) + + shelf['expires'] = datetime.now() + CACHE_EXPIRE + shelf[dt] = self._data + shelf.close() + + def json(self): + return json.dumps(self._data) + + def get_keys(self): + keys = self._data[0].keys() + keys.sort() + return keys + + def get_types(self): + return self.types + + def find(self, k, v): + """ + Return value(s) of property with key k containing v + """ + return [x for x in self._data if v in x[k]] + + def __str__(self): + return str(self._data) + + def __getattr__(self, attr): + try: + return self._data[0][attr] + except KeyError as e: + raise ValueError('Property "%s" not found' % attr) + + def __getitem__(self, attr): + return self._data[attr] + + +def types(): + return SystemProfile().get_types() + +def keys(dt=DEFAULT_DT): + return SystemProfile(dt).get_keys() + +def get(dt, param): + return getattr(SystemProfile(dt), param) + +def find(dt, k, v): + return SystemProfile(dt).find(k, v) |