import sys from os import getenv, makedirs, mkdir from os.path import expanduser, dirname, isdir, join from sys import platform appname = 'EDMarketConnector' applongname = 'E:D Market Connector' appversion = '1.4.1.0' if platform=='darwin': from Foundation import NSBundle, NSUserDefaults, NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSDocumentDirectory, NSLibraryDirectory, NSUserDomainMask elif platform=='win32': import ctypes import numbers CSIDL_PERSONAL = 0x0005 CSIDL_LOCAL_APPDATA = 0x001C # _winreg that ships with Python 2 doesn't support unicode, so do this instead from ctypes.wintypes import * HKEY_CURRENT_USER = 0x80000001 KEY_ALL_ACCESS = 0x000F003F REG_CREATED_NEW_KEY = 0x00000001 REG_OPENED_EXISTING_KEY = 0x00000002 REG_SZ = 1 REG_DWORD = 4 RegCreateKeyEx = ctypes.windll.advapi32.RegCreateKeyExW RegCreateKeyEx.restype = LONG RegCreateKeyEx.argtypes = [HKEY, LPCWSTR, DWORD, LPCVOID, DWORD, DWORD, LPCVOID, ctypes.POINTER(HKEY), ctypes.POINTER(DWORD)] RegOpenKeyEx = ctypes.windll.advapi32.RegOpenKeyExW RegOpenKeyEx.restype = LONG RegOpenKeyEx.argtypes = [HKEY, LPCWSTR, DWORD, DWORD, ctypes.POINTER(HKEY)] RegCloseKey = ctypes.windll.advapi32.RegCloseKey RegCloseKey.restype = LONG RegCloseKey.argtypes = [HKEY] RegQueryValueEx = ctypes.windll.advapi32.RegQueryValueExW RegQueryValueEx.restype = LONG RegQueryValueEx.argtypes = [HKEY, LPCWSTR, LPCVOID, ctypes.POINTER(DWORD), LPCVOID, ctypes.POINTER(DWORD)] RegSetValueEx = ctypes.windll.advapi32.RegSetValueExW RegSetValueEx.restype = LONG RegSetValueEx.argtypes = [HKEY, LPCWSTR, LPCVOID, DWORD, LPCVOID, DWORD] SHCopyKey = ctypes.windll.shlwapi.SHCopyKeyW SHCopyKey.restype = LONG SHCopyKey.argtypes = [HKEY, LPCWSTR, HKEY, DWORD] SHDeleteKey = ctypes.windll.shlwapi.SHDeleteKeyW SHDeleteKey.restype = LONG SHDeleteKey.argtypes = [HKEY, LPCWSTR] elif platform=='linux2': import codecs # requires python-iniparse package - ConfigParser that ships with Python < 3.2 doesn't support unicode from iniparse import RawConfigParser class Config: OUT_EDDN = 1 OUT_BPC = 2 OUT_TD = 4 OUT_CSV = 8 OUT_SHIP = 16 OUT_LOG = 32 if platform=='darwin': def __init__(self): self.app_dir = join(NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, True)[0], appname) if not isdir(self.app_dir): mkdir(self.app_dir) if not getattr(sys, 'frozen', False): # Don't use Python's settings if interactive self.bundle = 'uk.org.marginal.%s' % appname.lower() NSBundle.mainBundle().infoDictionary()['CFBundleIdentifier'] = self.bundle self.bundle = NSBundle.mainBundle().bundleIdentifier() self.defaults = NSUserDefaults.standardUserDefaults() settings = self.defaults.persistentDomainForName_(self.bundle) or {} self.settings = dict(settings) # Check out_dir exists if not self.get('outdir') or not isdir(self.get('outdir')): self.set('outdir', NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, True)[0]) def get(self, key): return self.settings.get(key) def getint(self, key): try: return int(self.settings.get(key, 0)) # should already be int, but check by casting except: return 0 def set(self, key, val): self.settings[key] = val def close(self): self.defaults.setPersistentDomain_forName_(self.settings, self.bundle) self.defaults.synchronize() self.defaults = None elif platform=='win32': def __init__(self): buf = ctypes.create_unicode_buffer(MAX_PATH) ctypes.windll.shell32.SHGetSpecialFolderPathW(0, buf, CSIDL_LOCAL_APPDATA, 0) self.app_dir = join(buf.value, appname) if not isdir(self.app_dir): mkdir(self.app_dir) self.hkey = HKEY() disposition = DWORD() if RegCreateKeyEx(HKEY_CURRENT_USER, r'Software\Marginal\EDMarketConnector', 0, None, 0, KEY_ALL_ACCESS, None, ctypes.byref(self.hkey), ctypes.byref(disposition)): raise Exception() if disposition.value == REG_CREATED_NEW_KEY: # Migrate pre-1.3.4 registry location oldkey = HKEY() if not RegOpenKeyEx(HKEY_CURRENT_USER, r'Software\EDMarketConnector', 0, KEY_ALL_ACCESS, ctypes.byref(oldkey)): SHCopyKey(oldkey, None, self.hkey, 0) SHDeleteKey(oldkey, '') RegCloseKey(oldkey) # set WinSparkle defaults - https://github.com/vslavik/winsparkle/wiki/Registry-Settings sparklekey = HKEY() if not RegCreateKeyEx(self.hkey, 'WinSparkle', 0, None, 0, KEY_ALL_ACCESS, None, ctypes.byref(sparklekey), ctypes.byref(disposition)): if disposition.value == REG_CREATED_NEW_KEY: buf = ctypes.create_unicode_buffer('1') RegSetValueEx(sparklekey, 'CheckForUpdates', 0, 1, buf, len(buf)*2) buf = ctypes.create_unicode_buffer(unicode(47*60*60)) RegSetValueEx(sparklekey, 'UpdateInterval', 0, 1, buf, len(buf)*2) RegCloseKey(sparklekey) if not self.get('outdir') or not isdir(self.get('outdir')): ctypes.windll.shell32.SHGetSpecialFolderPathW(0, buf, CSIDL_PERSONAL, 0) self.set('outdir', buf.value) def get(self, key): typ = DWORD() size = DWORD() if RegQueryValueEx(self.hkey, key, 0, ctypes.byref(typ), None, ctypes.byref(size)) or typ.value != REG_SZ: return None buf = ctypes.create_unicode_buffer(size.value / 2) if RegQueryValueEx(self.hkey, key, 0, ctypes.byref(typ), buf, ctypes.byref(size)): return None else: return buf.value def getint(self, key): typ = DWORD() size = DWORD(4) val = DWORD() if RegQueryValueEx(self.hkey, key, 0, ctypes.byref(typ), ctypes.byref(val), ctypes.byref(size)) or typ.value != REG_DWORD: return 0 else: return val.value def set(self, key, val): if isinstance(val, basestring): buf = ctypes.create_unicode_buffer(val) RegSetValueEx(self.hkey, key, 0, REG_SZ, buf, len(buf)*2) elif isinstance(val, numbers.Integral): RegSetValueEx(self.hkey, key, 0, REG_DWORD, ctypes.byref(DWORD(val)), 4) else: raise NotImplementedError() def close(self): RegCloseKey(self.hkey) self.hkey = None elif platform=='linux2': def __init__(self): # http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html self.app_dir = join(getenv('XDG_DATA_HOME', expanduser('~/.local/share')), appname) if not isdir(self.app_dir): makedirs(self.app_dir) self.filename = join(getenv('XDG_CONFIG_HOME', expanduser('~/.config')), appname, '%s.ini' % appname) if not isdir(dirname(self.filename)): makedirs(dirname(self.filename)) self.config = RawConfigParser() try: self.config.readfp(codecs.open(self.filename, 'r', 'utf-8')) except: self.config.add_section('config') if not self.get('outdir') or not isdir(self.get('outdir')): self.set('outdir', expanduser('~')) def set(self, key, val): self.config.set('config', key, val) def get(self, key): try: return self.config.get('config', key) # all values are stored as strings except: return None def getint(self, key): try: return int(self.config.get('config', key)) # all values are stored as strings except: return 0 def close(self): h = codecs.open(self.filename, 'w', 'utf-8') h.write(unicode(self.config.data)) h.close() self.config = None else: # ??? def __init__(self): raise NotImplementedError('Implement me') # singleton config = Config()