diff options
author | RaNaN <Mast3rRaNaN@hotmail.de> | 2013-03-31 18:32:13 +0200 |
---|---|---|
committer | RaNaN <Mast3rRaNaN@hotmail.de> | 2013-03-31 18:32:13 +0200 |
commit | 9ea1ab90b4705ef4d5ce37ded36a214f276c0a18 (patch) | |
tree | 995539a44a25c54344639d5ade7aa3e48624ed97 | |
parent | added account page (diff) | |
download | pyload-9ea1ab90b4705ef4d5ce37ded36a214f276c0a18.tar.xz |
add and delete accounts, db will be resetted
-rw-r--r-- | module/AccountManager.py | 11 | ||||
-rw-r--r-- | module/api/AccountApi.py | 10 | ||||
-rw-r--r-- | module/database/AccountDatabase.py | 8 | ||||
-rw-r--r-- | module/database/DatabaseBackend.py | 10 | ||||
-rw-r--r-- | module/plugins/Account.py | 27 | ||||
-rw-r--r-- | module/remote/apitypes.py | 2 | ||||
-rw-r--r-- | module/remote/pyload.thrift | 2 | ||||
-rw-r--r-- | module/web/static/js/models/Account.js | 20 | ||||
-rw-r--r-- | module/web/static/js/views/accounts/accountListView.js | 4 | ||||
-rw-r--r-- | module/web/static/js/views/accounts/accountModal.js | 13 | ||||
-rw-r--r-- | module/web/static/js/views/accounts/accountView.js | 13 | ||||
-rw-r--r-- | module/web/templates/default/accounts.html | 12 | ||||
-rwxr-xr-x | module/web/templates/default/backbone/accountDialog.html | 2 |
13 files changed, 93 insertions, 41 deletions
diff --git a/module/AccountManager.py b/module/AccountManager.py index d90c957c3..6e2786d55 100644 --- a/module/AccountManager.py +++ b/module/AccountManager.py @@ -22,6 +22,7 @@ from random import choice from module.common.json_layer import json from module.utils import lock + class AccountManager: """manages all accounts""" @@ -45,7 +46,6 @@ class AccountManager: self.createAccount(plugin, loginname, password, options) - return def iterAccounts(self): """ yields login, account for all accounts""" @@ -55,11 +55,14 @@ class AccountManager: def saveAccounts(self): """save all account information""" + # TODO: multi user + # TODO: activated data = [] for name, plugin in self.accounts.iteritems(): - data.extend([(name, acc.loginname, acc.activated, acc.password, json.dumps(acc.options)) for acc in - plugin.itervalues()]) + data.extend( + [(name, acc.loginname, 1 if acc.activated else 0, acc.password, json.dumps(acc.options)) for acc in + plugin.itervalues()]) self.core.db.saveAccounts(data) def createAccount(self, plugin, loginname, password, options): @@ -102,7 +105,7 @@ class AccountManager: self.core.db.removeAccount(plugin, user) self.core.eventManager.dispatchEvent("account:deleted", plugin, user) else: - self.core.log.debug("Remove non existing account %s %s" % (plugin, user)) + self.core.log.debug("Remove non existent account %s %s" % (plugin, user)) @lock diff --git a/module/api/AccountApi.py b/module/api/AccountApi.py index d1586e7aa..981842b5c 100644 --- a/module/api/AccountApi.py +++ b/module/api/AccountApi.py @@ -19,7 +19,7 @@ class AccountApi(ApiComponent): accs = self.core.accountManager.getAllAccounts(refresh) accounts = [] for plugin in accs.itervalues(): - accounts.extend(plugin.values()) + accounts.extend([acc.toInfoData() for acc in plugin.values()]) return accounts @@ -32,9 +32,10 @@ class AccountApi(ApiComponent): return self.core.pluginManager.getPlugins("accounts").keys() @RequirePerm(Permission.Accounts) - def updateAccount(self, plugin, account, password=None, options={}): + def updateAccount(self, plugin, login, password): """Changes pw/options for specific account.""" - self.core.accountManager.updateAccount(plugin, account, password, options) + # TODO: options + self.core.accountManager.updateAccount(plugin, login, password, {}) def updateAccountInfo(self, account): """ Update account from :class:`AccountInfo` """ @@ -46,8 +47,7 @@ class AccountApi(ApiComponent): :param account: :class:`ÀccountInfo` instance """ - # TODO - self.core.accountManager.removeAccount(plugin, account) + self.core.accountManager.removeAccount(account.plugin, account.loginname) if Api.extend(AccountApi): diff --git a/module/database/AccountDatabase.py b/module/database/AccountDatabase.py index 1602451fa..518674951 100644 --- a/module/database/AccountDatabase.py +++ b/module/database/AccountDatabase.py @@ -3,8 +3,8 @@ from module.database import queue, async from module.database import DatabaseBackend -class AccountMethods: +class AccountMethods: @queue def loadAccounts(db): db.c.execute('SELECT plugin, loginname, activated, password, options FROM accounts;') @@ -12,10 +12,14 @@ class AccountMethods: @async def saveAccounts(db, data): - db.c.executemany('INSERT INTO accounts(plugin, loginname, activated, password, options) VALUES(?,?,?,?,?)', data) + # TODO: owner, shared + + db.c.executemany( + 'INSERT INTO accounts(plugin, loginname, activated, password, options) VALUES(?,?,?,?,?)', data) @async def removeAccount(db, plugin, loginname): db.c.execute('DELETE FROM accounts WHERE plugin=? AND loginname=?', (plugin, loginname)) + DatabaseBackend.registerSub(AccountMethods)
\ No newline at end of file diff --git a/module/database/DatabaseBackend.py b/module/database/DatabaseBackend.py index e77fc0966..54d1c54bb 100644 --- a/module/database/DatabaseBackend.py +++ b/module/database/DatabaseBackend.py @@ -30,7 +30,7 @@ except: import sqlite3 DB = None -DB_VERSION = 5 +DB_VERSION = 6 def set_DB(db): global DB @@ -162,9 +162,9 @@ class DatabaseBackend(Thread): self.conn.close() try: - self.manager.core.log.warning(_("File database was deleted due to incompatible version.")) + self.manager.core.log.warning(_("Database was deleted due to incompatible version.")) except: - print "File database was deleted due to incompatible version." + print "Database was deleted due to incompatible version." remove(self.VERSION_FILE) move(self.DB_FILE, self.DB_FILE + ".backup") @@ -225,7 +225,7 @@ class DatabaseBackend(Thread): #--convert scripts start - def _convertV5(self): + def _convertV6(self): return False #--convert scripts end @@ -364,7 +364,7 @@ class DatabaseBackend(Thread): 'CREATE TABLE IF NOT EXISTS "accounts" (' '"plugin" TEXT NOT NULL, ' '"loginname" TEXT NOT NULL, ' - '"owner", INTEGER NOT NULL, ' + '"owner" INTEGER NOT NULL DEFAULT -1, ' '"activated" INTEGER DEFAULT 1, ' '"password" TEXT DEFAULT "", ' '"shared" INTEGER DEFAULT 0, ' diff --git a/module/plugins/Account.py b/module/plugins/Account.py index 7c24298e7..3ba819a6f 100644 --- a/module/plugins/Account.py +++ b/module/plugins/Account.py @@ -10,11 +10,12 @@ from module.network.CookieJar import CookieJar from Base import Base + class WrongPassword(Exception): pass #noinspection PyUnresolvedReferences -class Account(Base, AccountInfo): +class Account(Base): """ Base class for every account plugin. Just overwrite `login` and cookies will be stored and the account becomes accessible in\ @@ -28,12 +29,14 @@ class Account(Base, AccountInfo): UNLIMITED = -2 # Default values + owner = None valid = True validuntil = -1 trafficleft = -1 maxtraffic = -1 premium = True activated = True + shared = False #: after that time [in minutes] pyload will relogin the account login_timeout = 600 @@ -47,9 +50,9 @@ class Account(Base, AccountInfo): Base.__init__(self, manager.core) if "activated" in options: - activated = from_string(options["activated"], "bool") + self.activated = from_string(options["activated"], "bool") else: - activated = Account.activated + self.activated = Account.activated for opt in self.known_opt: if opt not in options: @@ -59,9 +62,8 @@ class Account(Base, AccountInfo): if opt not in self.known_opt: del options[opt] - # default account attributes - AccountInfo.__init__(self, self.__name__, loginname, Account.valid, Account.validuntil, Account.trafficleft, - Account.maxtraffic, Account.premium, activated, options) + self.loginname = loginname + self.options = options self.manager = manager @@ -74,6 +76,11 @@ class Account(Base, AccountInfo): self.init() + def toInfoData(self): + return AccountInfo(self.__name__, self.loginname, self.owner, self.valid, self.validuntil, self.trafficleft, + self.maxtraffic, + self.premium, self.activated, self.shared, self.options) + def init(self): pass @@ -104,7 +111,6 @@ class Account(Base, AccountInfo): self.logDebug("Deprecated .login(...) signature omit user, data") self.login(self.loginname, {"password": self.password}, req) - self.valid = True except WrongPassword: self.logWarning( @@ -175,7 +181,7 @@ class Account(Base, AccountInfo): # make sure to login req = self.getAccountRequest() self.checkLogin(req) - self.logDebug("Get Account Info for %s" % self.loginname) + self.logInfo(_("Get Account Info for %s") % self.loginname) try: try: infos = self.loadAccountInfo(req) @@ -184,6 +190,7 @@ class Account(Base, AccountInfo): infos = self.loadAccountInfo(self.loginname, req) except Exception, e: infos = {"error": str(e)} + self.logError(_("Error: %s") % e) finally: req.close() @@ -247,7 +254,7 @@ class Account(Base, AccountInfo): def formatTrafficleft(self): if self.trafficleft is None: self.getAccountInfo(force=True) - return format_size(self.trafficleft*1024) + return format_size(self.trafficleft * 1024) def wrongPassword(self): raise WrongPassword @@ -280,7 +287,7 @@ class Account(Base, AccountInfo): if self.login_ts: # separate from fresh login to have better debug logs self.logDebug("Reached login timeout for %s" % self.loginname) else: - self.logDebug("Login with %s" % self.loginname) + self.logInfo(_("Login with %s") % self.loginname) self._login(req) return False diff --git a/module/remote/apitypes.py b/module/remote/apitypes.py index f725aa386..196491083 100644 --- a/module/remote/apitypes.py +++ b/module/remote/apitypes.py @@ -523,7 +523,7 @@ class Iface(object): pass def unpauseServer(self): pass - def updateAccount(self, plugin, account, password): + def updateAccount(self, plugin, login, password): pass def updateAccountInfo(self, account): pass diff --git a/module/remote/pyload.thrift b/module/remote/pyload.thrift index 032be92fd..57d7e0a0a 100644 --- a/module/remote/pyload.thrift +++ b/module/remote/pyload.thrift @@ -489,7 +489,7 @@ service Pyload { list<AccountInfo> getAccounts(1: bool refresh), list<string> getAccountTypes(), - void updateAccount(1: PluginName plugin, 2: string account, 3: string password), + void updateAccount(1: PluginName plugin, 2: string login, 3: string password), void updateAccountInfo(1: AccountInfo account), void removeAccount(1: AccountInfo account), diff --git a/module/web/static/js/models/Account.js b/module/web/static/js/models/Account.js index 55e63ac08..c6e023578 100644 --- a/module/web/static/js/models/Account.js +++ b/module/web/static/js/models/Account.js @@ -1,4 +1,4 @@ -define(['jquery', 'backbone', 'underscore', 'utils/apitypes'], function($, Backbone, _, Api) { +define(['jquery', 'backbone', 'underscore', 'app', 'utils/apitypes'], function($, Backbone, _, App, Api) { return Backbone.Model.extend({ @@ -22,7 +22,6 @@ define(['jquery', 'backbone', 'underscore', 'utils/apitypes'], function($, Backb // Model Constructor initialize: function() { - }, // Any time a model attribute is set, this method is called @@ -30,8 +29,21 @@ define(['jquery', 'backbone', 'underscore', 'utils/apitypes'], function($, Backb }, - save: function(options){ - // TODO + save: function(options) { + options = App.apiRequest('updateAccountInfo', {account: this.toJSON()}, options); + return $.ajax(options); + }, + + destroy: function(options) { + options = App.apiRequest('removeAccount', {account: this.toJSON()}, options); + var self = this; + options.success = function() { + self.trigger('destroy', self, self.collection, options); + }; + + // TODO request is not dispatched +// return Backbone.Model.prototype.destroy.call(this, options); + return $.ajax(options); } }); diff --git a/module/web/static/js/views/accounts/accountListView.js b/module/web/static/js/views/accounts/accountListView.js index ea01f679e..68dffaa98 100644 --- a/module/web/static/js/views/accounts/accountListView.js +++ b/module/web/static/js/views/accounts/accountListView.js @@ -26,8 +26,10 @@ define(['jquery', 'underscore', 'backbone', 'app', 'collections/AccountList', '. render: function() { var self = this; + App.vent.trigger('accounts:destroyContent'); + // TODO trs cant' be animated this.accounts.each(function(account) { - self.content.append(new accountView({model: account}).render().el); + self.content.appendWithHeight(new accountView({model: account}).render().el); }); }, diff --git a/module/web/static/js/views/accounts/accountModal.js b/module/web/static/js/views/accounts/accountModal.js index 898b10a89..755ffd510 100644 --- a/module/web/static/js/views/accounts/accountModal.js +++ b/module/web/static/js/views/accounts/accountModal.js @@ -52,8 +52,17 @@ define(['jquery', 'underscore', 'app', 'views/abstract/modalView', 'text!tpl/def add: function(e) { e.stopPropagation(); if (this.select) { - var plugin = this.select.val(); - // TODO + var plugin = this.select.val(), + login = this.$('#login').val(), + password = this.$('#password').val(), + self = this; + + $.ajax(App.apiRequest('updateAccount', { + plugin: plugin, login: login, password: password + }, { success: function() { + App.accountView.refresh(); + self.hide(); + }})); } } }); diff --git a/module/web/static/js/views/accounts/accountView.js b/module/web/static/js/views/accounts/accountView.js index f310e4cc2..7d6306523 100644 --- a/module/web/static/js/views/accounts/accountView.js +++ b/module/web/static/js/views/accounts/accountView.js @@ -1,18 +1,23 @@ -define(['jquery', 'underscore', 'backbone', 'app'], - function($, _, Backbone, App) { +define(['jquery', 'underscore', 'backbone', 'app', '../abstract/itemView'], + function($, _, Backbone, App, itemView) { // Renders settings over view page - return Backbone.View.extend({ + return itemView.extend({ - el: "li", + el: "tr", + template: _.compile($('#template-account').html()), events: { + 'click .btn-danger': 'deleteItem' }, initialize: function() { + this.listenTo(this.model, 'remove', this.unrender); + this.listenTo(App.vent, 'accounts:destroyContent', this.destroy); }, render: function() { + this.$el.html(this.template(this.model.toJSON())); return this; } }); diff --git a/module/web/templates/default/accounts.html b/module/web/templates/default/accounts.html index 06b81c330..c68f04653 100644 --- a/module/web/templates/default/accounts.html +++ b/module/web/templates/default/accounts.html @@ -14,6 +14,15 @@ {% block head %} <script type="text/template" id="template-account"> + <td><% plugin %></td> + <td><% loginname %></td> + <td><% valid %></td> + <td><% premium %></td> + <td><% trafficleft %></td> + <td><% shared %></td> + <td><% activated %></td> + <td><% shared %></td> + <td><button type="button" class="btn btn-danger">Delete</button> </td> </script> {% endblock %} @@ -29,13 +38,14 @@ <table class="table table-striped"> <thead> <tr> - <th>Name</th> <th>Plugin</th> + <th>Name</th> <th>Valid</th> <th>Premium</th> <th>Traffic</th> <th>Shared</th> <th>Activated</th> + <th>Delete</th> </tr> </thead> <tbody id="account-content"> diff --git a/module/web/templates/default/backbone/accountDialog.html b/module/web/templates/default/backbone/accountDialog.html index dbc88e66d..7961ad2ba 100755 --- a/module/web/templates/default/backbone/accountDialog.html +++ b/module/web/templates/default/backbone/accountDialog.html @@ -3,7 +3,7 @@ Add an account {% endblock %} {% block content %} - <form class="form-horizontal" action="#"> + <form class="form-horizontal" action="#" autocomplete="off"> <legend> Please enter your account data </legend> |