Mercurial > public > src > rhodecode
changeset 404:10e8a95477a8 demo
Merge with 3171614c006793f325f03fe52da9057b509478c1
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Wed, 28 Jul 2010 02:29:08 +0200 |
parents | 0acccf6e2ab2 (current diff) 3171614c0067 (diff) |
children | b2a2f2ec08b8 |
files | pylons_app/controllers/admin/repos.py pylons_app/controllers/admin/users.py pylons_app/model/user_model.py |
diffstat | 15 files changed, 294 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/pylons_app/config/routing.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/config/routing.py Wed Jul 28 02:29:08 2010 +0200 @@ -4,6 +4,7 @@ may take precedent over the more generic routes. For more information refer to the routes manual at http://routes.groovie.org/docs/ """ +from __future__ import with_statement from routes import Mapper from pylons_app.lib.utils import check_repo_fast as cr @@ -31,7 +32,7 @@ repo_name = match_dict.get('repo_name') return not cr(repo_name, config['base_path']) - #REST routes + #REST REPO MAP with map.submapper(path_prefix='/_admin', controller='admin/repos') as m: m.connect("repos", "/repos", action="create", conditions=dict(method=["POST"])) @@ -69,7 +70,36 @@ map.resource('user', 'users', controller='admin/users', path_prefix='/_admin') map.resource('permission', 'permissions', controller='admin/permissions', path_prefix='/_admin') - map.resource('setting', 'settings', controller='admin/settings', path_prefix='/_admin', name_prefix='admin_') + + #map.resource('setting', 'settings', controller='admin/settings', path_prefix='/_admin', name_prefix='admin_') + #REST SETTINGS MAP + with map.submapper(path_prefix='/_admin', controller='admin/settings') as m: + m.connect("admin_settings", "/settings", + action="create", conditions=dict(method=["POST"])) + m.connect("admin_settings", "/settings", + action="index", conditions=dict(method=["GET"])) + m.connect("admin_formatted_settings", "/settings.{format}", + action="index", conditions=dict(method=["GET"])) + m.connect("admin_new_setting", "/settings/new", + action="new", conditions=dict(method=["GET"])) + m.connect("admin_formatted_new_setting", "/settings/new.{format}", + action="new", conditions=dict(method=["GET"])) + m.connect("/settings/{setting_id}", + action="update", conditions=dict(method=["PUT"])) + m.connect("/settings/{setting_id}", + action="delete", conditions=dict(method=["DELETE"])) + m.connect("admin_edit_setting", "/settings/{setting_id}/edit", + action="edit", conditions=dict(method=["GET"])) + m.connect("admin_formatted_edit_setting", "/settings/{setting_id}.{format}/edit", + action="edit", conditions=dict(method=["GET"])) + m.connect("admin_setting", "/settings/{setting_id}", + action="show", conditions=dict(method=["GET"])) + m.connect("admin_formatted_setting", "/settings/{setting_id}.{format}", + action="show", conditions=dict(method=["GET"])) + m.connect("admin_settings_my_account", "/my_account", + action="my_account", conditions=dict(method=["GET"])) + m.connect("admin_settings_my_account_update", "/my_account_update", + action="my_account_update", conditions=dict(method=["PUT"])) #ADMIN with map.submapper(path_prefix='/_admin', controller='admin/admin') as m:
--- a/pylons_app/controllers/admin/repos.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/controllers/admin/repos.py Wed Jul 28 02:29:08 2010 +0200 @@ -2,6 +2,7 @@ # encoding: utf-8 # repos controller for pylons # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com> +# # 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; version 2
--- a/pylons_app/controllers/admin/settings.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/controllers/admin/settings.py Wed Jul 28 02:29:08 2010 +0200 @@ -52,12 +52,13 @@ @LoginRequired() - #@HasPermissionAllDecorator('hg.admin') def __before__(self): c.admin_user = session.get('admin_user') c.admin_username = session.get('admin_username') super(SettingsController, self).__before__() - + + + @HasPermissionAllDecorator('hg.admin') def index(self, format='html'): """GET /admin/settings: All items in the collection""" # url('admin_settings') @@ -71,23 +72,26 @@ force_defaults=False ) + @HasPermissionAllDecorator('hg.admin') def create(self): """POST /admin/settings: Create a new item""" # url('admin_settings') - + + @HasPermissionAllDecorator('hg.admin') def new(self, format='html'): """GET /admin/settings/new: Form to create a new item""" # url('admin_new_setting') - - def update(self, id): - """PUT /admin/settings/id: Update an existing item""" + + @HasPermissionAllDecorator('hg.admin') + def update(self, setting_id): + """PUT /admin/settings/setting_id: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: - # h.form(url('admin_setting', id=ID), + # h.form(url('admin_setting', setting_id=ID), # method='put') - # url('admin_setting', id=ID) - if id == 'mapping': + # url('admin_setting', setting_id=ID) + if setting_id == 'mapping': rm_obsolete = request.POST.get('destroy', False) log.debug('Rescanning directories with destroy=%s', rm_obsolete) @@ -96,7 +100,7 @@ invalidate_cache('cached_repo_list') h.flash(_('Repositories sucessfully rescanned'), category='success') - if id == 'global': + if setting_id == 'global': application_form = ApplicationSettingsForm()() try: @@ -132,20 +136,77 @@ encoding="UTF-8") return redirect(url('admin_settings')) - - def delete(self, id): - """DELETE /admin/settings/id: Delete an existing item""" + + @HasPermissionAllDecorator('hg.admin') + def delete(self, setting_id): + """DELETE /admin/settings/setting_id: Delete an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="DELETE" /> # Or using helpers: - # h.form(url('admin_setting', id=ID), + # h.form(url('admin_setting', setting_id=ID), # method='delete') - # url('admin_setting', id=ID) + # url('admin_setting', setting_id=ID) + + @HasPermissionAllDecorator('hg.admin') + def show(self, setting_id, format='html'): + """GET /admin/settings/setting_id: Show a specific item""" + # url('admin_setting', setting_id=ID) + + @HasPermissionAllDecorator('hg.admin') + def edit(self, setting_id, format='html'): + """GET /admin/settings/setting_id/edit: Form to edit an existing item""" + # url('admin_edit_setting', setting_id=ID) + + + def my_account(self): + """ + GET /_admin/my_account Displays info about my account + """ + # url('admin_settings_my_account') + c.user = self.sa.query(User).get(c.hg_app_user.user_id) + if c.user.username == 'default': + h.flash(_("You can't edit this user since it's" + " crucial for entire application"), category='warning') + return redirect(url('users')) + + defaults = c.user.__dict__ + return htmlfill.render( + render('admin/users/user_edit_my_account.html'), + defaults=defaults, + encoding="UTF-8", + force_defaults=False + ) - def show(self, id, format='html'): - """GET /admin/settings/id: Show a specific item""" - # url('admin_setting', id=ID) + def my_account_update(self): + """PUT /_admin/my_account_update: Update an existing item""" + # Forms posted to this method should contain a hidden field: + # <input type="hidden" name="_method" value="PUT" /> + # Or using helpers: + # h.form(url('admin_settings_my_account_update'), + # method='put') + # url('admin_settings_my_account_update', id=ID) + user_model = UserModel() + uid = c.hg_app_user.user_id + _form = UserForm(edit=True, old_data={'user_id':uid})() + form_result = {} + try: + form_result = _form.to_python(dict(request.POST)) + user_model.update_my_account(uid, form_result) + h.flash(_('Your account was updated succesfully'), category='success') + + except formencode.Invalid as errors: + #c.user = self.sa.query(User).get(c.hg_app_user.user_id) + return htmlfill.render( + render('admin/users/user_edit_my_account.html'), + defaults=errors.value, + errors=errors.error_dict or {}, + prefix_error=False, + encoding="UTF-8") + except Exception: + log.error(traceback.format_exc()) + h.flash(_('error occured during update of user %s') \ + % form_result.get('username'), category='error') + + return redirect(url('my_account')) + - def edit(self, id, format='html'): - """GET /admin/settings/id/edit: Form to edit an existing item""" - # url('admin_edit_setting', id=ID)
--- a/pylons_app/controllers/admin/users.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/controllers/admin/users.py Wed Jul 28 02:29:08 2010 +0200 @@ -17,6 +17,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. +""" +Created on April 4, 2010 +users controller for pylons +@author: marcink +""" + from formencode import htmlfill from pylons import request, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect @@ -30,11 +36,7 @@ import formencode import logging import traceback -""" -Created on April 4, 2010 -users controller for pylons -@author: marcink -""" + log = logging.getLogger(__name__)
--- a/pylons_app/lib/auth.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/lib/auth.py Wed Jul 28 02:29:08 2010 +0200 @@ -104,7 +104,23 @@ def set_base_path(config): config['base_path'] = config['pylons.app_globals'].base_path - + +def fill_data(user): + """ + Fills user data with those from database + @param user: + """ + sa = meta.Session + dbuser = sa.query(User).get(user.user_id) + + user.username = dbuser.username + user.is_admin = dbuser.admin + user.name = dbuser.name + user.lastname = dbuser.lastname + + meta.Session.remove() + return user + def fill_perms(user): """ Fills user permission attribute with permissions taken from database @@ -113,6 +129,7 @@ sa = meta.Session user.permissions['repositories'] = {} + user.permissions['global'] = set() #first fetch default permissions default_perms = sa.query(Repo2Perm, Repository, Permission)\ @@ -122,14 +139,14 @@ 'default').one().user_id).all() if user.is_admin: - user.permissions['global'] = set(['hg.admin']) + user.permissions['global'].add('hg.admin') #admin have all rights full for perm in default_perms: p = 'repository.admin' user.permissions['repositories'][perm.Repo2Perm.repository.repo_name] = p else: - user.permissions['global'] = set() + user.permissions['global'].add('') for perm in default_perms: if perm.Repository.private: #disable defaults for private repos, @@ -164,8 +181,8 @@ @param session: """ user = session.get('hg_app_user', AuthUser()) - if user.is_authenticated: + user = fill_data(user) user = fill_perms(user) session['hg_app_user'] = user session.save()
--- a/pylons_app/lib/base.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/lib/base.py Wed Jul 28 02:29:08 2010 +0200 @@ -5,11 +5,12 @@ from pylons import config, tmpl_context as c, request, session from pylons.controllers import WSGIController from pylons.templating import render_mako as render +from pylons_app import __version__ from pylons_app.lib import auth from pylons_app.lib.utils import get_repo_slug from pylons_app.model import meta -from pylons_app.model.hg_model import _get_repos_cached -from pylons_app import __version__ +from pylons_app.model.hg_model import _get_repos_cached, \ + _get_repos_switcher_cached class BaseController(WSGIController): @@ -18,6 +19,7 @@ c.hg_app_name = config['hg_app_name'] c.repo_name = get_repo_slug(request) c.cached_repo_list = _get_repos_cached() + c.repo_switcher_list = _get_repos_switcher_cached(c.cached_repo_list) self.sa = meta.Session def __call__(self, environ, start_response):
--- a/pylons_app/lib/db_manage.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/lib/db_manage.py Wed Jul 28 02:29:08 2010 +0200 @@ -177,8 +177,9 @@ ('repository.read', 'Repository read access'), ('repository.write', 'Repository write access'), ('repository.admin', 'Repository admin access'), + ('repository.create', 'Repository create'), ('hg.admin', 'Hg Administrator'), - ] + ] for p in perms: new_perm = Permission()
--- a/pylons_app/model/hg_model.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/model/hg_model.py Wed Jul 28 02:29:08 2010 +0200 @@ -2,7 +2,7 @@ # encoding: utf-8 # Model for hg app # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com> - +# # 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; version 2 @@ -25,10 +25,12 @@ from beaker.cache import cache_region from mercurial import ui from mercurial.hgweb.hgwebdir_mod import findrepos -from vcs.exceptions import RepositoryError, VCSError +from pylons.i18n.translation import _ +from pylons_app.lib.auth import HasRepoPermissionAny from pylons_app.model import meta from pylons_app.model.db import Repository from sqlalchemy.orm import joinedload +from vcs.exceptions import RepositoryError, VCSError import logging import os import sys @@ -56,6 +58,15 @@ from pylons import app_globals as g return HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui) +@cache_region('super_short_term', 'cached_repos_switcher_list') +def _get_repos_switcher_cached(cached_repo_list): + repos_lst = [] + for repo in sorted(x.name.lower() for x in cached_repo_list.values()): + if HasRepoPermissionAny('repository.write', 'repository.read', 'repository.admin')(repo, 'main page check'): + repos_lst.append(repo) + + return repos_lst + @cache_region('long_term', 'full_changelog') def _full_changelog_cached(repo_name): log.info('getting full changelog for %s', repo_name)
--- a/pylons_app/model/user_model.py Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/model/user_model.py Wed Jul 28 02:29:08 2010 +0200 @@ -68,9 +68,9 @@ self.sa.rollback() raise - def update(self, id, form_data): + def update(self, uid, form_data): try: - new_user = self.sa.query(User).get(id) + new_user = self.sa.query(User).get(uid) if new_user.username == 'default': raise DefaultUserException( _("You can't Edit this user since it's" @@ -89,7 +89,28 @@ log.error(e) self.sa.rollback() raise - + + def update_my_account(self, uid, form_data): + try: + new_user = self.sa.query(User).get(uid) + if new_user.username == 'default': + raise DefaultUserException( + _("You can't Edit this user since it's" + " crucial for entire application")) + for k, v in form_data.items(): + if k == 'new_password' and v != '': + new_user.password = v + else: + if k not in ['admin', 'active']: + setattr(new_user, k, v) + + self.sa.add(new_user) + self.sa.commit() + except Exception as e: + log.error(e) + self.sa.rollback() + raise + def delete(self, id): try:
--- a/pylons_app/public/css/style.css Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/public/css/style.css Wed Jul 28 02:29:08 2010 +0200 @@ -3197,6 +3197,15 @@ } /* ----------------------------------------------------------- + REPO SWITCHER +----------------------------------------------------------- */ + +#switch_repos{ + position: absolute; + height: 25px; + z-index: 1; +} +/* ----------------------------------------------------------- BREADCRUMBS ----------------------------------------------------------- */
--- a/pylons_app/templates/admin/settings/settings.html Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/templates/admin/settings/settings.html Wed Jul 28 02:29:08 2010 +0200 @@ -23,7 +23,7 @@ </div> <!-- end box / title --> - ${h.form(url('admin_setting', id='mapping'),method='put')} + ${h.form(url('admin_setting', setting_id='mapping'),method='put')} <div class="form"> <!-- fields --> <h3>${_('Remap and rescan repositories')}</h3> @@ -49,7 +49,7 @@ </div> ${h.end_form()} - ${h.form(url('admin_setting', id='global'),method='put')} + ${h.form(url('admin_setting', setting_id='global'),method='put')} <div class="form"> <!-- fields --> <h3>${_('Global application settings')}</h3>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pylons_app/templates/admin/users/user_edit_my_account.html Wed Jul 28 02:29:08 2010 +0200 @@ -0,0 +1,79 @@ +## -*- coding: utf-8 -*- +<%inherit file="/base/base.html"/> + +<%def name="title()"> + ${_('User administration')} +</%def> + +<%def name="breadcrumbs_links()"> + ${_('My Account')} +</%def> + +<%def name="page_nav()"> + ${self.menu('admin')} +</%def> + +<%def name="main()"> +<div class="box"> + <!-- box / title --> + <div class="title"> + ${self.breadcrumbs()} + </div> + <!-- end box / title --> + ${h.form(url('admin_settings_my_account_update'),method='put')} + <div class="form"> + <!-- fields --> + <div class="fields"> + <div class="field"> + <div class="label"> + <label for="username">${_('Username')}:</label> + </div> + <div class="input"> + ${h.text('username')} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="new_password">${_('New password')}:</label> + </div> + <div class="input"> + ${h.password('new_password')} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="name">${_('Name')}:</label> + </div> + <div class="input"> + ${h.text('name')} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="lastname">${_('Lastname')}:</label> + </div> + <div class="input"> + ${h.text('lastname')} + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="email">${_('Email')}:</label> + </div> + <div class="input"> + ${h.text('email')} + </div> + </div> + + <div class="buttons"> + ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")} + </div> + </div> + </div> + ${h.end_form()} +</div> +</%def> \ No newline at end of file
--- a/pylons_app/templates/base/base.html Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/templates/base/base.html Wed Jul 28 02:29:08 2010 +0200 @@ -17,7 +17,7 @@ <!-- user --> <ul id="logged-user"> <li class="first"> - ${h.link_to('%s %s (%s)'%(c.hg_app_user.name,c.hg_app_user.lastname,c.hg_app_user.username),h.url('edit_user', id=c.hg_app_user.user_id))} + ${h.link_to('%s %s (%s)'%(c.hg_app_user.name,c.hg_app_user.lastname,c.hg_app_user.username),h.url('admin_settings_my_account'))} </li> <li class="last highlight">${h.link_to(u'Logout',h.url('logout_home'))}</li> </ul> @@ -91,15 +91,13 @@ } else{ YAHOO.util.Dom.setStyle('switch_repos','display',''); - //YAHOO.util.Dom.setStyle('repo_switcher','background','#FFFFFF'); - //YAHOO.util.Dom.setStyle('repo_switcher','color','#556CB5'); YAHOO.util.Dom.addClass('repo_switcher','selected'); } }); YAHOO.util.Event.addListener('repos_list','change',function(e){ var wa = YAHOO.util.Dom.get('repos_list').value; - var url = "${h.url('summary_home',repo_name='__REPLACE__')}".replace('__REPLACE__',wa); + var url = "${h.url('summary_home',repo_name='__REPO__')}".replace('__REPO__',wa); window.location = url; }) }); @@ -115,9 +113,9 @@ </span> <span>↓</span> </a> - <div id="switch_repos" style="display:none;position: absolute;height: 25px;z-index: 1"> - <select id="repos_list" size="=10" style="min-width: 150px"> - %for repo in sorted(x.name.lower() for x in c.cached_repo_list.values()): + <div id="switch_repos" style="display:none;"> + <select id="repos_list" size="10"> + %for repo in c.repo_switcher_list: <option value="${repo}">${repo}</option> %endfor </select>
--- a/pylons_app/templates/index.html Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/templates/index.html Wed Jul 28 02:29:08 2010 +0200 @@ -27,6 +27,13 @@ <!-- box / title --> <div class="title"> <h5>${_('Dashboard')}</h5> + ##%if h.HasPermissionAll('repository.create')(): + <ul class="links"> + <li> + <span>${h.link_to(u'ADD NEW REPO',h.url('new_repo'),class_="add_icon")}</span> + </li> + </ul> + ##%endif </div> <!-- end box / title --> <div class="table"> @@ -44,7 +51,7 @@ </thead> <tbody> %for cnt,repo in enumerate(c.repos_list): - %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(repo['name'],'main page check'): + %if repo['name'] in c.repo_switcher_list: <tr class="parity${cnt%2}"> <td> %if repo['repo'].dbrepo.private:
--- a/pylons_app/templates/summary/summary.html Tue Jul 27 15:57:48 2010 +0200 +++ b/pylons_app/templates/summary/summary.html Wed Jul 28 02:29:08 2010 +0200 @@ -217,7 +217,11 @@ var d = new Date(x*1000); var fd = d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate(); var nr_commits = parseInt(y); - showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd + ": " + nr_commits+" commits"); + var suffix = ''; + if(nr_commits > 1){ + var suffix = 's'; + } + showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd + ": " + nr_commits+" commit" + suffix); } } else {