diff options
| -rw-r--r-- | module/AddonManager.py | 2 | ||||
| -rw-r--r-- | module/api/ConfigApi.py | 24 | ||||
| -rw-r--r-- | module/config/ConfigManager.py | 20 | ||||
| -rw-r--r-- | module/database/ConfigDatabase.py | 12 | ||||
| -rw-r--r-- | module/interaction/EventManager.py | 6 | ||||
| -rw-r--r-- | module/web/static/js/views/settings/configSectionView.js | 1 | ||||
| -rw-r--r-- | module/web/static/js/views/settings/settingsView.js | 20 | ||||
| -rw-r--r-- | tests/manager/test_configManager.py | 5 | 
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 | 
