diff --git a/action/user.py b/action/user.py index 4134f00..c3520ac 100644 --- a/action/user.py +++ b/action/user.py @@ -52,7 +52,7 @@ class UserCreate(UserBase): self.propagate_exception(e) request.connection.commit() - return request.answer.complete_redirect(['user', str(user.id)]) + return request.answer.complete_redirect(['user', str(user.login)]) class UserUpdate(UserBase): @@ -70,7 +70,7 @@ class UserUpdate(UserBase): self.propagate_exception(e) request.connection.commit() - return request.answer.complete_redirect(['user', str(user.id)]) + return request.answer.complete_redirect(['user', str(user.login)]) class UserDelete(UserBase): @@ -114,7 +114,7 @@ class UserSetPassword(UserBase): self.propagate_exception(e) request.connection.commit() - return request.answer.complete_redirect(['user', str(user.id)]) + return request.answer.complete_redirect(['user', str(user.login)]) class UserSetSuperuser(UserBase): @@ -132,7 +132,7 @@ class UserSetSuperuser(UserBase): self.propagate_exception(e) request.connection.commit() - return request.answer.complete_redirect(['user', str(user.id)]) + return request.answer.complete_redirect(['user', str(user.login)]) actions = { diff --git a/answer.py b/answer.py index 82789ac..e625a2d 100644 --- a/answer.py +++ b/answer.py @@ -35,7 +35,7 @@ class Answer(Translator): self.text = '' self.html = '' - self.title = '' + self.uipath = list() self.content = '' self.errors = list() self.fields = dict() @@ -58,12 +58,10 @@ class Answer(Translator): def encodedfield(self, name): return self.e( self.fields.get(str(name), '') ) - def chain_title(self, subtitle): - if subtitle: - if self.title: - self.title = subtitle + ' | ' + self.title - else: - self.title = subtitle + def add_uipath_entry(self, title, path): + assert(type(title) is str) + assert(type(path) is list) + self.uipath.append((title, path)) def complete_redirect(self, path = None): self.status = '303 See Other' diff --git a/config.py b/config.py index 926930d..8757960 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,7 @@ config = { 'domain' : 'earthworm.local', + 'debug' : True, 'db': { 'prefix' : 'ew_', diff --git a/generator/form.py b/generator/form.py index bf07aab..7180418 100644 --- a/generator/form.py +++ b/generator/form.py @@ -44,7 +44,16 @@ class Form(): content = '\n' answer.content += '

' + answer.te(repo.repotype.name) + '

\n' answer.content += '

' + answer.e(repo.name) + '

\n' - answer.content += '

' + answer.e(repo.title) + '

\n' answer.content += '

' + answer.e(repo.description) + '

\n' - answer.content += '

' + request.protocol + request.domain + '/repo/' + repo.gen_subpath() + '

\n' + answer.content += '

' + answer.te('clone url:') + ' ' \ + + request.protocol \ + + request.domain \ + + '/repo/' \ + + repo.gen_subpath() \ + + '

\n' if repo.can_update(): answer.content += '

' + self.make_link(answer, prevpath + ['edit'], 'Edit repository') + '

\n' @@ -94,10 +94,10 @@ class RepoUpdatePage(Page): if not repo.can_update(): raise exception.HttpNotFound() - answer.chain_title( answer.te('Edit repository') ) + answer.add_uipath_entry( answer.t('Edit repository') ) form = Form(request) - form.begin('Edit repository', 'repo.update') + form.begin('Details', 'repo.update') form.add_hidden('repository_id', repo.id) form.add_input('title:', 'title', 'text', repo.title) form.add_textarea('description:', 'description', repo.description) @@ -128,8 +128,10 @@ class RepoDeletePage(Page): if not repo.can_delete(): raise exception.HttpNotFound() + answer.add_uipath_entry( answer.t('Delete repository'), prevpath ) + form = Form(request) - form.begin('Delete repository', 'repo.delete') + form.begin('', 'repo.delete') form.add_hidden('repository_id', repo.id) form.content += '

' + answer.te(repo.repotype.name) + '

\n' form.content += '

' + answer.e(repo.name) + '

\n' @@ -137,10 +139,11 @@ class RepoDeletePage(Page): form.content += '

' + answer.e(repo.description) + '

\n' form.content += '

' + answer.e(repo.description) + '

\n' form.content += '

' + request.protocol + request.domain + '/repo/' + repo.gen_subpath() + '

\n' + form.content += '

' + answer.te('Do you really want do delete repository?') + '

\n' form.add_submit('Confirm delete') form.end() - answer.content += form.content + return answer.complete_content() @@ -155,9 +158,8 @@ class RepoListPage(Page): repositories = request.model.repositories.get_list(user) answer = request.answer - answer.chain_title( answer.te('Repositories') ) + answer.add_uipath_entry( answer.t('Repositories'), prevpath ) - answer.content += '

' + answer.te('Repositories') + '

\n' for repo in repositories: url = request.get_urlpath_escaped(prevpath[:-1] + ['repo', str(repo.name)]) answer.content += '

' \ diff --git a/page/root.py b/page/root.py index 2f4d184..083ee4f 100644 --- a/page/root.py +++ b/page/root.py @@ -17,6 +17,8 @@ class RootPage(Page): answer = request.answer answer.template = self.commontemplate + answer.add_uipath_entry( answer.t(request.server.config['name']), prevpath ) + if path: if path[0] == 'user': return self.user.sub_process(request, path, prevpath) @@ -30,19 +32,20 @@ class RootPage(Page): else: raise exception.HttpNotFound() - answer.content += '

' + answer.te('root page') + '

' - answer.content += '

' + answer.te('Welcome!') + '

' + answer.content += '

' + answer.te('Welcome!') + '

' if request.model.users.can_list(): answer.content += '

' + self.make_link(answer, prevpath + ['users'], 'Users list') + '

\n' - answer.content += '

Env: \n' + answer.e(str(request.env)) + '

' + if request.server.config['debug']: + answer.content += '

' + answer.te('Debug data:') + '

' + answer.content += '

Env: \n' + answer.e(str(request.env)) + '

' - tables = list(v[0] for v in request.connection.query_list('SHOW TABLES')) - answer.content += '

DB tables: ' + answer.e(', '.join(tables)) + '

' + tables = list(v[0] for v in request.connection.query_list('SHOW TABLES')) + answer.content += '

DB tables: ' + answer.e(', '.join(tables)) + '

' - rows = request.connection.query_dict('SELECT * FROM %T', 'test') - answer.content += '

Rows of test table: ' + answer.e(str(rows)) + '

' + rows = request.connection.query_dict('SELECT * FROM %T', 'test') + answer.content += '

Rows of test table: ' + answer.e(str(rows)) + '

' return answer.complete_content() diff --git a/page/user.py b/page/user.py index 28c9862..d6621e7 100644 --- a/page/user.py +++ b/page/user.py @@ -1,5 +1,6 @@ import exception +from generator.form import Form from page.page import Page from page.repo import RepoPage, RepoCreatePage, RepoListPage @@ -12,16 +13,19 @@ class UserCreatePage(Page): if not request.model.users.can_create(): raise exception.HttpNotFound() answer = request.answer - answer.chain_title( answer.te('Create user') ) - answer.content += '

' + answer.te('Create user') + '

\n' - answer.content += '
\n' - answer.content += '\n' - answer.content += '

' + answer.te('login:') + '

\n' - answer.content += '

' + answer.te('password:') + '

\n' - answer.content += '

' + answer.te('retry password:') + '

\n' - answer.content += '

' + answer.te('name:') + '

\n' - answer.content += '

\n' - answer.content += '
\n' + + answer.add_uipath_entry( answer.t('Create user'), prevpath ) + + form = Form(request) + form.begin('', 'user.create') + form.add_input('login:', 'login', 'text') + form.add_input('password:', 'password', 'password', '') + form.add_input('retry password:', 'passwordretry', 'password', '') + form.add_input('name:', 'name', 'text') + form.add_submit() + form.end() + answer.content += form.content + return answer.complete_content() @@ -35,15 +39,14 @@ class UserPage(Page): raise exception.HttpNotFound() user = None - if path[0].isdecimal(): - user = request.model.users.get_by_id(int(path[0])) - else: - user = request.model.users.get_by_login(str(path[0])) + user = request.model.users.get_by_login(str(path[0])) if not user: raise exception.HttpNotFound() - request.answer.objects['user'] = user - request.answer.chain_title( request.answer.e(user.name) ) + answer = request.answer + + answer.objects['user'] = user + answer.add_uipath_entry( user.name, prevpath + [user.login] ) return self.profile.sub_process(request, path, prevpath) @@ -59,7 +62,6 @@ class UserProfilePage(Page): def process(self, request, path, prevpath): user = request.answer.objects['user'] answer = request.answer - answer.chain_title( answer.e(user.login) ) if path: if path[0] == 'edit': @@ -74,14 +76,11 @@ class UserProfilePage(Page): return self.repos.sub_process(request, path, prevpath) raise exception.HttpNotFound() - can_update = user.can_update() - - answer.content += '

' + answer.te('User profile') + '

\n' answer.content += '

' + answer.e(user.login) + '

\n' answer.content += '

' + answer.e(user.name) + '

\n' if user.superuser: answer.content += '

' + answer.te('Site admin') + '

\n' - if can_update: + if user.can_update(): answer.content += '

' + self.make_link(answer, prevpath + ['edit'], 'Edit user') + '

\n' answer.content += '

' + self.make_link(answer, prevpath + ['repos'], 'Repositories') + '

\n' @@ -99,41 +98,44 @@ class UserUpdatePage(Page): if not user.can_update(): raise exception.HttpNotFound() - answer.chain_title( answer.te('Edit user') ) - answer.content += '

' + answer.te('Edit user') + '

\n' - answer.content += '

' + answer.e(user.login) + '

\n' - answer.content += '
\n' - answer.content += '\n' - answer.content += '\n' - answer.content += '

' + answer.te('name:') + '

\n' - answer.content += '

\n' - answer.content += '
\n' + answer.add_uipath_entry( answer.t('Edit user'), prevpath ) + + form = Form(request) + form.begin('Profile', 'user.update') + form.add_hidden('user_id', user.id) + form.add_input('name:', 'name', 'name', user.name) + form.add_submit() + form.end() + answer.content += form.content - answer.content += '

' + answer.te('Change password') + '

\n' - answer.content += '
\n' - answer.content += '\n' - answer.content += '\n' + form = Form(request) + form.begin('Change password', 'user.setpassword') + form.add_hidden('user_id', user.id) if user.id == request.model.myrights.user_id: - answer.content += '

' + answer.te('old password:') + '

\n' - answer.content += '

' + answer.te('new password:') + '

\n' - answer.content += '

' + answer.te('new password retry:') + '

\n' - answer.content += '

\n' - answer.content += '
\n' + form.add_input('old password:', 'oldpassword', 'password', '') + form.add_input('new password:', 'newpassword', 'password', '') + form.add_input('new password retry:', 'newpasswordretry', 'password', '') + form.add_submit() + form.end() + answer.content += form.content if user.id != request.model.myrights.user_id and not user.superuser is None: - answer.content += '

' + answer.te('Global rights') + '

\n' - answer.content += '
\n' - answer.content += '\n' - answer.content += '\n' - answer.content += '

' + answer.te('site admin') + '

\n' - answer.content += '

\n' - answer.content += '
\n' + form = Form(request) + form.begin('Global rights', 'user.setsuperuser') + form.add_hidden('user_id', user.id) + form.add_checkbox('site admin:', 'superuser', user.superuser) + form.add_submit() + form.end() + answer.content += form.content if user.can_delete() and prevpath: - answer.content += '

' + answer.te('Deletion') + '

\n' - answer.content += '
\n' - answer.content += '

\n' - answer.content += '
\n' + url = request.get_urlpath_escaped(prevpath[:-1] + ['delete']) + form = Form(request) + form.content += '
' + form.GROUP_BEGIN + form.content += form.title('Deletion') + form.add_submit('Delete user') + form.end() + answer.content += form.content return answer.complete_content() @@ -148,18 +150,20 @@ class UserDeletePage(Page): if not user.can_delete(): raise exception.HttpNotFound() - answer.chain_title( answer.te('Delete user') ) - answer.content += '

' + answer.te('Do you really want do delete user?') + '

\n' - answer.content += '

' + answer.e(user.id) + '

\n' - answer.content += '

' + answer.e(user.login) + '

\n' - answer.content += '

' + answer.e(user.name) + '

\n' - answer.content += '\n' - answer.content += '\n' - answer.content += '\n' + answer.add_uipath_entry( answer.t('Delete user'), prevpath ) + + form = Form(request) + form.begin('', 'user.delete') + form.add_hidden('user_id', user.id) + form.content += '

' + answer.e(user.login) + '

\n' + form.content += '

' + answer.e(user.name) + '

\n' + form.content += '

' + answer.te('Do you really want do delete user?') + '

\n' if user.id == request.model.myrights.user_id: - answer.content += '

' + answer.te('password to delete your account:') + '

\n' - answer.content += '

\n' - answer.content += '
\n' + form.add_input('password to delete your account:', 'password', 'password', '') + form.add_submit('Confirm delete') + form.end() + answer.content += form.content + return answer.complete_content() @@ -175,12 +179,11 @@ class UserListPage(Page): users = request.model.users.get_list() answer = request.answer - answer.chain_title( answer.te('Users list') ) - answer.content += '

' + answer.te('Users list') + '

\n' + answer.add_uipath_entry( answer.t('Users list'), prevpath ) + for user in users: - url = request.get_urlpath_escaped(prevpath[:-1] + ['user', str(user.id)]) + url = request.get_urlpath_escaped(prevpath[:-1] + ['user', str(user.login)]) answer.content += '

' \ - + answer.e(user.id) + ' ' \ + answer.e(user.login) + ' ' \ + answer.e(user.name) + '

\n' diff --git a/request.py b/request.py index 30a2fb0..c300796 100644 --- a/request.py +++ b/request.py @@ -55,7 +55,7 @@ class Request: self.answer = answer.Answer(self) self.server.sessions.attach_session(self) - def read_posrvars(self): + def read_postvars(self): if self.method == 'POST': postvars = cgi.FieldStorage( fp = self.env["wsgi.input"], diff --git a/server.py b/server.py index 7ce5fc2..4b431e6 100644 --- a/server.py +++ b/server.py @@ -60,6 +60,8 @@ class Server: return { 'protocol' : str(config.get('protocol', 'https://')), 'domain' : str(config.get('domain', '')), + 'name' : str(config.get('name', 'Earthworm')), + 'debug' : bool(config.get('debug')), 'urlprefix' : urlprefix, 'urldataprefix' : str(config.get('urldataprefix', urlprefix + '/data')), diff --git a/template/common.py b/template/common.py index e52473e..12a86bd 100644 --- a/template/common.py +++ b/template/common.py @@ -13,10 +13,20 @@ class CommonTemplate(Template): self.errors = ErrorsTemplate() def wrap(self, answer): + titles = list() + uipath = list() + for i in answer.uipath: + title = answer.e(i[0]) + link = answer.request.get_urlpath_escaped(i[1]) + titles.insert(0, title) + uipath.append('%s' % (link, title)) + + title = titles[0] if titles else '' + return ''' - %(title)s + %(titlechain)s @@ -24,8 +34,14 @@ class CommonTemplate(Template): %(usermenu)s - %(errors)s +
+ %(errors)s +
+
+ %(uipath)s +
+

%(title)s

%(content)s
''' % { 'title' : answer.te('You logged in as:'), - 'profile' : answer.request.get_urlpath_escaped(['user', str(user.id)]), + 'profile' : answer.request.get_urlpath_escaped(['user', str(user.login)]), 'login' : answer.e(user.login if user else ''), 'name' : answer.e(user.name if user else ''), 'logout' : answer.te('Logout'),