summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/AddonManager.py2
-rw-r--r--module/api/ConfigApi.py24
-rw-r--r--module/config/ConfigManager.py20
-rw-r--r--module/database/ConfigDatabase.py12
-rw-r--r--module/interaction/EventManager.py6
-rw-r--r--module/web/static/js/views/settings/configSectionView.js1
-rw-r--r--module/web/static/js/views/settings/settingsView.js20
-rw-r--r--tests/manager/test_configManager.py5
8 files changed, 51 insertions, 39 deletions
diff --git a/module/AddonManager.py b/module/AddonManager.py
index dc83a553f..9a8ad44ac 100644
--- a/module/AddonManager.py
+++ b/module/AddonManager.py
@@ -115,6 +115,8 @@ class AddonManager:
self.log.info(_("Deactivate addons: %s") % ", ".join(sorted(deactive)))
def manageAddons(self, plugin, name, value):
+ # TODO: user
+
# check if section was a plugin
if plugin not in self.core.pluginManager.getPlugins("addons"):
return
diff --git a/module/api/ConfigApi.py b/module/api/ConfigApi.py
index b2327eb9a..e398d4bd6 100644
--- a/module/api/ConfigApi.py
+++ b/module/api/ConfigApi.py
@@ -14,6 +14,7 @@ def toConfigHolder(section, config, values):
config.config.iteritems()]
return holder
+
class ConfigApi(ApiComponent):
""" Everything related to configuration """
@@ -25,7 +26,7 @@ class ConfigApi(ApiComponent):
:rtype: str
:return: config value as string
"""
- value = self.core.config.get(section, option, self.user)
+ value = self.core.config.get(section, option, self.primaryUID)
return to_string(value)
def setConfigValue(self, section, option, value):
@@ -38,7 +39,7 @@ class ConfigApi(ApiComponent):
if option in ("limit_speed", "max_speed"): #not so nice to update the limit
self.core.requestFactory.updateBucket()
- self.core.config.set(section, option, value, self.user)
+ self.core.config.set(section, option, value, self.primaryUID)
def getConfig(self):
"""Retrieves complete config of core.
@@ -68,7 +69,7 @@ class ConfigApi(ApiComponent):
# TODO: multi user
data = []
active = [x.getName() for x in self.core.addonManager.activePlugins()]
- for name, config, values in self.core.config.iterSections(self.user):
+ for name, config, values in self.core.config.iterSections(self.primaryUID):
# skip unmodified and inactive addons
if not values and name not in active: continue
@@ -88,10 +89,9 @@ class ConfigApi(ApiComponent):
"""
# TODO: filter user_context / addons when not allowed
plugins = [ConfigInfo(name, config.name, config.description,
- self.core.pluginManager.getCategory(name),
- self.core.pluginManager.isUserPlugin(name))
- for name, config, values in self.core.config.iterSections(self.user)]
-
+ self.core.pluginManager.getCategory(name),
+ self.core.pluginManager.isUserPlugin(name))
+ for name, config, values in self.core.config.iterSections(self.primaryUID)]
return plugins
@@ -103,7 +103,7 @@ class ConfigApi(ApiComponent):
:rtype: ConfigHolder
"""
# requires at least plugin permissions, but only admin can load core config
- config, values = self.core.config.getSection(name)
+ config, values = self.core.config.getSection(name, self.primaryUID)
return toConfigHolder(name, config, values)
@@ -113,7 +113,10 @@ class ConfigApi(ApiComponent):
:param config: :class:`ConfigHolder`
"""
- #TODO
+ for item in config.items:
+ self.core.config.set(config.name, item.name, item.value, sync=False, user=self.primaryUID)
+ # save the changes
+ self.core.config.saveValues(self.primaryUID, config.name)
@RequirePerm(Permission.Plugins)
def deleteConfig(self, plugin):
@@ -121,7 +124,8 @@ class ConfigApi(ApiComponent):
:param plugin: plugin name
"""
- self.core.config.delete(plugin, self.user)
+ #TODO: delete should deactivate addons?
+ self.core.config.delete(plugin, self.primaryUID)
if Api.extend(ConfigApi):
diff --git a/module/config/ConfigManager.py b/module/config/ConfigManager.py
index ff638fd71..b1cb05d53 100644
--- a/module/config/ConfigManager.py
+++ b/module/config/ConfigManager.py
@@ -42,7 +42,6 @@ class ConfigManager(ConfigParser):
# Entries are saved as (user, section) keys
self.values = {}
# TODO: similar to a cache, could be deleted periodically
- # TODO: user / primaryuid is a bit messy
def save(self):
self.parser.save()
@@ -53,12 +52,11 @@ class ConfigManager(ConfigParser):
if user is not valid default value will be returned"""
# Core config loaded from parser, when no user is given or he is admin
- if section in self.parser and (not user or(user and user.isAdmin())):
+ if section in self.parser and user is None:
return self.parser.get(section, option)
else:
# We need the id and not the instance
# Will be None for admin user and so the same as internal access
- user = primary_uid(user)
try:
# Check if this config exists
# Configs without meta data can not be loaded!
@@ -86,11 +84,9 @@ class ConfigManager(ConfigParser):
""" set config value """
changed = False
- if section in self.parser and (not user or (user and user.isAdmin())):
+ if section in self.parser and user is None:
changed = self.parser.set(section, option, value, sync)
else:
- # associated id
- user = primary_uid(user)
data = self.config[section].config[option]
value = from_string(value, data.type)
old_value = self.get(section, option)
@@ -99,7 +95,7 @@ class ConfigManager(ConfigParser):
if value != old_value:
changed = True
self.values[user, section][option] = value
- self.saveValues(user, section)
+ if sync: self.saveValues(user, section)
if changed: self.core.evm.dispatchEvent("config:changed", section, option, value)
return changed
@@ -107,22 +103,20 @@ class ConfigManager(ConfigParser):
def saveValues(self, user, section):
self.db.saveConfig(section, json.dumps(self.values[user, section]), user)
- def delete(self, section, user=False):
+ def delete(self, section, user=None):
""" Deletes values saved in db and cached values for given user, NOT meta data
Does not trigger an error when nothing was deleted. """
- user = primary_uid(user)
if (user, section) in self.values:
del self.values[user, section]
self.db.deleteConfig(section, user)
+ self.core.evm.dispatchEvent("config:deleted", section, user)
def iterCoreSections(self):
return self.parser.iterSections()
def iterSections(self, user=None):
""" Yields: section, metadata, values """
-
- user = primary_uid(user)
values = self.db.loadConfigsForUser(user)
# Every section needs to be json decoded
@@ -137,8 +131,8 @@ class ConfigManager(ConfigParser):
yield name, config, values[name] if name in values else {}
def getSection(self, section, user=None):
- if section in self.parser and primary_uid(user) is None:
+ if section in self.parser and user is None:
return self.parser.getSection(section)
- values = self.loadValues(section, user)
+ values = self.loadValues(user, section)
return self.config.get(section), values
diff --git a/module/database/ConfigDatabase.py b/module/database/ConfigDatabase.py
index 2e9fdd9a0..554e07132 100644
--- a/module/database/ConfigDatabase.py
+++ b/module/database/ConfigDatabase.py
@@ -7,18 +7,14 @@ class ConfigMethods(DatabaseMethods):
@async
def saveConfig(self, plugin, config, user=None):
- if user is None:
- self.c.execute('INSERT INTO settings(plugin, config) VALUES(?,?)', (plugin, config))
- else:
- self.c.execute('INSERT INTO settings(plugin, config, user) VALUES(?,?,?)', (plugin, config, user))
+ if user is None: user = -1
+ self.c.execute('INSERT INTO settings(plugin, config, user) VALUES(?,?,?)', (plugin, config, user))
@queue
def loadConfig(self, plugin, user=None):
- if user is None:
- self.c.execute('SELECT config FROM settings WHERE plugin=? AND user=-1', (plugin, ))
- else:
- self.c.execute('SELECT config FROM settings WHERE plugin=? AND user=?', (plugin, user))
+ if user is None: user = -1
+ self.c.execute('SELECT config FROM settings WHERE plugin=? AND user=?', (plugin, user))
r = self.c.fetchone()
return r[0] if r else ""
diff --git a/module/interaction/EventManager.py b/module/interaction/EventManager.py
index b25514b6a..7d37ca6b9 100644
--- a/module/interaction/EventManager.py
+++ b/module/interaction/EventManager.py
@@ -56,6 +56,12 @@ class EventManager:
if event in self.events:
self.events[event].remove(func)
+ def removeFromEvents(self, func):
+ """ Removes func from all known events """
+ for name, events in self.events.iteritems():
+ if func in events:
+ events.remove(func)
+
def dispatchEvent(self, event, *args):
"""dispatches event with args"""
for f in self.events["event"]:
diff --git a/module/web/static/js/views/settings/configSectionView.js b/module/web/static/js/views/settings/configSectionView.js
index 79f314309..b3861f27e 100644
--- a/module/web/static/js/views/settings/configSectionView.js
+++ b/module/web/static/js/views/settings/configSectionView.js
@@ -76,6 +76,7 @@ define(['jquery', 'underscore', 'backbone', 'app', '../abstract/itemView', '../i
this.model.save({success: function(){
console.log("saved");
self.render();
+ App.settingsView.refresh();
}});
},
diff --git a/module/web/static/js/views/settings/settingsView.js b/module/web/static/js/views/settings/settingsView.js
index 4e83322e5..9968a48e0 100644
--- a/module/web/static/js/views/settings/settingsView.js
+++ b/module/web/static/js/views/settings/settingsView.js
@@ -14,6 +14,7 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
},
menu: null,
+ selected: null,
content: null,
modal: null,
@@ -25,7 +26,6 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
lastConfig: null,
isLoading: false,
-
initialize: function() {
this.menu = this.$('.settings-menu');
this.content = this.$('.setting-box > form');
@@ -53,6 +53,9 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
core: this.coreConfig,
plugin: this.pluginConfig
}));
+
+ // mark the selected element
+ this.$('li[data-name="' + this.selected + '"]').addClass("active");
},
openConfig: function(name) {
@@ -112,7 +115,7 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
failure: function() {
// TODO
- this.config = null;
+ this.config = null;
},
change_section: function(e) {
@@ -120,15 +123,15 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
// TODO move this into render?
var el = $(e.target).parent();
- var name = el.data("name");
- this.openConfig(name);
+ this.selected = el.data("name");
+ this.openConfig(this.selected);
this.menu.find("li.active").removeClass("active");
el.addClass("active");
e.preventDefault();
},
- choosePlugin: function(e){
+ choosePlugin: function(e) {
var self = this;
_.requireOnce(['views/settings/pluginChooserModal'], function(Modal) {
if (self.modal === null)
@@ -138,12 +141,15 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ConfigHolder', './con
});
},
- deleteConfig: function(e){
+ deleteConfig: function(e) {
e.stopPropagation();
var el = $(e.target).parent().parent();
var name = el.data("name");
+ var self = this;
+ $.ajax(App.apiRequest("deleteConfig", {plugin: name}, { success: function() {
+ self.refresh();
+ }}));
- console.log("Delete config " + name);
}
});
diff --git a/tests/manager/test_configManager.py b/tests/manager/test_configManager.py
index 6c10da4dd..8ab607a87 100644
--- a/tests/manager/test_configManager.py
+++ b/tests/manager/test_configManager.py
@@ -5,13 +5,16 @@ from collections import defaultdict
from nose.tools import raises
-from tests.helper.Stubs import Core, adminUser, normalUser
+from tests.helper.Stubs import Core
from module.Api import InvalidConfigSection
from module.database import DatabaseBackend
from module.config.ConfigParser import ConfigParser
from module.config.ConfigManager import ConfigManager
+adminUser = None
+normalUser = 1
+
class TestConfigManager(TestCase):
@classmethod