settings.py 3.25 KB
Newer Older
1 2 3 4 5 6 7 8 9
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 18 18:34:40 2018

@author: Antoine Lima, Leo Reynaert, Domitille Jehenne
"""

import json
Antoine Lima's avatar
Antoine Lima committed
10
import main
11

Antoine Lima's avatar
Antoine Lima committed
12 13 14 15 16 17 18 19 20
class MyEncoder(json.JSONEncoder):
	def default(self, obj):
		if isinstance(obj, Setting): 
			return obj.__dict__
		elif isinstance(obj, String) and obj=='settingsPath':
			return None
		else:
			return json.JSONEncoder.default(self, obj)

21 22 23 24
class Setting(object):
	TypeName = ''
	
	def __init__(self, value):
Antoine Lima's avatar
Antoine Lima committed
25
		self.type = type(self).TypeName
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
		self.value = value

class SettingBoolean(Setting):
	TypeName = 'boolean'
	
	def __init__(self, value):
		Setting.__init__(self, value)

class SettingCombo(Setting):
	TypeName = 'combo'
	
	def __init__(self, value, values):
		Setting.__init__(self, value)
		self.values = values
		
		if self.value not in values:
			raise ValueError('Setting value {} not in list of possible values {}'.format(self.value, self.values))

class SettingRange(Setting):
	TypeName = 'range'
	
	def __init__(self, value, limits):
		Setting.__init__(self, value)
Antoine Lima's avatar
Antoine Lima committed
49
		self.range = [min(limits), max(limits)]
50
		
Antoine Lima's avatar
Antoine Lima committed
51
		if self.value<self.range[0] or self.value>self.range[1]:
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
			raise ValueError('Setting value {} not in range {}'.format(self.value, (self.lower_limit, self.upper_limit)))
		
class SettingsHolder(object):
	def __init__(self, settingsPath):
		self.settingsPath = settingsPath
		self.loadSettingsFromJSON()
			
	def __delitem__(self, key):
		pass

	def __getitem__(self, key):
		subkeys = SettingsHolder._parseKey(key)
		
		if len(subkeys) == 2:
			return getattr(self, subkeys[0])[subkeys[1]].value
		elif len(subkeys) == 1:
			return getattr(self, subkeys[0]).value
		else:
			raise IndexError('Invalid key {}'.format(key))
	
	def __setitem__(self, key, value):
		subkeys = SettingsHolder._parseKey(key)
		
		if len(subkeys) == 2:
			getattr(self, subkeys[0])[subkeys[1]].value = value
		elif len(subkeys) == 1:
			getattr(self, subkeys[0]).value = value
		else:
			raise IndexError('Invalid key {}'.format(key))
	
	@staticmethod
	def _parseKey(key):
		return [k for k in key.split('.') if k]

	def loadSettingsFromJSON(self):
		with open(self.settingsPath, 'r') as f:
			content = json.load(f)
			
			# Outer loop, setting category
			for cat in content:
				setattr(self, cat, dict())
				content_outer = content[cat]
				
				# Inner loop, setting type
				for name in content_outer:
					content_inner = content_outer[name]
					typeName = content_inner['type']
					value = content_inner['value']
					
					# Switch over types
					if typeName == SettingBoolean.TypeName:
						setting = SettingBoolean(value)
					elif typeName == SettingCombo.TypeName:
						setting = SettingCombo(value, content_inner['values'])
					elif typeName == SettingRange.TypeName:
						setting = SettingRange(value, content_inner['range'])
					else:
						raise ValueError('Unknown setting type {}'.format(typeName))

					getattr(self, cat)[name] = setting

Antoine Lima's avatar
Antoine Lima committed
113 114 115 116 117 118 119 120 121 122
	def saveSettingsToJSON(self):
		# Deletes the settings path member to prevent it from being saved in the JSON 
		settingsPath = self.settingsPath
		del self.settingsPath
		
		with open(settingsPath, 'w') as f:
			content = json.dump(self.__dict__, f, cls=MyEncoder, indent=4)
		
		self.settingsPath = settingsPath

Antoine Lima's avatar
Antoine Lima committed
123
Settings = SettingsHolder(main.MainWin.getContent('settings.json'))