Changeset - d303aacb3349
[Not reviewed]
default
0 10 0
Marcin Kuzminski - 15 years ago 2010-06-28 13:54:47
marcin@python-works.com
repos crud controllers - change id into repo_name for compatability, added ajax repo perm user function variuos html fixes, permissions forms and managment fixes.
Added permission fetching for each request in AuthUser instance
10 files changed with 113 insertions and 52 deletions:
0 comments (0 inline, 0 general)
pylons_app/config/routing.py
Show inline comments
 
@@ -14,60 +14,63 @@ def make_map(config):
 
    map.explicit = False
 

	
 
    # The ErrorController route (handles 404/500 error pages); it should
 
    # likely stay at the top, ensuring it can always be resolved
 
    map.connect('/error/{action}', controller='error')
 
    map.connect('/error/{action}/{id}', controller='error')
 

	
 
    # CUSTOM ROUTES HERE
 
    map.connect('hg_home', '/', controller='hg', action='index')
 
    
 
    
 
    #REST routes
 
    with map.submapper(path_prefix='/_admin', controller='repos') as m:
 
        m.connect("repos", "/repos",
 
             action="create", conditions=dict(method=["POST"]))
 
        m.connect("repos", "/repos",
 
             action="index", conditions=dict(method=["GET"]))
 
        m.connect("formatted_repos", "/repos.{format}",
 
             action="index",
 
            conditions=dict(method=["GET"]))
 
        m.connect("new_repo", "/repos/new",
 
             action="new", conditions=dict(method=["GET"]))
 
        m.connect("formatted_new_repo", "/repos/new.{format}",
 
             action="new", conditions=dict(method=["GET"]))
 
        m.connect("/repos/{id:.*}",
 
        m.connect("/repos/{repo_name:.*}",
 
             action="update", conditions=dict(method=["PUT"]))
 
        m.connect("/repos/{id:.*}",
 
        m.connect("/repos/{repo_name:.*}",
 
             action="delete", conditions=dict(method=["DELETE"]))
 
        m.connect("edit_repo", "/repos/{id:.*}/edit",
 
        m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
 
             action="edit", conditions=dict(method=["GET"]))
 
        m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
 
             action="edit", conditions=dict(method=["GET"]))
 
        m.connect("formatted_edit_repo", "/repos/{id:.*}.{format}/edit",
 
             action="edit", conditions=dict(method=["GET"]))
 
        m.connect("repo", "/repos/{id:.*}",
 
        m.connect("repo", "/repos/{repo_name:.*}",
 
             action="show", conditions=dict(method=["GET"]))
 
        m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
 
             action="show", conditions=dict(method=["GET"]))
 
        m.connect("formatted_repo", "/repos/{id:.*}.{format}",
 
             action="show", conditions=dict(method=["GET"]))
 
        #ajax delete repo perm user
 
        m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
 
             action="delete_perm_user", conditions=dict(method=["DELETE"]))
 

	
 
    map.resource('user', 'users', path_prefix='/_admin')
 
    map.resource('permission', 'permissions', path_prefix='/_admin')
 
    
 
    #ADMIN
 
    with map.submapper(path_prefix='/_admin', controller='admin') as m:
 
        m.connect('admin_home', '/', action='index')#main page
 
        m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
 
                  action='add_repo')
 
    
 
    #FEEDS
 
    map.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
 
                controller='feed', action='rss')
 
    map.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
 
                controller='feed', action='atom')
 
    
 
    map.connect('login_home', '/login', controller='login')
 
    map.connect('logout_home', '/logout', controller='login', action='logout')
 
    
 
    map.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
 
                controller='changeset', revision='tip')
 
    map.connect('summary_home', '/{repo_name:.*}/summary',
 
                controller='summary')
 
    map.connect('shortlog_home', '/{repo_name:.*}/shortlog',
pylons_app/controllers/repos.py
Show inline comments
 
@@ -13,54 +13,51 @@
 
# 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, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 
"""
 
Created on April 7, 2010
 
admin controller for pylons
 
@author: marcink
 
"""
 
from operator import itemgetter
 
from pylons import request, response, session, tmpl_context as c, url, \
 
    app_globals as g
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 
from pylons_app.lib import helpers as h
 
from pylons_app.lib.auth import LoginRequired
 
from pylons_app.lib.base import BaseController, render
 
from pylons_app.lib.utils import invalidate_cache
 
from pylons_app.model.repo_model import RepoModel
 
from pylons_app.model.hg_model import HgModel
 
from pylons_app.model.forms import RepoForm
 
from pylons_app.model.meta import Session
 
from datetime import datetime
 
import formencode
 
from formencode import htmlfill
 
import logging
 
import os
 
import shutil
 
log = logging.getLogger(__name__)
 

	
 
class ReposController(BaseController):
 
    """REST Controller styled on the Atom Publishing Protocol"""
 
    # To properly map this controller, ensure your config/routing.py
 
    # file has a resource setup:
 
    #     map.resource('repo', 'repos')
 
    @LoginRequired()
 
    def __before__(self):
 
        c.admin_user = session.get('admin_user')
 
        c.admin_username = session.get('admin_username')
 
        super(ReposController, self).__before__()
 
                
 
    def index(self, format='html'):
 
        """GET /repos: All items in the collection"""
 
        # url('repos')
 
        cached_repo_list = HgModel().get_repos()
 
        c.repos_list = sorted(cached_repo_list, key=itemgetter('name_sort'))
 
        return render('admin/repos/repos.html')
 
    
 
    def create(self):
 
        """POST /repos: Create a new item"""
 
        # url('repos')
 
        repo_model = RepoModel()
 
@@ -72,113 +69,126 @@ class ReposController(BaseController):
 
            h.flash(_('created repository %s') % form_result['repo_name'],
 
                    category='success')
 
                                                             
 
        except formencode.Invalid as errors:
 
            c.form_errors = errors.error_dict
 
            c.new_repo = errors.value['repo_name']
 
            return htmlfill.render(
 
                 render('admin/repos/repo_add.html'),
 
                defaults=errors.value,
 
                encoding="UTF-8")        
 

	
 
        except Exception:
 
            h.flash(_('error occured during creation of repository %s') \
 
                    % form_result['repo_name'], category='error')
 
            
 
        return redirect('repos')
 

	
 
    def new(self, format='html'):
 
        """GET /repos/new: Form to create a new item"""
 
        new_repo = request.GET.get('repo', '')
 
        c.new_repo = h.repo_name_slug(new_repo)
 

	
 
        return render('admin/repos/repo_add.html')
 

	
 
    def update(self, id):
 
        """PUT /repos/id: Update an existing item"""
 
    def update(self, repo_name):
 
        """PUT /repos/repo_name: 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('repo', id=ID),
 
        #    h.form(url('repo', repo_name=ID),
 
        #           method='put')
 
        # url('repo', id=ID)
 
        # url('repo', repo_name=ID)
 
        repo_model = RepoModel()
 
        _form = RepoForm(edit=True)()
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            repo_model.update(id, form_result)
 
            repo_model.update(repo_name, form_result)
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('Repository %s updated succesfully' % id), category='success')
 
            h.flash(_('Repository %s updated succesfully' % repo_name), category='success')
 
                           
 
        except formencode.Invalid as errors:
 
            c.repo_info = repo_model.get(id)
 
            c.repo_info = repo_model.get(repo_name)
 
            c.users_array = repo_model.get_users_js()
 
            errors.value.update({'user':c.repo_info.user.username})
 
            c.form_errors = errors.error_dict
 
            return htmlfill.render(
 
                 render('admin/repos/repo_edit.html'),
 
                defaults=errors.value,
 
                encoding="UTF-8")
 
        except Exception:
 
            h.flash(_('error occured during update of repository %s') \
 
                    % form_result['repo_name'], category='error')
 
        return redirect(url('repos'))
 
    
 
    def delete(self, id):
 
        """DELETE /repos/id: Delete an existing item"""
 
    def delete(self, repo_name):
 
        """DELETE /repos/repo_name: 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('repo', id=ID),
 
        #    h.form(url('repo', repo_name=ID),
 
        #           method='delete')
 
        # url('repo', id=ID)
 
        # url('repo', repo_name=ID)
 
        
 
        repo_model = RepoModel()
 
        repo = repo_model.get(id)
 
        repo = repo_model.get(repo_name)
 
        if not repo:
 
            h.flash(_('%s repository is not mapped to db perhaps' 
 
                      ' it was moved or renamed  from the filesystem'
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % id, category='error')
 
                      ' in order to rescan repositories') % repo_name, category='error')
 
        
 
            return redirect(url('repos'))
 
        try:
 
            repo_model.delete(repo)            
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('deleted repository %s') % id, category='success')
 
            h.flash(_('deleted repository %s') % repo_name, category='success')
 
        except Exception:
 
            h.flash(_('An error occured during deletion of %s') % id,
 
            h.flash(_('An error occured during deletion of %s') % repo_name,
 
                    category='error')
 
        
 
        return redirect(url('repos'))
 
        
 
    def show(self, id, format='html'):
 
        """GET /repos/id: Show a specific item"""
 
        # url('repo', id=ID)
 
    def delete_perm_user(self, repo_name):
 
        """
 
        DELETE an existing repository permission user
 
        @param repo_name:
 
        """
 
        
 
    def edit(self, id, format='html'):
 
        """GET /repos/id/edit: Form to edit an existing item"""
 
        # url('edit_repo', id=ID)
 
        try:
 
        repo_model = RepoModel()
 
        c.repo_info = repo = repo_model.get(id)
 
            repo_model.delete_perm_user(request.POST, repo_name)            
 
        except Exception as e:
 
            h.flash(_('An error occured during deletion of repository user'),
 
                    category='error')
 
        
 
        
 
    def show(self, repo_name, format='html'):
 
        """GET /repos/repo_name: Show a specific item"""
 
        # url('repo', repo_name=ID)
 
        
 
    def edit(self, repo_name, format='html'):
 
        """GET /repos/repo_name/edit: Form to edit an existing item"""
 
        # url('edit_repo', repo_name=ID)
 
        repo_model = RepoModel()
 
        c.repo_info = repo = repo_model.get(repo_name)
 
        if not repo:
 
            h.flash(_('%s repository is not mapped to db perhaps' 
 
                      ' it was created or renamed from the filesystem'
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % id, category='error')
 
                      ' in order to rescan repositories') % repo_name, category='error')
 
        
 
            return redirect(url('repos'))        
 
        defaults = c.repo_info.__dict__
 
        defaults.update({'user':c.repo_info.user.username})
 
        
 
        c.users_array = repo_model.get_users_js()
 
        
 
        for p in c.repo_info.repo2perm:
 
            defaults.update({'perm_%s' % p.user.username: 
 
                             p.permission.permission_name})
 
                
 
        return htmlfill.render(
 
            render('admin/repos/repo_edit.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )          
pylons_app/lib/auth.py
Show inline comments
 
@@ -6,49 +6,49 @@
 
# 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
 
# of the License or (at your opinion) any later version of the license.
 
# 
 
# 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, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 
"""
 
Created on April 4, 2010
 

	
 
@author: marcink
 
"""
 

	
 
from functools import wraps
 
from pylons import session, url, app_globals as g
 
from pylons.controllers.util import abort, redirect
 
from pylons_app.model import meta
 
from pylons_app.model.db import User
 
from pylons_app.model.db import User, Repo2Perm
 
from sqlalchemy.exc import OperationalError
 
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
 
import crypt
 
import logging
 
log = logging.getLogger(__name__)
 

	
 
def get_crypt_password(password):
 
    """
 
    Cryptographic function used for password hashing
 
    @param password: password to hash
 
    """
 
    return crypt.crypt(password, '6a')
 

	
 
def authfunc(environ, username, password):
 
    sa = meta.Session
 
    password_crypt = get_crypt_password(password)
 
    try:
 
        user = sa.query(User).filter(User.username == username).one()
 
    except (NoResultFound, MultipleResultsFound, OperationalError) as e:
 
        log.error(e)
 
        user = None
 
        
 
    if user:
 
        if user.active:
 
@@ -70,49 +70,60 @@ class  AuthUser(object):
 
    is_admin = False
 
    permissions = set()
 
    group = set()
 
    
 
    def __init__(self):
 
        pass
 

	
 

	
 

	
 
def set_available_permissions(config):
 
    """
 
    This function will propagate pylons globals with all available defined
 
    permission given in db. We don't wannt to check each time from db for new 
 
    permissions since adding a new permission also requires application restart
 
    ie. to decorate new views with the newly created permission
 
    @param config:
 
    """
 
    from pylons_app.model.meta import Session
 
    from pylons_app.model.db import Permission
 
    logging.info('getting information about all available permissions')
 
    sa = Session()
 
    all_perms = sa.query(Permission).all()
 
    config['pylons.app_globals'].available_permissions = [x.permission_name for x in all_perms]
 

	
 
def get_user(session):
 
    """
 
    Gets user from session, and wraps permissions into user
 
    @param session:
 
    """
 
    user = session.get('hg_app_user', AuthUser())
 
    if user.is_authenticated:
 
        sa = meta.Session
 
        user.permissions = sa.query(Repo2Perm)\
 
        .filter(Repo2Perm.user_id == user.user_id).all()
 

	
 
    return user
 
        
 
#===============================================================================
 
# DECORATORS
 
#===============================================================================
 
class LoginRequired(object):
 
    """
 
    Must be logged in to execute this function else redirect to login page
 
    """
 
    def __init__(self):
 
        pass
 
    
 
    def __call__(self, func):
 
        
 
        @wraps(func)
 
        def _wrapper(*fargs, **fkwargs):
 
            user = session.get('hg_app_user', AuthUser())
 
            log.info('Checking login required for user:%s', user.username)            
 
            if user.is_authenticated:
 
                    log.info('user %s is authenticated', user.username)
 
                    func(*fargs)
 
            else:
 
                logging.info('user %s not authenticated', user.username)
 
                logging.info('redirecting to login page')
 
                return redirect(url('login_home'))
pylons_app/lib/base.py
Show inline comments
 
"""The base Controller API
 

	
 
Provides the BaseController class for subclassing.
 
"""
 
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.lib.auth import LoginRequired, AuthUser
 
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__
 

	
 
class BaseController(WSGIController):
 
    
 
    def __before__(self):
 
        c.hg_app_version = __version__
 
        c.repos_prefix = config['hg_app_name']
 
        c.repo_name = get_repo_slug(request)
 
        c.hg_app_user = session.get('hg_app_user', AuthUser())
 
        c.hg_app_user = auth.get_user(session)
 
        c.cached_repo_list = _get_repos_cached()
 
        self.sa = meta.Session
 
    
 
    def __call__(self, environ, start_response):
 
        """Invoke the Controller"""
 
        # WSGIController.__call__ dispatches to the Controller method
 
        # the request is routed to. This routing information is
 
        # available in environ['pylons.routes_dict']
 
        try:
 
            return WSGIController.__call__(self, environ, start_response)
 
        finally:
 
            meta.Session.remove()
pylons_app/model/forms.py
Show inline comments
 
@@ -134,60 +134,62 @@ class ValidRepoUser(formencode.validator
 
        return self.user_db.user_id
 

	
 
def ValidRepoName(edit=False):    
 
    class _ValidRepoName(formencode.validators.FancyValidator):
 
            
 
        def to_python(self, value, state):
 
            slug = h.repo_name_slug(value)
 
            
 
            sa = meta.Session
 
            if sa.query(Repository).get(slug) and not edit:
 
                raise formencode.Invalid(_('This repository already exists'),
 
                                         value, state)
 
                        
 
            return slug 
 
    return _ValidRepoName
 

	
 
class ValidPerms(formencode.validators.FancyValidator):
 
    messages = {'perm_new_user_name':_('This username is not valid')}
 
    
 
    def to_python(self, value, state):
 
        perms_update = []
 
        perms_new = []
 
        #build a list of permission to update and new permission to create
 
        for k, v in value.items():
 
            print k, v
 
            if k.startswith('perm_'):
 
                if  k.startswith('perm_new_user'):
 
                    new_perm = value.get('perm_new_user', False)
 
                    new_user = value.get('perm_new_user_name', False)
 
                    if new_user and new_perm:
 
                        if (new_user, new_perm) not in perms_new:
 
                            perms_new.append((new_user, new_perm))
 
                else:
 
                    perms_update.append((k[5:], v))
 
                #clear from form list
 
                #del value[k]
 
                    usr = k[5:]                    
 
                    if usr == 'default':
 
                        if value['private']:
 
                            #set none for default when updating to private repo
 
                            v = 'repository.none'
 
                    perms_update.append((usr, v))
 
        value['perms_updates'] = perms_update
 
        value['perms_new'] = perms_new
 
        sa = meta.Session
 
        for k, v in perms_new:
 
            try:
 
                self.user_db = sa.query(User).filter(User.username == k).one()
 
            except Exception:
 
                msg = self.message('perm_new_user_name',
 
                                     state=State_obj)
 
                raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})            
 
        return value
 
                
 
#===============================================================================
 
# FORMS        
 
#===============================================================================
 
class LoginForm(formencode.Schema):
 
    allow_extra_fields = True
 
    filter_extra_fields = True
 
    username = UnicodeString(
 
                             strip=True,
 
                             min=3,
 
                             not_empty=True,
 
                             messages={
 
                                       'empty':_('Please enter a login'),
pylons_app/model/repo_model.py
Show inline comments
 
@@ -83,72 +83,83 @@ class RepoModel(object):
 
                r2p.permission_id = self.sa.query(Permission).filter(
 
                                                Permission.permission_name == 
 
                                                perm).one().permission_id
 
                self.sa.add(r2p)
 
                                    
 
            self.sa.add(cur_repo)
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise    
 
    
 
    def create(self, form_data, cur_user, just_db=False):
 
        try:
 
            repo_name = form_data['repo_name']
 
            new_repo = Repository()
 
            for k, v in form_data.items():
 
                setattr(new_repo, k, v)
 
                
 
            new_repo.user_id = cur_user.user_id
 
            self.sa.add(new_repo)
 

	
 
            #create default permission
 
            repo2perm = Repo2Perm()
 
            default_perm = 'repository.none' if form_data['private'] \
 
                                                        else 'repository.read'
 
            repo2perm.permission_id = self.sa.query(Permission)\
 
                    .filter(Permission.permission_name == 'repository.read')\
 
                    .filter(Permission.permission_name == default_perm)\
 
                    .one().permission_id
 
                        
 
            repo2perm.repository = repo_name
 
            repo2perm.user_id = self.sa.query(User)\
 
                    .filter(User.username == 'default').one().user_id 
 
            
 
            self.sa.add(repo2perm)
 
            self.sa.commit()
 
            if not just_db:
 
                self.__create_repo(repo_name)
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise    
 
                     
 
    def delete(self, repo):
 
        try:
 
            self.sa.delete(repo)
 
            self.sa.commit()
 
            self.__delete_repo(repo.repo_name)
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 
    def delete_perm_user(self, form_data, repo_name):
 
        try:
 
            r2p = self.sa.query(Repo2Perm).filter(Repo2Perm.repository == repo_name)\
 
            .filter(Repo2Perm.user_id == form_data['user_id']).delete()
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 
       
 
    def __create_repo(self, repo_name):        
 
        repo_path = os.path.join(g.base_path, repo_name)
 
        if check_repo(repo_name, g.base_path):
 
            log.info('creating repo %s in %s', repo_name, repo_path)
 
            from vcs.backends.hg import MercurialRepository
 
            MercurialRepository(repo_path, create=True)
 

	
 
    def __rename_repo(self, old, new):
 
        log.info('renaming repoo from %s to %s', old, new)
 
        old_path = os.path.join(g.base_path, old)
 
        new_path = os.path.join(g.base_path, new)
 
        shutil.move(old_path, new_path)
 
    
 
    def __delete_repo(self, name):
 
        rm_path = os.path.join(g.base_path, name)
 
        log.info("Removing %s", rm_path)
 
        #disable hg 
 
        shutil.move(os.path.join(rm_path, '.hg'), os.path.join(rm_path, 'rm__.hg'))
 
        #disable repo
 
        shutil.move(rm_path, os.path.join(g.base_path, 'rm__%s__%s' \
 
                                          % (datetime.today(), name)))
pylons_app/templates/admin/repos/repo_add.html
Show inline comments
 
@@ -9,36 +9,36 @@
 
	 /  
 
	${_('Repos')}
 
</%def>
 
<%def name="page_nav()">
 
	${self.menu('admin')}
 
	${self.submenu('repos')}
 
</%def>
 
<%def name="main()">
 
	<div>
 
        <h2>${_('Repositories')} - ${_('add new')}</h2>
 
        ${h.form(url('repos'))}
 
        <table>
 
        	<tr>
 
        		<td>${_('Name')}</td>
 
        		<td>${h.text('repo_name',c.new_repo)}</td>
 
        		<td>${self.get_form_error('repo_name')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Description')}</td>
 
        		<td>${h.textarea('description',cols=23,rows=5)}</td>
 
        		<td>${self.get_form_error('description')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Private')}</td>
 
        		<td>${h.checkbox('private')}</td>
 
        		<td>${h.checkbox('private',value="True")}</td>
 
        		<td>${self.get_form_error('private')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td></td>
 
        		<td>${h.submit('add','add')}</td>
 
        	</tr>
 
        	        	        	
 
        </table>
 
        ${h.end_form()}
 
    </div>
 
</%def>   
pylons_app/templates/admin/repos/repo_edit.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Repositories administration')}
 
</%def>
 
<%def name="breadcrumbs()">
 
	${h.link_to(u'Admin',h.url('admin_home'))}
 
	 /  
 
	 ${_('Repos')}
 
</%def>
 
<%def name="page_nav()">
 
	${self.menu('admin')}
 
	${self.submenu('repos')}
 
</%def>
 
<%def name="main()">
 
	<div>
 
        <h2>${_('Repositories')} - ${_('edit')}</h2>
 
        ${h.form(url('repo', id=c.repo_info.repo_name),method='put')}
 
        <h2>${_('Repositories')} - ${_('edit')} "${c.repo_name}"</h2>
 
        ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
 
        <table>
 
        	<tr>
 
        		<td>${_('Name')}</td>
 
        		<td>${h.text('repo_name')}</td>
 
        		<td>${h.text('repo_name',size="28")}</td>
 
        		<td>${self.get_form_error('repo_name')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Description')}</td>
 
        		<td>${h.textarea('description',cols=23,rows=5)}</td>
 
        		<td>${h.textarea('description',cols=32,rows=5)}</td>
 
        		<td>${self.get_form_error('description')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Private')}</td>
 
        		<td>${h.checkbox('private')}</td>
 
        		<td>${h.checkbox('private',value="True")}</td>
 
        		<td>${self.get_form_error('private')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Owner')}</td>
 
				<td class='ac'>
 
					<div id="perm_ac">
 
						${h.text('user',class_='yui-ac-input')}
 
						<div id="owner_container"></div>
 
					</div>
 
				</td>        		
 
        		<td>${self.get_form_error('user')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Permissions')}</td>
 
        		<td>
 
        			<table>
 
        				<tr>
 
        					<td>${_('none')}</td>
 
        					<td>${_('read')}</td>
 
        					<td>${_('write')}</td>
 
        					<td>${_('admin')}</td>
 
        					<td>${_('user')}</td>
 
        				</tr>
 
        				
 
        				%for r2p in c.repo_info.repo2perm:
 
        					%if r2p.user.username =='default' and c.repo_info.private:
 
	        				<tr>
 
									<td colspan="4">
 
										<span style="font-size: 0.8em">${_('disabled for private repository')}</span></td>
 
									<td>${r2p.user.username}</td>
 
								</tr>
 
							%else:
 
	        				<tr id=${id(r2p.user.username)}>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
 
	        					<td>${r2p.user.username}</td>
 
	        					<td>
 
	        					  %if r2p.user.username !='default':
 
				                  	<span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},${id(r2p.user.username)})">
 
				                  		<script type="text/javascript">
 
											function ajaxAction(user_id,field_id){
 
												var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
 
												var callback = { success:function(o){
 
																YAHOO.util.Dom.get(String(field_id)).innerHTML = '<td colspan="6"></td>';
 
															 }};
 
												var postData = '_method=delete&user_id='+user_id; 
 
												var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData); 
 
						                	};
 
										</script>       	
 
				                  	</span>
 
				                  %endif					
 
	        					</td>
 
	        				</tr>
 
	        				%endif
 
						%endfor
 
						<%
 
							if not hasattr(c,'form_errors'):
 
								d = 'display:none;'
 
							else:
 
								d=''
 
						%>
 

	
 
        				<tr id="add_perm_input" style="${d}">
 
        					<td>${h.radio('perm_new_user','repository.none')}</td>
 
        					<td>${h.radio('perm_new_user','repository.read')}</td>
 
        					<td>${h.radio('perm_new_user','repository.write')}</td>
 
        					<td>${h.radio('perm_new_user','repository.admin')}</td>
 
        					<td class='ac'>
 
        						<div id="perm_ac">
 
        							${h.text('perm_new_user_name',class_='yui-ac-input')}
 
									<div id="perm_container"></div>
 
        						</div>
 
        					</td>
 
        					<td>${self.get_form_error('perm_new_user_name')}</td>     					
 
        				</tr>
 
        				<tr>
 
        					<td colspan="4">
 
        						<span id="add_perm" class="add_icon" style="cursor: pointer;">
pylons_app/templates/admin/repos/repos.html
Show inline comments
 
@@ -3,37 +3,37 @@
 

	
 
<%def name="title()">
 
    ${_('Repositories administration')}
 
</%def>
 
<%def name="breadcrumbs()">
 
	${h.link_to(u'Admin',h.url('admin_home'))}
 
	 /  
 
	 ${_('Repos')}
 
</%def>
 
<%def name="page_nav()">
 
	${self.menu('admin')}
 
	${self.submenu('repos')}
 
</%def>
 
<%def name="main()">
 
	<div>
 
        <h2>${_('Repositories administration')}</h2>
 
        <table class="table_disp">
 
        <tr class="header">
 
            <td>${_('name')}</td>
 
            <td>${_('last revision')}</td>
 
            <td>${_('action')}</td>
 
        </tr>
 
	        %for cnt,repo in enumerate(c.repos_list):
 
	 		<tr class="parity${cnt%2}">
 
			    <td>${h.link_to(repo['name'],h.url('edit_repo',id=repo['name']))}</td>
 
			    <td>${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))}</td>
 
		        <td>r${repo['rev']}:${repo['tip']}</td>
 
                <td>
 
                  ${h.form(url('repo', id=repo['name']),method='delete')}
 
                  ${h.form(url('repo', repo_name=repo['name']),method='delete')}
 
                  	${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
 
                  ${h.end_form()}
 
     			</td>
 
			</tr>
 
			%endfor
 
		</table>
 
		<span class="add_icon">${h.link_to(u'add repo',h.url('new_repo'))}</span>    
 
    </div>
 
</%def>    
pylons_app/templates/base/base.html
Show inline comments
 
@@ -85,49 +85,49 @@ def is_current(selected):
 
		            var wa = YAHOO.util.Dom.get('repos_list').value;
 
		        	
 
		            var url = "${h.url('summary_home',repo_name='__REPLACE__')}".replace('__REPLACE__',wa);
 
			        window.location = url;
 
				})
 
	           });
 
	       	</script>       	
 
	        <ul class="page-nav">
 
				<li>
 
					<a id="repo_switcher" title="${_('Switch repository')}" href="#">&darr;</a>
 
					<div id="switch_repos" style="display:none;position: absolute;height: 25px">
 
						<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()):
 
							<option value="${repo}">${repo}</option>
 
						%endfor
 
						</select>
 
					</div>			
 
				</li>
 
	            <li ${is_current('summary')}>${h.link_to(_('summary'),h.url('summary_home',repo_name=c.repo_name))}</li>
 
	            <li ${is_current('shortlog')}>${h.link_to(_('shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}</li>
 
				<li ${is_current('changelog')}>${h.link_to(_('changelog'),h.url('changelog_home',repo_name=c.repo_name))}</li>            
 
	            <li ${is_current('branches')}>${h.link_to(_('branches'),h.url('branches_home',repo_name=c.repo_name))}</li>
 
	            <li ${is_current('tags')}>${h.link_to(_('tags'),h.url('tags_home',repo_name=c.repo_name))}</li>
 
	            <li ${is_current('files')}>${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name))}</li>
 
				<li>${h.link_to(_('settings'),h.url('edit_repo',id=c.repo_name))}</li>	        
 
				<li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name))}</li>	        
 
	        </ul>
 
		%else:
 
		##Root menu
 
			<ul class="page-nav">
 
				<li ${is_current('home')}>${h.link_to(_('Home'),h.url('/'))}</li>
 
				<li ${is_current('admin')}>${h.link_to(_('Admin'),h.url('admin_home'))}</li>
 
				<li class="logout">${h.link_to(u'Logout',h.url('logout_home'))}</li>
 
			</ul>
 
		%endif    
 
		</div>
 
</%def>
 
<%def name="submenu(current=None)">
 
	<% 
 
	def is_current(selected):
 
		if selected == current:
 
			return "class='current_submenu'"
 
	%>
 
	%if current != None:
 
	<div>
 
    <ul class="submenu">
 
        <li ${is_current('repos')}>${h.link_to(u'repos',h.url('repos'),class_='repos')}</li>
 
        <li ${is_current('users')}>${h.link_to(u'users',h.url('users'),class_='users')}</li>
 
        <li ${is_current('permissions')}>${h.link_to(u'permissions',h.url('permissions'),class_='permissions')}</li>
 
    </ul>
0 comments (0 inline, 0 general)