summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-03-31 18:32:13 +0200
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-03-31 18:32:13 +0200
commit9ea1ab90b4705ef4d5ce37ded36a214f276c0a18 (patch)
tree995539a44a25c54344639d5ade7aa3e48624ed97
parentadded account page (diff)
downloadpyload-9ea1ab90b4705ef4d5ce37ded36a214f276c0a18.tar.xz
add and delete accounts, db will be resetted
-rw-r--r--module/AccountManager.py11
-rw-r--r--module/api/AccountApi.py10
-rw-r--r--module/database/AccountDatabase.py8
-rw-r--r--module/database/DatabaseBackend.py10
-rw-r--r--module/plugins/Account.py27
-rw-r--r--module/remote/apitypes.py2
-rw-r--r--module/remote/pyload.thrift2
-rw-r--r--module/web/static/js/models/Account.js20
-rw-r--r--module/web/static/js/views/accounts/accountListView.js4
-rw-r--r--module/web/static/js/views/accounts/accountModal.js13
-rw-r--r--module/web/static/js/views/accounts/accountView.js13
-rw-r--r--module/web/templates/default/accounts.html12
-rwxr-xr-xmodule/web/templates/default/backbone/accountDialog.html2
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>