From: Simo Sorce Date: Fri, 24 Jan 2014 20:32:21 +0000 (-0500) Subject: Rename src package to ipsilon X-Git-Tag: v0.2.2~131 X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=commitdiff_plain;h=84dcd4573e24b2a8901cecbe4ae15967564861e9 Rename src package to ipsilon Signed-off-by: Petr Vobornik Reviewed-by: Simo Sorce --- diff --git a/ipsilon/__init_.py b/ipsilon/__init_.py new file mode 100644 index 0000000..e69de29 diff --git a/ipsilon/ipsilon.py b/ipsilon/ipsilon.py new file mode 100755 index 0000000..7a782d6 --- /dev/null +++ b/ipsilon/ipsilon.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 Simo Sorce +# +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys +sys.stdout = sys.stderr + +import os +import atexit +import threading +import cherrypy +from util import plugin +from util import data +from util import page +from jinja2 import Environment, FileSystemLoader +import root + +cherrypy.config.update('ipsilon.conf') + +plugins = plugin.Plugins(path=cherrypy.config['base.dir']) +idp_providers = plugins.get_providers() +if idp_providers: + cherrypy.config['idp_providers'] = idp_providers + +datastore = data.Store() +admin_config = datastore.get_admin_config() +for option in admin_config: + cherrypy.config[option] = admin_config[option] + +templates = os.path.join(cherrypy.config['base.dir'], 'templates') +env = Environment(loader=FileSystemLoader(templates)) + +cherrypy.tools.protect = cherrypy.Tool('before_handler', page.protect) + +if __name__ == "__main__": + conf = { '/': {'tools.staticdir.root': os.getcwd()}, + '/ui': { 'tools.staticdir.on': True, + 'tools.staticdir.dir': 'ui' } + } + cherrypy.quickstart(root.Root(env), '/', conf) + +else: + cherrypy.config['environment'] = 'embedded' + + if cherrypy.__version__.startswith('3.0') and cherrypy.engine.state == 0: + cherrypy.engine.start(blocking=False) + atexit.register(cherrypy.engine.stop) + + application = cherrypy.Application(root.Root(env), + script_name=None, config=None) diff --git a/ipsilon/root.py b/ipsilon/root.py new file mode 100755 index 0000000..a352641 --- /dev/null +++ b/ipsilon/root.py @@ -0,0 +1,26 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 Simo Sorce +# +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from util import page +import cherrypy + +class Root(page.Page): + + def root(self): + return self._template('index.html', title='Root') diff --git a/ipsilon/util/__init__.py b/ipsilon/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ipsilon/util/data.py b/ipsilon/util/data.py new file mode 100755 index 0000000..ec64588 --- /dev/null +++ b/ipsilon/util/data.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 Simo Sorce +# +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import sqlite3 +import cherrypy + +class Store(object): + + def __init__(self, path=None): + if path is None: + self._path = os.getcwd() + else: + self._path = path + + def _load_config(self, dbname): + con = None + rows = [] + try: + con = sqlite3.connect(dbname) + cur = con.cursor() + cur.executescript(""" + CREATE TABLE IF NOT EXISTS config(name TEXT, value TEXT) + """) + cur.execute("SELECT * FROM config") + rows = cur.fetchall() + con.commit() + except sqlite3.Error, e: + if con: + con.rollback() + cherrypy.log.error("Failed to load config: [%s]" % e) + finally: + if con: + con.close() + + conf = {} + for row in rows: + if row[0] in conf: + # multivalued + if conf[row[0]] is list: + conf[row[0]].append(row[1]) + else: + v = conf[row[0]] + conf[row[0]] = [v, row[1]] + else: + conf[row[0]] = row[1] + + return conf + + def get_admin_config(self): + path = None + if 'admin.config.db' in cherrypy.config: + path = cherrypy.config['admin.config.db'] + if not path: + path = os.path.join(self._path, 'adminconfig.sqlite') + + return self._load_config(path) + + def _load_user_prefs(self, dbname, user): + con = None + rows = [] + try: + con = sqlite3.connect(dbname) + cur = con.cursor() + cur.executescript(""" + CREATE TABLE IF NOT EXISTS users(name TEXT, + option TEXT, + value TEXT) + """) + cur.execute("SELECT option, value FROM users " + "where name = '%s'" % user) + rows = cur.fetchall() + con.commit() + except sqlite3.Error, e: + if con: + con.rollback() + cherrypy.log.error("Failed to load %s's prefs from " + "%s: [%s]" % ( user, dbname, e)) + finally: + if con: + con.close() + + conf = {} + for row in rows: + conf[row[0]] = row[1] + + return conf + + def _get_user_preferences(self, user): + path = None + if 'user.prefs.db' in cherrypy.config: + path = cherrypy.config['user.prefs.db'] + if not path: + path = os.path.join(self._path, 'userprefs.sqlite') + + return self._load_user_prefs(path, user) diff --git a/ipsilon/util/page.py b/ipsilon/util/page.py new file mode 100755 index 0000000..15cbed0 --- /dev/null +++ b/ipsilon/util/page.py @@ -0,0 +1,60 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 Simo Sorce +# +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from util import user +import cherrypy + +def protect(): + if cherrypy.request.login: + user = cherrypy.session.get('user', None) + if user == cherrypy.request.login: + return + else: + cherrypy.session.regenerate() + cherrypy.session['user'] = cherrypy.request.login + +class Page(object): + def __init__(self, template_env): + self._env = template_env + self.basepath = cherrypy.config.get('base.mount', "") + self.username = None + + def __call__(self, *args, **kwargs): + self.username = cherrypy.session.get('user', None) + self.user = user.User(self.username) + + if len(args) > 0: + op = getattr(self, args[0], None) + if callable(op) and getattr(self, args[0]+'.exposed', None): + return op(args[1:], **kwargs) + else: + op = getattr(self, 'root', None) + if callable(op): + return op(**kwargs) + + return self.default(*args, **kwargs) + + def _template(self, *args, **kwargs): + t = self._env.get_template(args[0]) + return t.render(basepath=self.basepath, user=self.user, **kwargs) + + def default(self, *args, **kwargs): + raise cherrypy.HTTPError(404) + + exposed = True diff --git a/ipsilon/util/plugin.py b/ipsilon/util/plugin.py new file mode 100755 index 0000000..be9ed02 --- /dev/null +++ b/ipsilon/util/plugin.py @@ -0,0 +1,80 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 Simo Sorce +# +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import imp +import cherrypy + +class Plugins(object): + + def __init__(self, path=None): + if path is None: + self._path = os.getcwd() + else: + self._path = path + self._providers_tree = None + + def _load_class(self, tree, class_type, file_name): + cherrypy.log.error('Check module %s for class %s' % (file_name, + class_type)) + name, ext = os.path.splitext(os.path.split(file_name)[-1]) + try: + if ext.lower() == '.py': + mod = imp.load_source(name, file_name) + elif ex.lower() == '.pyc': + mod = imp.load_compiled(name, file_name) + else: + return + except Exception, e: + cherrypy.log.error('Failed to load "%s" module: [%s]' % (name, e)) + return + + if hasattr(mod, class_type): + tree[name] = getattr(mod, class_type)() + cherrypy.log.error('Added module %s' % (name)) + + def _load_classes(self, tree, path, class_type): + files = None + try: + files = os.listdir(path) + except Exception, e: + cherrypy.log.error('No modules in %s: [%s]' % (path, e)) + return + + for name in files: + filename = od.path.join(path, name) + self._load_class(tree, class_type, filename) + + def get_providers(self): + if self._providers_tree is None: + path = None + if 'providers.dir' in cherrypy.config: + path = cherrypy.config['providers.dir'] + if not path: + path = os.path.join(self._path, 'providers') + + self._providers_tree = [] + self._load_classes(self._providers_tree, path, 'IdpProvider') + + return self._providers_tree + + def get_custom(self, class_type): + tree = [] + self._load_classes(tree, class_type) + return tree diff --git a/ipsilon/util/user.py b/ipsilon/util/user.py new file mode 100755 index 0000000..1241340 --- /dev/null +++ b/ipsilon/util/user.py @@ -0,0 +1,79 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 Simo Sorce +# +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from util import data + +class Site(object): + def __init__(self, value): + # implement lookup of sites id for link/name + self.link = value + self.name = value + +class User(object): + def __init__(self, username): + if username is None: + self.name = None + self._userdata = dict() + else: + self._userdata = self._get_user_data(username) + self.name = username + + def _get_user_data(self, username): + store = data.Store() + return store._get_user_preferences(username) + + @property + def is_admin(self): + if 'is_admin' in self._userdata: + if self._userdata['is_admin'] == '1': + return True + return False + + @is_admin.setter + def is_admin(self, value): + if value is True: + self._userdata['is_admin'] = '1' + else: + self._userdata['is_admin'] = '0' + + @property + def fullname(self): + if 'fullname' in self._userdata: + return self._userdata['fullname'] + else: + return self.name + + @fullname.setter + def fullname(self, value): + self._userdata['fullname'] = value + + @property + def sites(self): + if 'sites' in self._userdata: + d = [] + for site in self._userdata['sites']: + d.append(Site(site)) + else: + return [] + + @sites.setter + def sites(self): + #TODO: implement setting sites via the user object ? + raise AttributeError + diff --git a/setup.py b/setup.py index 95e2f79..e2edc87 100755 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ setup( version = '0.1', license = 'GPLv3+', packages = ['ipsilon'], - package_dir = {'ipsilon': 'src'}, + package_dir = {'ipsilon': 'ipsilon'}, data_files = [('share/man/man7', ["man/ipsilon.7"]), ('doc', ['COPYING']), ('examples', ['examples/ipsilon.conf'])] diff --git a/src/__init_.py b/src/__init_.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/ipsilon.py b/src/ipsilon.py deleted file mode 100755 index 7a782d6..0000000 --- a/src/ipsilon.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2013 Simo Sorce -# -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import sys -sys.stdout = sys.stderr - -import os -import atexit -import threading -import cherrypy -from util import plugin -from util import data -from util import page -from jinja2 import Environment, FileSystemLoader -import root - -cherrypy.config.update('ipsilon.conf') - -plugins = plugin.Plugins(path=cherrypy.config['base.dir']) -idp_providers = plugins.get_providers() -if idp_providers: - cherrypy.config['idp_providers'] = idp_providers - -datastore = data.Store() -admin_config = datastore.get_admin_config() -for option in admin_config: - cherrypy.config[option] = admin_config[option] - -templates = os.path.join(cherrypy.config['base.dir'], 'templates') -env = Environment(loader=FileSystemLoader(templates)) - -cherrypy.tools.protect = cherrypy.Tool('before_handler', page.protect) - -if __name__ == "__main__": - conf = { '/': {'tools.staticdir.root': os.getcwd()}, - '/ui': { 'tools.staticdir.on': True, - 'tools.staticdir.dir': 'ui' } - } - cherrypy.quickstart(root.Root(env), '/', conf) - -else: - cherrypy.config['environment'] = 'embedded' - - if cherrypy.__version__.startswith('3.0') and cherrypy.engine.state == 0: - cherrypy.engine.start(blocking=False) - atexit.register(cherrypy.engine.stop) - - application = cherrypy.Application(root.Root(env), - script_name=None, config=None) diff --git a/src/root.py b/src/root.py deleted file mode 100755 index a352641..0000000 --- a/src/root.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2013 Simo Sorce -# -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from util import page -import cherrypy - -class Root(page.Page): - - def root(self): - return self._template('index.html', title='Root') diff --git a/src/util/__init__.py b/src/util/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/util/data.py b/src/util/data.py deleted file mode 100755 index ec64588..0000000 --- a/src/util/data.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2013 Simo Sorce -# -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import os -import sqlite3 -import cherrypy - -class Store(object): - - def __init__(self, path=None): - if path is None: - self._path = os.getcwd() - else: - self._path = path - - def _load_config(self, dbname): - con = None - rows = [] - try: - con = sqlite3.connect(dbname) - cur = con.cursor() - cur.executescript(""" - CREATE TABLE IF NOT EXISTS config(name TEXT, value TEXT) - """) - cur.execute("SELECT * FROM config") - rows = cur.fetchall() - con.commit() - except sqlite3.Error, e: - if con: - con.rollback() - cherrypy.log.error("Failed to load config: [%s]" % e) - finally: - if con: - con.close() - - conf = {} - for row in rows: - if row[0] in conf: - # multivalued - if conf[row[0]] is list: - conf[row[0]].append(row[1]) - else: - v = conf[row[0]] - conf[row[0]] = [v, row[1]] - else: - conf[row[0]] = row[1] - - return conf - - def get_admin_config(self): - path = None - if 'admin.config.db' in cherrypy.config: - path = cherrypy.config['admin.config.db'] - if not path: - path = os.path.join(self._path, 'adminconfig.sqlite') - - return self._load_config(path) - - def _load_user_prefs(self, dbname, user): - con = None - rows = [] - try: - con = sqlite3.connect(dbname) - cur = con.cursor() - cur.executescript(""" - CREATE TABLE IF NOT EXISTS users(name TEXT, - option TEXT, - value TEXT) - """) - cur.execute("SELECT option, value FROM users " - "where name = '%s'" % user) - rows = cur.fetchall() - con.commit() - except sqlite3.Error, e: - if con: - con.rollback() - cherrypy.log.error("Failed to load %s's prefs from " - "%s: [%s]" % ( user, dbname, e)) - finally: - if con: - con.close() - - conf = {} - for row in rows: - conf[row[0]] = row[1] - - return conf - - def _get_user_preferences(self, user): - path = None - if 'user.prefs.db' in cherrypy.config: - path = cherrypy.config['user.prefs.db'] - if not path: - path = os.path.join(self._path, 'userprefs.sqlite') - - return self._load_user_prefs(path, user) diff --git a/src/util/page.py b/src/util/page.py deleted file mode 100755 index 15cbed0..0000000 --- a/src/util/page.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2013 Simo Sorce -# -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from util import user -import cherrypy - -def protect(): - if cherrypy.request.login: - user = cherrypy.session.get('user', None) - if user == cherrypy.request.login: - return - else: - cherrypy.session.regenerate() - cherrypy.session['user'] = cherrypy.request.login - -class Page(object): - def __init__(self, template_env): - self._env = template_env - self.basepath = cherrypy.config.get('base.mount', "") - self.username = None - - def __call__(self, *args, **kwargs): - self.username = cherrypy.session.get('user', None) - self.user = user.User(self.username) - - if len(args) > 0: - op = getattr(self, args[0], None) - if callable(op) and getattr(self, args[0]+'.exposed', None): - return op(args[1:], **kwargs) - else: - op = getattr(self, 'root', None) - if callable(op): - return op(**kwargs) - - return self.default(*args, **kwargs) - - def _template(self, *args, **kwargs): - t = self._env.get_template(args[0]) - return t.render(basepath=self.basepath, user=self.user, **kwargs) - - def default(self, *args, **kwargs): - raise cherrypy.HTTPError(404) - - exposed = True diff --git a/src/util/plugin.py b/src/util/plugin.py deleted file mode 100755 index be9ed02..0000000 --- a/src/util/plugin.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2013 Simo Sorce -# -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import os -import imp -import cherrypy - -class Plugins(object): - - def __init__(self, path=None): - if path is None: - self._path = os.getcwd() - else: - self._path = path - self._providers_tree = None - - def _load_class(self, tree, class_type, file_name): - cherrypy.log.error('Check module %s for class %s' % (file_name, - class_type)) - name, ext = os.path.splitext(os.path.split(file_name)[-1]) - try: - if ext.lower() == '.py': - mod = imp.load_source(name, file_name) - elif ex.lower() == '.pyc': - mod = imp.load_compiled(name, file_name) - else: - return - except Exception, e: - cherrypy.log.error('Failed to load "%s" module: [%s]' % (name, e)) - return - - if hasattr(mod, class_type): - tree[name] = getattr(mod, class_type)() - cherrypy.log.error('Added module %s' % (name)) - - def _load_classes(self, tree, path, class_type): - files = None - try: - files = os.listdir(path) - except Exception, e: - cherrypy.log.error('No modules in %s: [%s]' % (path, e)) - return - - for name in files: - filename = od.path.join(path, name) - self._load_class(tree, class_type, filename) - - def get_providers(self): - if self._providers_tree is None: - path = None - if 'providers.dir' in cherrypy.config: - path = cherrypy.config['providers.dir'] - if not path: - path = os.path.join(self._path, 'providers') - - self._providers_tree = [] - self._load_classes(self._providers_tree, path, 'IdpProvider') - - return self._providers_tree - - def get_custom(self, class_type): - tree = [] - self._load_classes(tree, class_type) - return tree diff --git a/src/util/user.py b/src/util/user.py deleted file mode 100755 index 1241340..0000000 --- a/src/util/user.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2013 Simo Sorce -# -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from util import data - -class Site(object): - def __init__(self, value): - # implement lookup of sites id for link/name - self.link = value - self.name = value - -class User(object): - def __init__(self, username): - if username is None: - self.name = None - self._userdata = dict() - else: - self._userdata = self._get_user_data(username) - self.name = username - - def _get_user_data(self, username): - store = data.Store() - return store._get_user_preferences(username) - - @property - def is_admin(self): - if 'is_admin' in self._userdata: - if self._userdata['is_admin'] == '1': - return True - return False - - @is_admin.setter - def is_admin(self, value): - if value is True: - self._userdata['is_admin'] = '1' - else: - self._userdata['is_admin'] = '0' - - @property - def fullname(self): - if 'fullname' in self._userdata: - return self._userdata['fullname'] - else: - return self.name - - @fullname.setter - def fullname(self, value): - self._userdata['fullname'] = value - - @property - def sites(self): - if 'sites' in self._userdata: - d = [] - for site in self._userdata['sites']: - d.append(Site(site)) - else: - return [] - - @sites.setter - def sites(self): - #TODO: implement setting sites via the user object ? - raise AttributeError -