720f3b3eb6
The location of the config folder has changed. OctoPrint will try to migrate the configuration from its old location (~/.printerwebui, ...) to its new one (~/.octoprint, ...). For this to work the following conditions must be met: 1) the old config folder exists and is a directory 2) the new config folder does not exist at all. The migration functionality will be in the future.
154 lines
No EOL
3.9 KiB
Python
154 lines
No EOL
3.9 KiB
Python
# coding=utf-8
|
|
__author__ = "Gina Häußge <osd@foosel.net>"
|
|
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
|
|
|
import ConfigParser
|
|
import sys
|
|
import os
|
|
|
|
APPNAME="OctoPrint"
|
|
OLD_APPNAME="PrinterWebUI"
|
|
|
|
instance = None
|
|
|
|
def settings():
|
|
global instance
|
|
if instance is None:
|
|
instance = Settings()
|
|
return instance
|
|
|
|
default_settings = {
|
|
"serial": {
|
|
"port": None,
|
|
"baudrate": None
|
|
},
|
|
"server": {
|
|
"host": "0.0.0.0",
|
|
"port": 5000
|
|
},
|
|
"webcam": {
|
|
"stream": None,
|
|
"snapshot": None,
|
|
"ffmpeg": None
|
|
},
|
|
"folder": {
|
|
"uploads": None,
|
|
"timelapse": None,
|
|
"timelapse_tmp": None
|
|
},
|
|
"feature": {
|
|
"analyzeGcode": True
|
|
}
|
|
}
|
|
|
|
class Settings(object):
|
|
|
|
def __init__(self):
|
|
self.settings_dir = None
|
|
|
|
self._config = None
|
|
self._changes = None
|
|
|
|
self.init_settings_dir()
|
|
self.load()
|
|
|
|
def init_settings_dir(self):
|
|
self.settings_dir = _resolveSettingsDir(APPNAME)
|
|
|
|
# migration due to rename
|
|
old_settings_dir = _resolveSettingsDir(OLD_APPNAME)
|
|
if os.path.exists(old_settings_dir) and os.path.isdir(old_settings_dir) and not os.path.exists(self.settings_dir):
|
|
os.rename(old_settings_dir, self.settings_dir)
|
|
|
|
def load(self):
|
|
self._config = ConfigParser.ConfigParser(allow_no_value=True)
|
|
self._config.read(os.path.join(self.settings_dir, "config.ini"))
|
|
|
|
def save(self, force=False):
|
|
if self._changes is None and not force:
|
|
return
|
|
|
|
for section in default_settings.keys():
|
|
if self._changes.has_key(section):
|
|
for key in self._changes[section].keys():
|
|
value = self._changes[section][key]
|
|
if not self._config.has_section(section):
|
|
self._config.add_section(section)
|
|
self._config.set(section, key, value)
|
|
|
|
with open(os.path.join(self.settings_dir, "config.ini"), "wb") as configFile:
|
|
self._config.write(configFile)
|
|
self._changes = None
|
|
self.load()
|
|
|
|
def get(self, section, key):
|
|
if section not in default_settings.keys():
|
|
return None
|
|
|
|
if self._config.has_option(section, key):
|
|
return self._config.get(section, key)
|
|
|
|
if default_settings.has_key(section) and default_settings[section].has_key(key):
|
|
return default_settings[section][key]
|
|
|
|
return None
|
|
|
|
def getInt(self, section, key):
|
|
value = self.get(section, key)
|
|
if value is None:
|
|
return None
|
|
|
|
try:
|
|
return int(value)
|
|
except ValueError:
|
|
return None
|
|
|
|
def getBoolean(self, section, key):
|
|
value = self.get(section, key)
|
|
if value is None:
|
|
return None
|
|
if isinstance(value, bool):
|
|
return value
|
|
return value.lower() in ["true", "yes", "y", "1"]
|
|
|
|
def getBaseFolder(self, type):
|
|
if type not in default_settings["folder"].keys():
|
|
return None
|
|
|
|
folder = self.get("folder", type)
|
|
if folder is None:
|
|
folder = os.path.join(self.settings_dir, type.replace("_", os.path.sep))
|
|
|
|
if not os.path.isdir(folder):
|
|
os.makedirs(folder)
|
|
|
|
return folder
|
|
|
|
def set(self, section, key, value):
|
|
if section not in default_settings.keys():
|
|
return None
|
|
|
|
if self._changes is None:
|
|
self._changes = {}
|
|
|
|
if self._changes.has_key(section):
|
|
sectionConfig = self._changes[section]
|
|
else:
|
|
sectionConfig = {}
|
|
|
|
sectionConfig[key] = value
|
|
self._changes[section] = sectionConfig
|
|
|
|
def _resolveSettingsDir(applicationName):
|
|
# taken from http://stackoverflow.com/questions/1084697/how-do-i-store-desktop-application-data-in-a-cross-platform-way-for-python
|
|
if sys.platform == "darwin":
|
|
from AppKit import NSSearchPathForDirectoriesInDomains
|
|
# http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
|
|
# NSApplicationSupportDirectory = 14
|
|
# NSUserDomainMask = 1
|
|
# True for expanding the tilde into a fully qualified path
|
|
return os.path.join(NSSearchPathForDirectoriesInDomains(14, 1, True)[0], applicationName)
|
|
elif sys.platform == "win32":
|
|
return os.path.join(os.environ["APPDATA"], applicationName)
|
|
else:
|
|
return os.path.expanduser(os.path.join("~", "." + applicationName.lower())) |