1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-14 16:27:13 +03:00
EDMarketConnector/config.py
Jonathan Harris 31364d29a2 Make EDSM log entry automatically on system entry
Don't make log entry at stations.
2016-07-25 20:21:08 +01:00

280 lines
10 KiB
Python

import numbers
import sys
from os import getenv, makedirs, mkdir, pardir
from os.path import expanduser, dirname, isdir, join, normpath
from sys import platform
appname = 'EDMarketConnector'
applongname = 'E:D Market Connector'
appcmdname = 'EDMC'
appversion = '2.1.4.0'
update_feed = 'https://marginal.org.uk/edmarketconnector.xml'
update_interval = 47*60*60
if platform=='darwin':
from Foundation import NSBundle, NSUserDefaults, NSSearchPathForDirectoriesInDomains, NSApplicationSupportDirectory, NSDocumentDirectory, NSLibraryDirectory, NSUserDomainMask
elif platform=='win32':
import ctypes
CSIDL_PERSONAL = 0x0005
CSIDL_LOCAL_APPDATA = 0x001C
CSIDL_PROFILE = 0x0028
# _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]
RegCopyTree = ctypes.windll.advapi32.RegCopyTreeW
RegCopyTree.restype = LONG
RegCopyTree.argtypes = [HKEY, LPCWSTR, HKEY]
RegDeleteKey = ctypes.windll.advapi32.RegDeleteTreeW
RegDeleteKey.restype = LONG
RegDeleteKey.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_MKT_EDDN = 1
OUT_MKT_BPC = 2
OUT_MKT_TD = 4
OUT_MKT_CSV = 8
OUT_SHIP_EDS = 16
# OUT_SYS_FILE = 32 # No longer supported
# OUT_STAT = 64 # No longer available
OUT_SHIP_CORIOLIS = 128
OUT_SYS_EDSM = 256
# OUT_SYS_AUTO = 512 # Now always automatic
OUT_MKT_MANUAL = 1024
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)
self.plugin_dir = join(self.app_dir, 'plugins')
if not isdir(self.plugin_dir):
mkdir(self.plugin_dir)
self.home = expanduser('~')
self.respath = getattr(sys, 'frozen', False) and normpath(join(dirname(sys.executable), pardir, 'Resources')) or dirname(__file__)
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 save(self):
self.defaults.setPersistentDomain_forName_(self.settings, self.bundle)
self.defaults.synchronize()
def close(self):
self.save()
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.plugin_dir = join(self.app_dir, 'plugins')
if not isdir(self.plugin_dir):
mkdir(self.plugin_dir)
# expanduser in Python 2 on Windows doesn't handle non-ASCII - http://bugs.python.org/issue13207
ctypes.windll.shell32.SHGetSpecialFolderPathW(0, buf, CSIDL_PROFILE, 0)
self.home = buf.value
self.respath = dirname(getattr(sys, 'frozen', False) and sys.executable or __file__)
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)):
RegCopyTree(oldkey, None, self.hkey)
RegCloseKey(oldkey)
RegDeleteKey(HKEY_CURRENT_USER, r'Software\EDMarketConnector')
# 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(update_interval))
RegSetValueEx(sparklekey, 'UpdateInterval', 0, 1, buf, len(buf)*2)
RegCloseKey(sparklekey)
if not self.get('outdir') or not isdir(self.get('outdir')):
buf = ctypes.create_unicode_buffer(MAX_PATH)
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 save(self):
pass # Redundant since registry keys are written immediately
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.plugin_dir = join(self.app_dir, 'plugins')
if not isdir(self.plugin_dir):
mkdir(self.plugin_dir)
self.home = expanduser('~')
self.respath = dirname(__file__)
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):
assert isinstance(val, basestring) or isinstance(val, numbers.Integral), type(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 save(self):
h = codecs.open(self.filename, 'w', 'utf-8')
h.write(unicode(self.config.data))
h.close()
def close(self):
self.save()
self.config = None
else: # ???
def __init__(self):
raise NotImplementedError('Implement me')
# singleton
config = Config()