Changeset - b9bbc0d6e9f3
[Not reviewed]
beta
0 7 0
Marcin Kuzminski - 15 years ago 2010-11-18 01:55:51
marcin@python-works.com
added cache reset, stats reset, and delete into repository settings in admin.
Some small template fixes
7 files changed with 105 insertions and 11 deletions:
0 comments (0 inline, 0 general)
rhodecode/config/routing.py
Show inline comments
 
"""
 
Routes configuration
 

	
 
The more specific and detailed routes should be defined first so they
 
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 rhodecode.lib.utils import check_repo_fast as cr
 

	
 
def make_map(config):
 
    """Create, configure and return the routes Mapper"""
 
    map = Mapper(directory=config['pylons.paths']['controllers'],
 
                 always_scan=config['debug'])
 
    map.minimization = False
 
    map.explicit = False
 

	
 
    def check_repo(environ, match_dict):
 
        """
 
        check for valid repository for proper 404 handling
 
        :param environ:
 
        :param match_dict:
 
        """
 
        repo_name = match_dict.get('repo_name')
 
        return not cr(repo_name, config['base_path'])
 

	
 
    # 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
 
    #==========================================================================
 

	
 
    #MAIN PAGE
 
    map.connect('home', '/', controller='home', action='index')
 
    map.connect('bugtracker', "http://bitbucket.org/marcinkuzminski/rhodecode/issues", _static=True)
 
    map.connect('gpl_license', "http://www.gnu.org/licenses/gpl.html", _static=True)
 
    #ADMIN REPOSITORY REST ROUTES
 
    with map.submapper(path_prefix='/_admin', controller='admin/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/{repo_name:.*}",
 
             action="update", conditions=dict(method=["PUT"],
 
                                              function=check_repo))
 
        m.connect("/repos/{repo_name:.*}",
 
             action="delete", conditions=dict(method=["DELETE"],
 
                                              function=check_repo))
 
        m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
 
             action="edit", conditions=dict(method=["GET"],
 
                                            function=check_repo))
 
        m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
 
             action="edit", conditions=dict(method=["GET"],
 
                                            function=check_repo))
 
        m.connect("repo", "/repos/{repo_name:.*}",
 
             action="show", conditions=dict(method=["GET"],
 
                                            function=check_repo))
 
        m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
 
             action="show", conditions=dict(method=["GET"],
 
                                            function=check_repo))
 
        #ajax delete repo perm user
 
        m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
 
             action="delete_perm_user", conditions=dict(method=["DELETE"],
 
                                                        function=check_repo))
 

	
 
        #settings actions
 
        m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
 
             action="repo_stats", conditions=dict(method=["DELETE"],
 
                                                        function=check_repo))
 
        m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
 
             action="repo_cache", conditions=dict(method=["DELETE"],
 
                                                        function=check_repo))
 
    #ADMIN USER REST ROUTES
 
    map.resource('user', 'users', controller='admin/users', path_prefix='/_admin')
 

	
 
    #ADMIN PERMISSIONS REST ROUTES
 
    map.resource('permission', 'permissions', controller='admin/permissions', path_prefix='/_admin')
 
    map.connect('permissions_ldap', '/_admin/permissions_ldap', controller='admin/permissions', action='ldap')
 

	
 

	
 
    #ADMIN SETTINGS REST ROUTES
 
    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("formatted_admin_settings", "/settings.{format}",
 
             action="index", conditions=dict(method=["GET"]))
 
        m.connect("admin_new_setting", "/settings/new",
 
             action="new", conditions=dict(method=["GET"]))
 
        m.connect("formatted_admin_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("formatted_admin_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("formatted_admin_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"]))
 
        m.connect("admin_settings_create_repository", "/create_repository",
 
             action="create_repository", conditions=dict(method=["GET"]))
 

	
 
    #ADMIN MAIN PAGES
 
    with map.submapper(path_prefix='/_admin', controller='admin/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')
 
    #SEARCH
 
    map.connect('search', '/_admin/search', controller='search',)
 
    map.connect('search_repo', '/_admin/search/{search_repo:.*}', controller='search')
 

	
 
    #LOGIN/LOGOUT/REGISTER/SIGN IN
 
    map.connect('login_home', '/_admin/login', controller='login')
 
    map.connect('logout_home', '/_admin/logout', controller='login', action='logout')
 
    map.connect('register', '/_admin/register', controller='login', action='register')
 
    map.connect('reset_password', '/_admin/password_reset', controller='login', action='password_reset')
 

	
 
    #FEEDS
 
    map.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
 
                controller='feed', action='rss',
 
                conditions=dict(function=check_repo))
 
    map.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
 
                controller='feed', action='atom',
 
                conditions=dict(function=check_repo))
 

	
 

	
 
    #REPOSITORY ROUTES
 
    map.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
 
                controller='changeset', revision='tip',
 
                conditions=dict(function=check_repo))
 
    map.connect('raw_changeset_home', '/{repo_name:.*}/raw-changeset/{revision}',
 
                controller='changeset', action='raw_changeset', revision='tip',
 
                conditions=dict(function=check_repo))
 
    map.connect('summary_home', '/{repo_name:.*}/summary',
 
                controller='summary', conditions=dict(function=check_repo))
 
    map.connect('shortlog_home', '/{repo_name:.*}/shortlog',
 
                controller='shortlog', conditions=dict(function=check_repo))
 
    map.connect('branches_home', '/{repo_name:.*}/branches',
 
                controller='branches', conditions=dict(function=check_repo))
 
    map.connect('tags_home', '/{repo_name:.*}/tags',
 
                controller='tags', conditions=dict(function=check_repo))
 
    map.connect('changelog_home', '/{repo_name:.*}/changelog',
 
                controller='changelog', conditions=dict(function=check_repo))
 
    map.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
 
                controller='files', revision='tip', f_path='',
 
                conditions=dict(function=check_repo))
 
    map.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
 
                controller='files', action='diff', revision='tip', f_path='',
 
                conditions=dict(function=check_repo))
 
    map.connect('files_rawfile_home', '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
 
                controller='files', action='rawfile', revision='tip', f_path='',
 
                conditions=dict(function=check_repo))
 
    map.connect('files_raw_home', '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
 
                controller='files', action='raw', revision='tip', f_path='',
 
                conditions=dict(function=check_repo))
 
    map.connect('files_annotate_home', '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
 
                controller='files', action='annotate', revision='tip', f_path='',
 
                conditions=dict(function=check_repo))
 
    map.connect('files_archive_home', '/{repo_name:.*}/archive/{revision}/{fileformat}',
 
                controller='files', action='archivefile', revision='tip',
 
                conditions=dict(function=check_repo))
 
    map.connect('repo_settings_delete', '/{repo_name:.*}/settings',
 
                controller='settings', action="delete",
 
                conditions=dict(method=["DELETE"], function=check_repo))
 
    map.connect('repo_settings_update', '/{repo_name:.*}/settings',
 
                controller='settings', action="update",
 
                conditions=dict(method=["PUT"], function=check_repo))
 
    map.connect('repo_settings_home', '/{repo_name:.*}/settings',
 
                controller='settings', action='index',
 
                conditions=dict(function=check_repo))
 

	
 
    map.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
 
                controller='settings', action='fork_create',
 
                conditions=dict(function=check_repo, method=["POST"]))
 
    map.connect('repo_fork_home', '/{repo_name:.*}/fork',
 
                controller='settings', action='fork',
 
                conditions=dict(function=check_repo))
 

	
 
    return map
rhodecode/controllers/admin/repos.py
Show inline comments
 
#!/usr/bin/env python
 
# 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
 
# 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 7, 2010
 
admin controller for pylons
 
@author: marcink
 
"""
 
from formencode import htmlfill
 
from operator import itemgetter
 
from paste.httpexceptions import HTTPInternalServerError
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
 
    HasPermissionAnyDecorator
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.lib.utils import invalidate_cache, action_logger
 
from rhodecode.model.db import User
 
from rhodecode.model.forms import RepoForm
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.model.repo import RepoModel
 
import formencode
 
import logging
 
import traceback
 

	
 
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()
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
 
    def __before__(self):
 
        c.admin_user = session.get('admin_user')
 
        c.admin_username = session.get('admin_username')
 
        super(ReposController, self).__before__()
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def index(self, format='html'):
 
        """GET /repos: All items in the collection"""
 
        # url('repos')
 
        cached_repo_list = ScmModel().get_repos()
 
        c.repos_list = sorted(cached_repo_list, key=itemgetter('name_sort'))
 
        return render('admin/repos/repos.html')
 

	
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
 
    def create(self):
 
        """POST /repos: Create a new item"""
 
        # url('repos')
 
        repo_model = RepoModel()
 
        _form = RepoForm()()
 
        form_result = {}
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            repo_model.create(form_result, c.rhodecode_user)
 
            h.flash(_('created repository %s') % form_result['repo_name'],
 
                    category='success')
 

	
 
            if request.POST.get('user_created'):
 
                action_logger(self.rhodecode_user, 'user_created_repo',
 
                              form_result['repo_name'], '', self.sa)
 
            else:
 
                action_logger(self.rhodecode_user, 'admin_created_repo',
 
                              form_result['repo_name'], '', self.sa)
 

	
 
        except formencode.Invalid, errors:
 
            c.new_repo = errors.value['repo_name']
 

	
 
            if request.POST.get('user_created'):
 
                r = render('admin/repos/repo_add_create_repository.html')
 
            else:
 
                r = render('admin/repos/repo_add.html')
 

	
 
            return htmlfill.render(
 
                r,
 
                defaults=errors.value,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 

	
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            msg = _('error occured during creation of repository %s') \
 
                    % form_result.get('repo_name')
 
            h.flash(msg, category='error')
 
        if request.POST.get('user_created'):
 
            return redirect(url('home'))
 
        return redirect(url('repos'))
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    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')
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    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', repo_name=ID),
 
        #           method='put')
 
        # url('repo', repo_name=ID)
 
        repo_model = RepoModel()
 
        changed_name = repo_name
 
        _form = RepoForm(edit=True, old_data={'repo_name':repo_name})()
 

	
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            repo_model.update(repo_name, form_result)
 
            invalidate_cache('get_repo_cached_%s' % repo_name)
 
            h.flash(_('Repository %s updated successfully' % repo_name),
 
                    category='success')
 
            changed_name = form_result['repo_name']
 
            action_logger(self.rhodecode_user, 'admin_updated_repo',
 
                              changed_name, '', self.sa)
 

	
 
        except formencode.Invalid, errors:
 
            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})
 
            return htmlfill.render(
 
                render('admin/repos/repo_edit.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 occurred during update of repository %s') \
 
                    % repo_name, category='error')
 

	
 
        return redirect(url('edit_repo', repo_name=changed_name))
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    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', repo_name=ID),
 
        #           method='delete')
 
        # url('repo', repo_name=ID)
 

	
 
        repo_model = RepoModel()
 
        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') % repo_name,
 
                      category='error')
 

	
 
            return redirect(url('repos'))
 
        try:
 
            action_logger(self.rhodecode_user, 'admin_deleted_repo',
 
                              repo_name, '', self.sa)
 
            repo_model.delete(repo)
 
            invalidate_cache('get_repo_cached_%s' % repo_name)
 
            h.flash(_('deleted repository %s') % repo_name, category='success')
 

	
 
        except Exception, e:
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occured during deletion of %s') % repo_name,
 
                    category='error')
 

	
 
        return redirect(url('repos'))
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def delete_perm_user(self, repo_name):
 
        """
 
        DELETE an existing repository permission user
 
        :param repo_name:
 
        """
 

	
 
        try:
 
            repo_model = RepoModel()
 
            repo_model.delete_perm_user(request.POST, repo_name)
 
        except Exception, e:
 
            h.flash(_('An error occured during deletion of repository user'),
 
                    category='error')
 
            raise HTTPInternalServerError()
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def repo_stats(self, repo_name):
 
        """
 
        DELETE an existing repository statistics
 
        :param repo_name:
 
        """
 

	
 
        try:
 
            repo_model = RepoModel()
 
            repo_model.delete_stats(repo_name)
 
        except Exception, e:
 
            h.flash(_('An error occured during deletion of repository stats'),
 
                    category='error')
 
        return redirect(url('edit_repo', repo_name=repo_name))
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def repo_cache(self, repo_name):
 
        """
 
        INVALIDATE exisitings repository cache
 
        :param repo_name:
 
        """
 

	
 
        try:
 
            ScmModel().mark_for_invalidation(repo_name)
 
        except Exception, e:
 
            h.flash(_('An error occured during cache invalidation'),
 
                    category='error')
 
        return redirect(url('edit_repo', repo_name=repo_name))
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def show(self, repo_name, format='html'):
 
        """GET /repos/repo_name: Show a specific item"""
 
        # url('repo', repo_name=ID)
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    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 repo.stats:
 
            last_rev = repo.stats.stat_on_revision
 
        else:
 
            last_rev = 0
 
        c.stats_revision = last_rev
 
        c.repo_last_rev = ScmModel().get(repo_name).revisions[-1]
 
        if last_rev == 0:
 
            c.stats_percentage = 0
 
        else:
 
            c.stats_percentage = '%.2f' % ((float((last_rev)) / c.repo_last_rev) * 100)
 

	
 

	
 
        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') % repo_name,
 
                      category='error')
 

	
 
            return redirect(url('repos'))
 
        defaults = c.repo_info.__dict__
 
        if c.repo_info.user:
 
            defaults.update({'user':c.repo_info.user.username})
 
        else:
 
            replacement_user = self.sa.query(User)\
 
            .filter(User.admin == True).first().username
 
            defaults.update({'user':replacement_user})
 

	
 
        c.users_array = repo_model.get_users_js()
 

	
 
        for p in c.repo_info.repo_to_perm:
 
            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
 
        )
rhodecode/model/db.py
Show inline comments
 
from rhodecode.model.meta import Base
 
from sqlalchemy import *
 
from sqlalchemy.orm import relation, backref
 
from sqlalchemy.orm.session import Session
 
from vcs.utils.lazy import LazyProperty
 
import logging
 
log = logging.getLogger(__name__)
 

	
 
class RhodeCodeSettings(Base):
 
    __tablename__ = 'rhodecode_settings'
 
    __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
 
    app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    app_settings_name = Column("app_settings_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    app_settings_value = Column("app_settings_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 

	
 
    def __init__(self, k, v):
 
        self.app_settings_name = k
 
        self.app_settings_value = v
 

	
 
    def __repr__(self):
 
        return "<RhodeCodeSetting('%s:%s')>" % (self.app_settings_name,
 
                                                self.app_settings_value)
 

	
 
class RhodeCodeUi(Base):
 
    __tablename__ = 'rhodecode_ui'
 
    __table_args__ = {'useexisting':True}
 
    ui_id = Column("ui_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    ui_section = Column("ui_section", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    ui_key = Column("ui_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    ui_value = Column("ui_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    ui_active = Column("ui_active", BOOLEAN(), nullable=True, unique=None, default=True)
 

	
 

	
 
class User(Base):
 
    __tablename__ = 'users'
 
    __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
 
    user_id = Column("user_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    username = Column("username", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    password = Column("password", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    active = Column("active", BOOLEAN(), nullable=True, unique=None, default=None)
 
    admin = Column("admin", BOOLEAN(), nullable=True, unique=None, default=False)
 
    name = Column("name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    lastname = Column("lastname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    email = Column("email", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    last_login = Column("last_login", DATETIME(timezone=False), nullable=True, unique=None, default=None)
 
    is_ldap = Column("is_ldap", BOOLEAN(), nullable=False, unique=None, default=False)
 

	
 
    user_log = relation('UserLog', cascade='all')
 
    user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
 

	
 
    @LazyProperty
 
    def full_contact(self):
 
        return '%s %s <%s>' % (self.name, self.lastname, self.email)
 

	
 
    def __repr__(self):
 
        return "<User('id:%s:%s')>" % (self.user_id, self.username)
 

	
 
    def update_lastlogin(self):
 
        """Update user lastlogin"""
 
        import datetime
 

	
 
        try:
 
            session = Session.object_session(self)
 
            self.last_login = datetime.datetime.now()
 
            session.add(self)
 
            session.commit()
 
            log.debug('updated user %s lastlogin', self.username)
 
        except Exception:
 
            session.rollback()
 

	
 

	
 
class UserLog(Base):
 
    __tablename__ = 'user_logs'
 
    __table_args__ = {'useexisting':True}
 
    user_log_id = Column("user_log_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
 
    repository_id = Column("repository_id", INTEGER(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
 
    repository_name = Column("repository_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    user_ip = Column("user_ip", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    action = Column("action", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    action_date = Column("action_date", DATETIME(timezone=False), nullable=True, unique=None, default=None)
 

	
 
    user = relation('User')
 
    repository = relation('Repository')
 

	
 
class Repository(Base):
 
    __tablename__ = 'repositories'
 
    __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
 
    repo_id = Column("repo_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    repo_name = Column("repo_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
 
    repo_type = Column("repo_type", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default=None)
 
    user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
 
    private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
 
    description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    fork_id = Column("fork_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=False, default=None)
 

	
 
    user = relation('User')
 
    fork = relation('Repository', remote_side=repo_id)
 
    repo_to_perm = relation('RepoToPerm', cascade='all')
 
    stats = relation('Statistics', cascade='all')
 
    stats = relation('Statistics', cascade='all', uselist=False)
 

	
 
    def __repr__(self):
 
        return "<Repository('%s:%s')>" % (self.repo_id, self.repo_name)
 

	
 
class Permission(Base):
 
    __tablename__ = 'permissions'
 
    __table_args__ = {'useexisting':True}
 
    permission_id = Column("permission_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    permission_longname = Column("permission_longname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 

	
 
    def __repr__(self):
 
        return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
 

	
 
class RepoToPerm(Base):
 
    __tablename__ = 'repo_to_perm'
 
    __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
 
    repo_to_perm_id = Column("repo_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
 
    repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
 

	
 
    user = relation('User')
 
    permission = relation('Permission')
 
    repository = relation('Repository')
 

	
 
class UserToPerm(Base):
 
    __tablename__ = 'user_to_perm'
 
    __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
 
    user_to_perm_id = Column("user_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
 

	
 
    user = relation('User')
 
    permission = relation('Permission')
 

	
 
class Statistics(Base):
 
    __tablename__ = 'statistics'
 
    __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
 
    stat_id = Column("stat_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=True, default=None)
 
    stat_on_revision = Column("stat_on_revision", INTEGER(), nullable=False)
 
    commit_activity = Column("commit_activity", BLOB(), nullable=False)#JSON data
 
    commit_activity_combined = Column("commit_activity_combined", BLOB(), nullable=False)#JSON data
 
    languages = Column("languages", BLOB(), nullable=False)#JSON data
 

	
 
    repository = relation('Repository', single_parent=True)
 

	
 
class CacheInvalidation(Base):
 
    __tablename__ = 'cache_invalidation'
 
    __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
 
    cache_id = Column("cache_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    cache_key = Column("cache_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    cache_args = Column("cache_args", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    cache_active = Column("cache_active", BOOLEAN(), nullable=True, unique=None, default=False)
 

	
 

	
 
    def __init__(self, cache_key, cache_args=''):
 
        self.cache_key = cache_key
 
        self.cache_args = cache_args
 
        self.cache_active = False
 

	
 
    def __repr__(self):
 
        return "<CacheInvaidation('%s:%s')>" % (self.cache_id, self.cache_key)
rhodecode/model/repo.py
Show inline comments
 
#!/usr/bin/env python
 
# encoding: utf-8
 
# model for handling repositories actions
 
# 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
 
# 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 Jun 5, 2010
 
model for handling repositories actions
 
:author: marcink
 
"""
 
from vcs.backends import get_repo, get_backend
 
from datetime import datetime
 
from pylons import app_globals as g
 
from rhodecode.model.db import Repository, RepoToPerm, User, Permission
 
from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
 
    Statistics
 
from rhodecode.model.meta import Session
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.caching_query import FromCache
 
import logging
 
import os
 
import shutil
 
import traceback
 
log = logging.getLogger(__name__)
 

	
 
class RepoModel(object):
 

	
 
    def __init__(self):
 
        self.sa = Session()
 

	
 
    def get(self, repo_id, cache=False):
 
        repo = self.sa.query(Repository)\
 
            .filter(Repository.repo_name == repo_id)
 

	
 
        if cache:
 
            repo = repo.options(FromCache("sql_cache_short",
 
                                          "get_repo_%s" % repo))
 
        return repo.scalar()
 

	
 
    def get_users_js(self):
 

	
 
        users = self.sa.query(User).filter(User.active == True).all()
 
        u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
 
        users_array = '[%s];' % '\n'.join([u_tmpl % (u.user_id, u.name,
 
                                                    u.lastname, u.username)
 
                                        for u in users])
 
        return users_array
 

	
 

	
 
    def update(self, repo_name, form_data):
 
        try:
 

	
 
            #update permissions
 
            for username, perm in form_data['perms_updates']:
 
                r2p = self.sa.query(RepoToPerm)\
 
                        .filter(RepoToPerm.user == UserModel().get_by_username(username, cache=False))\
 
                        .filter(RepoToPerm.repository == self.get(repo_name))\
 
                        .one()
 

	
 
                r2p.permission_id = self.sa.query(Permission).filter(
 
                                                Permission.permission_name ==
 
                                                perm).one().permission_id
 
                self.sa.add(r2p)
 

	
 
            #set new permissions
 
            for username, perm in form_data['perms_new']:
 
                r2p = RepoToPerm()
 
                r2p.repository = self.get(repo_name)
 
                r2p.user = UserModel().get_by_username(username, cache=False)
 

	
 
                r2p.permission_id = self.sa.query(Permission).filter(
 
                                        Permission.permission_name == perm)\
 
                                        .one().permission_id
 
                self.sa.add(r2p)
 

	
 
            #update current repo
 
            cur_repo = self.get(repo_name, cache=False)
 

	
 
            for k, v in form_data.items():
 
                if k == 'user':
 
                    cur_repo.user_id = v
 
                else:
 
                    setattr(cur_repo, k, v)
 

	
 
            self.sa.add(cur_repo)
 

	
 
            if repo_name != form_data['repo_name']:
 
                #rename our data
 
                self.__rename_repo(repo_name, form_data['repo_name'])
 

	
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def create(self, form_data, cur_user, just_db=False, fork=False):
 
        try:
 
            if fork:
 
                #force str since hg doesn't go with unicode
 
                repo_name = str(form_data['fork_name'])
 
                org_name = str(form_data['repo_name'])
 

	
 
            else:
 
                org_name = repo_name = str(form_data['repo_name'])
 
            new_repo = Repository()
 
            for k, v in form_data.items():
 
                if k == 'repo_name':
 
                    v = repo_name
 
                setattr(new_repo, k, v)
 

	
 
            if fork:
 
                parent_repo = self.sa.query(Repository)\
 
                        .filter(Repository.repo_name == org_name).scalar()
 
                new_repo.fork = parent_repo
 

	
 
            new_repo.user_id = cur_user.user_id
 
            self.sa.add(new_repo)
 

	
 
            #create default permission
 
            repo_to_perm = RepoToPerm()
 
            default = 'repository.read'
 
            for p in UserModel().get_by_username('default', cache=False).user_perms:
 
                if p.permission.permission_name.startswith('repository.'):
 
                    default = p.permission.permission_name
 
                    break
 

	
 
            default_perm = 'repository.none' if form_data['private'] else default
 

	
 
            repo_to_perm.permission_id = self.sa.query(Permission)\
 
                    .filter(Permission.permission_name == default_perm)\
 
                    .one().permission_id
 

	
 
            repo_to_perm.repository_id = new_repo.repo_id
 
            repo_to_perm.user_id = UserModel().get_by_username('default', cache=False).user_id
 

	
 
            self.sa.add(repo_to_perm)
 
            self.sa.commit()
 
            if not just_db:
 
                self.__create_repo(repo_name, form_data['repo_type'])
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def create_fork(self, form_data, cur_user):
 
        from rhodecode.lib.celerylib import tasks, run_task
 
        run_task(tasks.create_repo_fork, form_data, cur_user)
 

	
 
    def delete(self, repo):
 
        try:
 
            self.sa.delete(repo)
 
            self.__delete_repo(repo)
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def delete_perm_user(self, form_data, repo_name):
 
        try:
 
            self.sa.query(RepoToPerm)\
 
                .filter(RepoToPerm.repository == self.get(repo_name))\
 
                .filter(RepoToPerm.user_id == form_data['user_id']).delete()
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def delete_stats(self, repo_name):
 
        try:
 
            self.sa.query(Statistics)\
 
                .filter(Statistics.repository == self.get(repo_name)).delete()
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 

	
 
    def __create_repo(self, repo_name, alias):
 
        from rhodecode.lib.utils import check_repo
 
        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)
 
            backend = get_backend(alias)
 
            backend(repo_path, create=True)
 

	
 
    def __rename_repo(self, old, new):
 
        log.info('renaming repo from %s to %s', old, new)
 

	
 
        old_path = os.path.join(g.base_path, old)
 
        new_path = os.path.join(g.base_path, new)
 
        if os.path.isdir(new_path):
 
            raise Exception('Was trying to rename to already existing dir %s',
 
                            new_path)
 
        shutil.move(old_path, new_path)
 

	
 
    def __delete_repo(self, repo):
 
        rm_path = os.path.join(g.base_path, repo.repo_name)
 
        log.info("Removing %s", rm_path)
 
        #disable hg/git
 
        alias = repo.repo_type
 
        shutil.move(os.path.join(rm_path, '.%s' % alias),
 
                    os.path.join(rm_path, 'rm__.%s' % alias))
 
        #disable repo
 
        shutil.move(rm_path, os.path.join(g.base_path, 'rm__%s__%s' \
 
                                          % (datetime.today(), repo.repo_name)))
rhodecode/public/css/style.css
Show inline comments
 
@@ -269,2063 +269,2071 @@ text-decoration:none;
 
}
 
 
#header #header-inner #logo a:hover {
 
color:#bfe3ff;
 
}
 
 
#header #header-inner #quick,#header #header-inner #quick ul {
 
position:relative;
 
float:right;
 
list-style-type:none;
 
list-style-position:outside;
 
margin:10px 5px 0 0;
 
padding:0;
 
}
 
 
#header #header-inner #quick li {
 
position:relative;
 
float:left;
 
margin:0 5px 0 0;
 
padding:0;
 
}
 
 
#header #header-inner #quick li a {
 
top:0;
 
left:0;
 
height:1%;
 
display:block;
 
clear:both;
 
overflow:hidden;
 
color:#FFF;
 
font-weight:700;
 
text-decoration:none;
 
background:#369 url("../../images/quick_l.png") no-repeat top left;
 
padding:0;
 
}
 
 
#header #header-inner #quick li span {
 
top:0;
 
right:0;
 
height:1%;
 
display:block;
 
float:left;
 
background:url("../../images/quick_r.png") no-repeat top right;
 
border-left:1px solid #3f6f9f;
 
margin:0;
 
padding:10px 12px 8px 10px;
 
}
 
 
#header #header-inner #quick li span.normal {
 
border:none;
 
padding:10px 12px 8px;
 
}
 
 
#header #header-inner #quick li span.icon {
 
top:0;
 
left:0;
 
border-left:none;
 
background:url("../../images/quick_l.png") no-repeat top left;
 
border-right:1px solid #2e5c89;
 
padding:8px 8px 4px;
 
}
 
 
#header #header-inner #quick li a:hover {
 
background:#4e4e4e url("../../images/quick_l_selected.png") no-repeat top left;
 
}
 
 
#header #header-inner #quick li a:hover span {
 
border-left:1px solid #545454;
 
background:url("../../images/quick_r_selected.png") no-repeat top right;
 
}
 
 
#header #header-inner #quick li a:hover span.icon {
 
border-left:none;
 
border-right:1px solid #464646;
 
background:url("../../images/quick_l_selected.png") no-repeat top left;
 
}
 
 
#header #header-inner #quick ul {
 
top:29px;
 
right:0;
 
min-width:200px;
 
display:none;
 
position:absolute;
 
background:#FFF;
 
border:1px solid #666;
 
border-top:1px solid #003367;
 
z-index:100;
 
margin:0;
 
padding:0;
 
}
 
 
#header #header-inner #quick ul.repo_switcher {
 
max-height:275px;
 
overflow-x:hidden;
 
overflow-y:auto;
 
}
 
 
#header #header-inner #quick .repo_switcher_type{
 
position:absolute;
 
left:0;
 
top:9px; 
 
 
}
 
#header #header-inner #quick li ul li {
 
border-bottom:1px solid #ddd;
 
}
 
 
#header #header-inner #quick li ul li a {
 
width:182px;
 
height:auto;
 
display:block;
 
float:left;
 
background:#FFF;
 
color:#003367;
 
font-weight:400;
 
margin:0;
 
padding:7px 9px;
 
}
 
 
#header #header-inner #quick li ul li a:hover {
 
color:#000;
 
background:#FFF;
 
}
 
 
#header #header-inner #quick ul ul {
 
top:auto;
 
}
 
 
#header #header-inner #quick li ul ul {
 
right:200px;
 
max-height:275px;
 
overflow:auto;
 
overflow-x:hidden;
 
white-space:normal;
 
}
 
 
#header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover {
 
background:url("../images/icons/book.png") no-repeat scroll 4px 9px #FFF;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover {
 
background:url("../images/icons/lock.png") no-repeat scroll 4px 9px #FFF;
 
min-width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover {
 
background:url("../images/icons/lock_open.png") no-repeat scroll 4px 9px #FFF;
 
min-width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.hg,#header #header-inner #quick li ul li a.hg:hover {
 
background:url("../images/icons/hgicon.png") no-repeat scroll 4px 9px #FFF;
 
min-width:167px;
 
margin:0 0 0 14px;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.git,#header #header-inner #quick li ul li a.git:hover {
 
background:url("../images/icons/giticon.png") no-repeat scroll 4px 9px #FFF;
 
min-width:167px;
 
margin:0 0 0 14px;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover {
 
background:url("../images/icons/database_edit.png") no-repeat scroll 4px 9px #FFF;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover {
 
background:#FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover {
 
background:#FFF url("../images/icons/cog.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover {
 
background:#FFF url("../images/icons/key.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover {
 
background:#FFF url("../images/icons/arrow_divide.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover {
 
background:#FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover {
 
background:#FFF url("../images/icons/delete.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover {
 
background:#FFF url("../images/icons/arrow_branch.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.tags,#header #header-inner #quick li ul li a.tags:hover {
 
background:#FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#header #header-inner #quick li ul li a.admin,#header #header-inner #quick li ul li a.admin:hover {
 
background:#FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
 
width:167px;
 
margin:0;
 
padding:12px 9px 7px 24px;
 
}
 
 
#content #left {
 
left:0;
 
width:280px;
 
position:absolute;
 
}
 
 
#content #right {
 
margin:0 60px 10px 290px;
 
}
 
 
#content div.box {
 
clear:both;
 
overflow:hidden;
 
background:#fff;
 
margin:0 0 10px;
 
padding:0 0 10px;
 
}
 
 
#content div.box-left {
 
width:49%;
 
clear:none;
 
float:left;
 
margin:0 0 10px;
 
}
 
 
#content div.box-right {
 
width:49%;
 
clear:none;
 
float:right;
 
margin:0 0 10px;
 
}
 
 
#content div.box div.title {
 
clear:both;
 
overflow:hidden;
 
background:#369 url("../images/header_inner.png") repeat-x;
 
margin:0 0 20px;
 
padding:0;
 
}
 
 
#content div.box div.title h5 {
 
float:left;
 
border:none;
 
color:#fff;
 
text-transform:uppercase;
 
margin:0;
 
padding:11px 0 11px 10px;
 
}
 
 
#content div.box div.title ul.links li {
 
list-style:none;
 
float:left;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.title ul.links li a {
 
height:1%;
 
display:block;
 
float:left;
 
border-left:1px solid #316293;
 
color:#fff;
 
font-size:11px;
 
font-weight:700;
 
text-decoration:none;
 
margin:0;
 
padding:13px 16px 12px;
 
}
 
 
#content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6 {
 
clear:both;
 
overflow:hidden;
 
border-bottom:1px solid #DDD;
 
margin:10px 20px;
 
padding:0 0 15px;
 
}
 
 
#content div.box p {
 
color:#5f5f5f;
 
font-size:12px;
 
line-height:150%;
 
margin:0 24px 10px;
 
padding:0;
 
}
 
 
#content div.box blockquote {
 
border-left:4px solid #DDD;
 
color:#5f5f5f;
 
font-size:11px;
 
line-height:150%;
 
margin:0 34px;
 
padding:0 0 0 14px;
 
}
 
 
#content div.box blockquote p {
 
margin:10px 0;
 
padding:0;
 
}
 
 
#content div.box dl {
 
margin:10px 24px;
 
}
 
 
#content div.box dt {
 
font-size:12px;
 
margin:0;
 
}
 
 
#content div.box dd {
 
font-size:12px;
 
margin:0;
 
padding:8px 0 8px 15px;
 
}
 
 
#content div.box li {
 
font-size:12px;
 
padding:4px 0;
 
}
 
 
#content div.box ul.disc,#content div.box ul.circle {
 
margin:10px 24px 10px 38px;
 
}
 
 
#content div.box ul.square {
 
margin:10px 24px 10px 40px;
 
}
 
 
#content div.box img.left {
 
border:none;
 
float:left;
 
margin:10px 10px 10px 0;
 
}
 
 
#content div.box img.right {
 
border:none;
 
float:right;
 
margin:10px 0 10px 10px;
 
}
 
 
#content div.box div.messages {
 
clear:both;
 
overflow:hidden;
 
margin:0 20px;
 
padding:0;
 
}
 
 
#content div.box div.message {
 
clear:both;
 
overflow:hidden;
 
margin:0;
 
padding:10px 0;
 
}
 
 
#content div.box div.message a {
 
font-weight:400 !important;
 
}
 
 
#content div.box div.message div.image {
 
float:left;
 
margin:9px 0 0 5px;
 
padding:6px;
 
}
 
 
#content div.box div.message div.image img {
 
vertical-align:middle;
 
margin:0;
 
}
 
 
#content div.box div.message div.text {
 
float:left;
 
margin:0;
 
padding:9px 6px;
 
}
 
 
#content div.box div.message div.dismiss a {
 
height:16px;
 
width:16px;
 
display:block;
 
background:url("../images/icons/cross.png") no-repeat;
 
margin:15px 14px 0 0;
 
padding:0;
 
}
 
 
#content div.box div.message div.text h1,#content div.box div.message div.text h2,#content div.box div.message div.text h3,#content div.box div.message div.text h4,#content div.box div.message div.text h5,#content div.box div.message div.text h6 {
 
border:none;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.message div.text span {
 
height:1%;
 
display:block;
 
margin:0;
 
padding:5px 0 0;
 
}
 
 
#content div.box div.message-error {
 
height:1%;
 
clear:both;
 
overflow:hidden;
 
background:#FBE3E4;
 
border:1px solid #FBC2C4;
 
color:#860006;
 
}
 
 
#content div.box div.message-error h6 {
 
color:#860006;
 
}
 
 
#content div.box div.message-warning {
 
height:1%;
 
clear:both;
 
overflow:hidden;
 
background:#FFF6BF;
 
border:1px solid #FFD324;
 
color:#5f5200;
 
}
 
 
#content div.box div.message-warning h6 {
 
color:#5f5200;
 
}
 
 
#content div.box div.message-notice {
 
height:1%;
 
clear:both;
 
overflow:hidden;
 
background:#8FBDE0;
 
border:1px solid #6BACDE;
 
color:#003863;
 
}
 
 
#content div.box div.message-notice h6 {
 
color:#003863;
 
}
 
 
#content div.box div.message-success {
 
height:1%;
 
clear:both;
 
overflow:hidden;
 
background:#E6EFC2;
 
border:1px solid #C6D880;
 
color:#4e6100;
 
}
 
 
#content div.box div.message-success h6 {
 
color:#4e6100;
 
}
 
 
#content div.box div.form div.fields div.field {
 
height:1%;
 
border-bottom:1px solid #DDD;
 
clear:both;
 
margin:0;
 
padding:10px 0;
 
}
 
 
#content div.box div.form div.fields div.field-first {
 
padding:0 0 10px;
 
}
 
 
#content div.box div.form div.fields div.field-noborder {
 
border-bottom:0 !important;
 
}
 
 
#content div.box div.form div.fields div.field span.error-message {
 
height:1%;
 
display:inline-block;
 
color:red;
 
margin:8px 0 0 4px;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field span.success {
 
height:1%;
 
display:block;
 
color:#316309;
 
margin:8px 0 0;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.label {
 
left:80px;
 
width:auto;
 
position:absolute;
 
margin:0;
 
padding:8px 0 0 5px;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label,#content div.box-right div.form div.fields div.field div.label {
 
clear:both;
 
overflow:hidden;
 
left:0;
 
width:auto;
 
position:relative;
 
margin:0;
 
padding:0 0 8px;
 
}
 
 
#content div.box div.form div.fields div.field div.label-select {
 
padding:5px 0 0 5px;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label-select,#content div.box-right div.form div.fields div.field div.label-select {
 
padding:0 0 8px;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label-textarea,#content div.box-right div.form div.fields div.field div.label-textarea {
 
padding:0 0 8px !important;
 
}
 
 
#content div.box div.form div.fields div.field div.label label {
 
color:#393939;
 
font-weight:700;
 
}
 
 
#content div.box div.form div.fields div.field div.input {
 
margin:0 0 0 200px;
 
}
 
#content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input {
 
margin:0 0 0 0px;
 
}
 
 
#content div.box div.form div.fields div.field div.input input {
 
background:#FFF;
 
border-top:1px solid #b3b3b3;
 
border-left:1px solid #b3b3b3;
 
border-right:1px solid #eaeaea;
 
border-bottom:1px solid #eaeaea;
 
color:#000;
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
margin:0;
 
padding:7px 7px 6px;
 
}
 
 
 
 
#content div.box div.form div.fields div.field div.input input.small {
 
width:30%;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.medium {
 
width:55%;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.large {
 
width:85%;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.date {
 
width:177px;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.button {
 
background:#D4D0C8;
 
border-top:1px solid #FFF;
 
border-left:1px solid #FFF;
 
border-right:1px solid #404040;
 
border-bottom:1px solid #404040;
 
color:#000;
 
margin:0;
 
padding:4px 8px;
 
}
 
 
#content div.box div.form div.fields div.field div.input a.ui-input-file {
 
width:28px;
 
height:28px;
 
display:inline;
 
position:absolute;
 
overflow:hidden;
 
cursor:pointer;
 
background:#e5e3e3 url("../images/button_browse.png") no-repeat;
 
border:none;
 
text-decoration:none;
 
margin:0 0 0 6px;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea {
 
border-top:1px solid #b3b3b3;
 
border-left:1px solid #b3b3b3;
 
border-right:1px solid #eaeaea;
 
border-bottom:1px solid #eaeaea;
 
margin:0 0 0 200px;
 
padding:10px;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea-editor {
 
border:1px solid #ddd;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea textarea {
 
width:100%;
 
height:220px;
 
overflow:hidden;
 
background:#FFF;
 
color:#000;
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
outline:none;
 
border-width:0;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box-left div.form div.fields div.field div.textarea textarea,#content div.box-right div.form div.fields div.field div.textarea textarea {
 
width:100%;
 
height:100px;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table {
 
width:100%;
 
border:none;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td {
 
background:#DDD;
 
border:none;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td table {
 
width:auto;
 
border:none;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td table td {
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
padding:5px 5px 5px 0;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive {
 
background:#b1b1b1;
 
}
 
 
#content div.box div.form div.fields div.field div.select a.ui-selectmenu {
 
color:#565656;
 
text-decoration:none;
 
}
 
 
#content div.box div.form div.fields div.field input[type=text]:focus,#content div.box div.form div.fields div.field input[type=password]:focus,#content div.box div.form div.fields div.field input[type=file]:focus,#content div.box div.form div.fields div.field textarea:focus,#content div.box div.form div.fields div.field select:focus {
 
background:#f6f6f6;
 
border-color:#666;
 
}
 
 
div.form div.fields div.field div.button {
 
margin:0;
 
padding:0 0 0 8px;
 
}
 
 
div.form div.fields div.field div.highlight .ui-state-default {
 
background:#4e85bb url("../images/button_highlight.png") repeat-x;
 
border-top:1px solid #5c91a4;
 
border-left:1px solid #2a6f89;
 
border-right:1px solid #2b7089;
 
border-bottom:1px solid #1a6480;
 
color:#FFF;
 
margin:0;
 
padding:6px 12px;
 
}
 
 
div.form div.fields div.field div.highlight .ui-state-hover {
 
background:#46a0c1 url("../images/button_highlight_selected.png") repeat-x;
 
border-top:1px solid #78acbf;
 
border-left:1px solid #34819e;
 
border-right:1px solid #35829f;
 
border-bottom:1px solid #257897;
 
color:#FFF;
 
margin:0;
 
padding:6px 12px;
 
}
 
 
#content div.box div.form div.fields div.buttons div.highlight input.ui-state-default {
 
background:#4e85bb url("../../images/button_highlight.png") repeat-x;
 
border-top:1px solid #5c91a4;
 
border-left:1px solid #2a6f89;
 
border-right:1px solid #2b7089;
 
border-bottom:1px solid #1a6480;
 
color:#fff;
 
margin:0;
 
padding:6px 12px;
 
}
 
 
#content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover {
 
background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
 
border-top:1px solid #78acbf;
 
border-left:1px solid #34819e;
 
border-right:1px solid #35829f;
 
border-bottom:1px solid #257897;
 
color:#fff;
 
margin:0;
 
padding:6px 12px;
 
}
 
 
#content div.box table {
 
width:100%;
 
border-collapse:collapse;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box table th {
 
background:#eee;
 
border-bottom:1px solid #ddd;
 
padding:5px 0px 5px 5px;
 
}
 
 
#content div.box table th.left {
 
text-align:left;
 
}
 
 
#content div.box table th.right {
 
text-align:right;
 
}
 
 
#content div.box table th.center {
 
text-align:center;
 
}
 
 
#content div.box table th.selected {
 
vertical-align:middle;
 
padding:0;
 
}
 
 
#content div.box table td {
 
background:#fff;
 
border-bottom:1px solid #cdcdcd;
 
vertical-align:middle;
 
padding:5px;
 
}
 
 
#content div.box table tr.selected td {
 
background:#FFC;
 
}
 
 
#content div.box table td.selected {
 
width:3%;
 
text-align:center;
 
vertical-align:middle;
 
padding:0;
 
}
 
 
#content div.box table td.action {
 
width:45%;
 
text-align:left;
 
}
 
 
#content div.box table td.date {
 
width:33%;
 
text-align:center;
 
}
 
 
#content div.box div.action {
 
float:right;
 
background:#FFF;
 
text-align:right;
 
margin:10px 0 0;
 
padding:0;
 
}
 
 
#content div.box div.action select {
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
margin:0;
 
}
 
 
#content div.box div.action .ui-selectmenu {
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.pagination {
 
height:1%;
 
clear:both;
 
overflow:hidden;
 
margin:10px 0 0;
 
padding:0;
 
}
 
 
#content div.box div.pagination ul.pager {
 
float:right;
 
text-align:right;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.pagination ul.pager li {
 
height:1%;
 
float:left;
 
list-style:none;
 
background:#ebebeb url("../images/pager.png") repeat-x;
 
border-top:1px solid #dedede;
 
border-left:1px solid #cfcfcf;
 
border-right:1px solid #c4c4c4;
 
border-bottom:1px solid #c4c4c4;
 
color:#4A4A4A;
 
font-weight:700;
 
margin:0 0 0 4px;
 
padding:0;
 
}
 
 
#content div.box div.pagination ul.pager li.separator {
 
padding:6px;
 
}
 
 
#content div.box div.pagination ul.pager li.current {
 
background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
 
border-top:1px solid #ccc;
 
border-left:1px solid #bebebe;
 
border-right:1px solid #b1b1b1;
 
border-bottom:1px solid #afafaf;
 
color:#515151;
 
padding:6px;
 
}
 
 
#content div.box div.pagination ul.pager li a {
 
height:1%;
 
display:block;
 
float:left;
 
color:#515151;
 
text-decoration:none;
 
margin:0;
 
padding:6px;
 
}
 
 
#content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active {
 
background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
 
border-top:1px solid #ccc;
 
border-left:1px solid #bebebe;
 
border-right:1px solid #b1b1b1;
 
border-bottom:1px solid #afafaf;
 
margin:-1px;
 
}
 
 
#content div.box div.pagination-wh {
 
height:1%;
 
clear:both;
 
overflow:hidden;
 
text-align:right;
 
margin:10px 0 0;
 
padding:0;
 
}
 
 
#content div.box div.pagination-right {
 
float:right;
 
}
 
 
#content div.box div.pagination-wh a,#content div.box div.pagination-wh span.pager_dotdot {
 
height:1%;
 
float:left;
 
background:#ebebeb url("../images/pager.png") repeat-x;
 
border-top:1px solid #dedede;
 
border-left:1px solid #cfcfcf;
 
border-right:1px solid #c4c4c4;
 
border-bottom:1px solid #c4c4c4;
 
color:#4A4A4A;
 
font-weight:700;
 
margin:0 0 0 4px;
 
padding:6px;
 
}
 
 
#content div.box div.pagination-wh span.pager_curpage {
 
height:1%;
 
float:left;
 
background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
 
border-top:1px solid #ccc;
 
border-left:1px solid #bebebe;
 
border-right:1px solid #b1b1b1;
 
border-bottom:1px solid #afafaf;
 
color:#515151;
 
font-weight:700;
 
margin:0 0 0 4px;
 
padding:6px;
 
}
 
 
#content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active {
 
background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
 
border-top:1px solid #ccc;
 
border-left:1px solid #bebebe;
 
border-right:1px solid #b1b1b1;
 
border-bottom:1px solid #afafaf;
 
text-decoration:none;
 
}
 
 
#content div.box div.traffic div.legend {
 
clear:both;
 
overflow:hidden;
 
border-bottom:1px solid #ddd;
 
margin:0 0 10px;
 
padding:0 0 10px;
 
}
 
 
#content div.box div.traffic div.legend h6 {
 
float:left;
 
border:none;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.traffic div.legend li {
 
list-style:none;
 
float:left;
 
font-size:11px;
 
margin:0;
 
padding:0 8px 0 4px;
 
}
 
 
#content div.box div.traffic div.legend li.visits {
 
border-left:12px solid #edc240;
 
}
 
 
#content div.box div.traffic div.legend li.pageviews {
 
border-left:12px solid #afd8f8;
 
}
 
 
#content div.box div.traffic table {
 
width:auto;
 
}
 
 
#content div.box div.traffic table td {
 
background:transparent;
 
border:none;
 
padding:2px 3px 3px;
 
}
 
 
#content div.box div.traffic table td.legendLabel {
 
padding:0 3px 2px;
 
}
 
 
#footer {
 
clear:both;
 
overflow:hidden;
 
text-align:right;
 
margin:0;
 
padding:0 30px 4px;
 
margin:-10px 0 0;
 
}
 
 
#footer div#footer-inner {
 
background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367;
 
border-top:2px solid #FFFFFF;
 
}
 
 
#footer div#footer-inner p {
 
padding:15px 25px 15px 0;
 
color:#FFF;
 
font-weight:700;
 
}
 
#footer div#footer-inner .footer-link {
 
float:left;
 
padding-left:10px;
 
}
 
#footer div#footer-inner .footer-link a {
 
color:#FFF; 
 
}
 
 
#login div.title {
 
width:420px;
 
clear:both;
 
overflow:hidden;
 
position:relative;
 
background:#003367 url("../../images/header_inner.png") repeat-x;
 
margin:0 auto;
 
padding:0;
 
}
 
 
#login div.inner {
 
width:380px;
 
background:#FFF url("../images/login.png") no-repeat top left;
 
border-top:none;
 
border-bottom:none;
 
margin:0 auto;
 
padding:20px;
 
}
 
 
#login div.form div.fields div.field div.label {
 
width:173px;
 
float:left;
 
text-align:right;
 
margin:2px 10px 0 0;
 
padding:5px 0 0 5px;
 
}
 
 
#login div.form div.fields div.field div.input input {
 
width:176px;
 
background:#FFF;
 
border-top:1px solid #b3b3b3;
 
border-left:1px solid #b3b3b3;
 
border-right:1px solid #eaeaea;
 
border-bottom:1px solid #eaeaea;
 
color:#000;
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
margin:0;
 
padding:7px 7px 6px;
 
}
 
 
#login div.form div.fields div.buttons {
 
clear:both;
 
overflow:hidden;
 
border-top:1px solid #DDD;
 
text-align:right;
 
margin:0;
 
padding:10px 0 0;
 
}
 
 
#login div.form div.links {
 
clear:both;
 
overflow:hidden;
 
margin:10px 0 0;
 
padding:0 0 2px;
 
}
 
 
#register div.title {
 
width:420px;
 
clear:both;
 
overflow:hidden;
 
position:relative;
 
background:#003367 url("../images/header_inner.png") repeat-x;
 
margin:0 auto;
 
padding:0;
 
}
 
 
#register div.inner {
 
width:380px;
 
background:#FFF;
 
border-top:none;
 
border-bottom:none;
 
margin:0 auto;
 
padding:20px;
 
}
 
 
#register div.form div.fields div.field div.label {
 
width:100px;
 
float:left;
 
text-align:right;
 
margin:2px 10px 0 0;
 
padding:5px 0 0 5px;
 
}
 
 
#register div.form div.fields div.field div.input input {
 
width:245px;
 
background:#FFF;
 
border-top:1px solid #b3b3b3;
 
border-left:1px solid #b3b3b3;
 
border-right:1px solid #eaeaea;
 
border-bottom:1px solid #eaeaea;
 
color:#000;
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
margin:0;
 
padding:7px 7px 6px;
 
}
 
 
#register div.form div.fields div.buttons {
 
clear:both;
 
overflow:hidden;
 
border-top:1px solid #DDD;
 
text-align:left;
 
margin:0;
 
padding:10px 0 0 114px;
 
}
 
 
#register div.form div.fields div.buttons div.highlight input.ui-state-default {
 
background:url("../images/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
 
color:#FFF;
 
border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
 
border-style:solid;
 
border-width:1px;
 
}
 
 
#register div.form div.activation_msg {
 
padding-top:4px;
 
padding-bottom:4px;
 
}
 
 
.trending_language_tbl,.trending_language_tbl td {
 
border:0 !important;
 
margin:0 !important;
 
padding:0 !important;
 
}
 
 
.trending_language {
 
background-color:#003367;
 
color:#FFF;
 
display:block;
 
min-width:20px;
 
text-decoration:none;
 
height:12px;
 
margin-bottom:4px;
 
margin-left:5px;
 
white-space:pre;
 
padding:3px;
 
}
 
 
h3.files_location {
 
font-size:1.8em;
 
font-weight:700;
 
border-bottom:none !important;
 
margin:10px 0 !important;
 
}
 
 
#files_data dl dt {
 
float:left;
 
width:115px;
 
margin:0 !important;
 
padding:5px;
 
}
 
 
#files_data dl dd {
 
margin:0 !important;
 
padding:5px !important;
 
}
 
 
#changeset_content {
 
border:1px solid #CCC;
 
padding:5px;
 
}
 
 
#changeset_content .container {
 
min-height:120px;
 
font-size:1.2em;
 
overflow:hidden;
 
}
 
 
#changeset_content .container .right {
 
float:right;
 
width:25%;
 
text-align:right;
 
}
 
 
#changeset_content .container .left .message {
 
font-style:italic;
 
color:#556CB5;
 
white-space:pre-wrap;
 
}
 
 
.cs_files .cs_added {
 
background:url("../images/icons/page_white_add.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
margin-top:7px;
 
text-align:left;
 
}
 
 
.cs_files .cs_changed {
 
background:url("../images/icons/page_white_edit.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
margin-top:7px;
 
text-align:left;
 
}
 
 
.cs_files .cs_removed {
 
background:url("../images/icons/page_white_delete.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
margin-top:7px;
 
text-align:left;
 
}
 
 
#graph {
 
overflow:hidden;
 
}
 
 
#graph_nodes {
 
width:160px;
 
float:left;
 
margin-left:-50px;
 
margin-top:5px;
 
}
 
 
#graph_content {
 
width:800px;
 
float:left;
 
}
 
 
#graph_content .container_header {
 
border:1px solid #CCC;
 
padding:10px;
 
}
 
 
#graph_content .container {
 
border-bottom:1px solid #CCC;
 
border-left:1px solid #CCC;
 
border-right:1px solid #CCC;
 
min-height:80px;
 
overflow:hidden;
 
font-size:1.2em;
 
}
 
 
#graph_content .container .right {
 
float:right;
 
width:28%;
 
text-align:right;
 
padding-bottom:5px;
 
}
 
 
#graph_content .container .left .date {
 
font-weight:700;
 
padding-bottom:5px;
 
}
 
 
#graph_content .container .left .message {
 
font-size:100%;
 
padding-top:3px;
 
white-space:pre-wrap;
 
}
 
 
.right div {
 
clear:both;
 
}
 
 
.right .changes .added,.changed,.removed {
 
border:1px solid #DDD;
 
display:block;
 
float:right;
 
text-align:center;
 
min-width:15px;
 
}
 
 
.right .changes .added {
 
background:#BFB;
 
}
 
 
.right .changes .changed {
 
background:#FD8;
 
}
 
 
.right .changes .removed {
 
background:#F88;
 
}
 
 
.right .merge {
 
vertical-align:top;
 
font-size:0.75em;
 
font-weight:700;
 
}
 
 
.right .parent {
 
font-size:90%;
 
font-family:monospace;
 
}
 
 
.right .logtags .branchtag {
 
background:#FFF url("../images/icons/arrow_branch.png") no-repeat right 6px;
 
display:block;
 
font-size:0.8em;
 
padding:11px 16px 0 0;
 
}
 
 
.right .logtags .tagtag {
 
background:#FFF url("../images/icons/tag_blue.png") no-repeat right 6px;
 
display:block;
 
font-size:0.8em;
 
padding:11px 16px 0 0;
 
}
 
 
div.browserblock {
 
overflow:hidden;
 
border:1px solid #ccc;
 
background:#f8f8f8;
 
font-size:100%;
 
line-height:125%;
 
padding:0;
 
}
 
 
div.browserblock .browser-header {
 
border-bottom:1px solid #CCC;
 
background:#FFF;
 
color:blue;
 
padding:10px 0;
 
}
 
 
div.browserblock .browser-header span {
 
margin-left:25px;
 
font-weight:700;
 
}
 
 
div.browserblock .browser-body {
 
background:#EEE;
 
}
 
 
table.code-browser {
 
border-collapse:collapse;
 
width:100%;
 
}
 
 
table.code-browser tr {
 
margin:3px;
 
}
 
 
table.code-browser thead th {
 
background-color:#EEE;
 
height:20px;
 
font-size:1.1em;
 
font-weight:700;
 
text-align:left;
 
padding-left:10px;
 
}
 
 
table.code-browser tbody td {
 
padding-left:10px;
 
height:20px;
 
}
 
 
table.code-browser .browser-file {
 
background:url("../images/icons/document_16.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
text-align:left;
 
}
 
 
table.code-browser .browser-dir {
 
background:url("../images/icons/folder_16.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
text-align:left;
 
}
 
 
.box .search {
 
clear:both;
 
overflow:hidden;
 
margin:0;
 
padding:0 20px 10px;
 
}
 
 
.box .search div.search_path {
 
background:none repeat scroll 0 0 #EEE;
 
border:1px solid #CCC;
 
color:blue;
 
margin-bottom:10px;
 
padding:10px 0;
 
}
 
 
.box .search div.search_path div.link {
 
font-weight:700;
 
margin-left:25px;
 
}
 
 
.box .search div.search_path div.link a {
 
color:#003367;
 
cursor:pointer;
 
text-decoration:none;
 
}
 
 
#path_unlock {
 
color:red;
 
font-size:1.2em;
 
padding-left:4px;
 
}
 
 
.info_box * {
 
background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
 
color:#4A4A4A;
 
font-weight:700;
 
height:1%;
 
display:inline;
 
border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
 
border-style:solid;
 
border-width:1px;
 
padding:4px 6px;
 
}
 
 
.info_box span {
 
margin-left:3px;
 
margin-right:3px;
 
}
 
 
.info_box input#at_rev {
 
text-align:center;
 
padding:5px 3px 3px 2px;
 
}
 
 
.info_box input#view {
 
text-align:center;
 
padding:4px 3px 2px 2px;
 
}
 
 
.yui-overlay,.yui-panel-container {
 
visibility:hidden;
 
position:absolute;
 
z-index:2;
 
}
 
 
.yui-tt {
 
visibility:hidden;
 
position:absolute;
 
color:#666;
 
background-color:#FFF;
 
font-family:arial, helvetica, verdana, sans-serif;
 
border:2px solid #003367;
 
font:100% sans-serif;
 
width:auto;
 
opacity:1px;
 
padding:8px;
 
white-space: pre;
 
}
 
 
.ac {
 
vertical-align:top;
 
}
 
 
.ac .yui-ac {
 
position:relative;
 
font-family:arial;
 
font-size:100%;
 
}
 
 
.ac .perm_ac {
 
width:15em;
 
}
 
 
.ac .yui-ac-input {
 
width:100%;
 
}
 
 
.ac .yui-ac-container {
 
position:absolute;
 
top:1.6em;
 
width:100%;
 
}
 
 
.ac .yui-ac-content {
 
position:absolute;
 
width:100%;
 
border:1px solid gray;
 
background:#fff;
 
overflow:hidden;
 
z-index:9050;
 
}
 
 
.ac .yui-ac-shadow {
 
position:absolute;
 
width:100%;
 
background:#000;
 
-moz-opacity:0.1px;
 
opacity:.10;
 
filter:alpha(opacity =   10);
 
z-index:9049;
 
margin:.3em;
 
}
 
 
.ac .yui-ac-content ul {
 
width:100%;
 
margin:0;
 
padding:0;
 
}
 
 
.ac .yui-ac-content li {
 
cursor:default;
 
white-space:nowrap;
 
margin:0;
 
padding:2px 5px;
 
}
 
 
.ac .yui-ac-content li.yui-ac-prehighlight {
 
background:#B3D4FF;
 
}
 
 
.ac .yui-ac-content li.yui-ac-highlight {
 
background:#556CB5;
 
color:#FFF;
 
}
 
 
.add_icon {
 
background:url("../images/icons/add.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.edit_icon {
 
background:url("../images/icons/folder_edit.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.delete_icon {
 
background:url("../images/icons/delete.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.refresh_icon {
 
background:url("../images/icons/arrow_refresh.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.rss_icon {
 
background:url("../images/icons/rss_16.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.atom_icon {
 
background:url("../images/icons/atom.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
padding-top:1px;
 
text-align:left;
 
}
 
 
.archive_icon {
 
background:url("../images/icons/compress.png") no-repeat scroll 3px;
 
height:16px;
 
padding-left:20px;
 
text-align:left;
 
padding-top:1px;
 
}
 
 
.action_button {
 
border:0;
 
display:block;
 
}
 
 
.action_button:hover {
 
border:0;
 
text-decoration:underline;
 
cursor:pointer;
 
}
 
 
#switch_repos {
 
position:absolute;
 
height:25px;
 
z-index:1;
 
}
 
 
#switch_repos select {
 
min-width:150px;
 
max-height:250px;
 
z-index:1;
 
}
 
 
.breadcrumbs {
 
border:medium none;
 
color:#FFF;
 
float:left;
 
text-transform:uppercase;
 
font-weight:700;
 
font-size:14px;
 
margin:0;
 
padding:11px 0 11px 10px;
 
}
 
 
.breadcrumbs a {
 
color:#FFF;
 
}
 
 
.flash_msg ul {
 
margin:0;
 
padding:0 0 10px;
 
}
 
 
.error_msg {
 
background-color:#FFCFCF;
 
background-image:url("../../images/icons/error_msg.png");
 
border:1px solid #FF9595;
 
color:#C30;
 
}
 
 
.warning_msg {
 
background-color:#FFFBCC;
 
background-image:url("../../images/icons/warning_msg.png");
 
border:1px solid #FFF35E;
 
color:#C69E00;
 
}
 
 
.success_msg {
 
background-color:#D5FFCF;
 
background-image:url("../../images/icons/success_msg.png");
 
border:1px solid #97FF88;
 
color:#090;
 
}
 
 
.notice_msg {
 
background-color:#DCE3FF;
 
background-image:url("../../images/icons/notice_msg.png");
 
border:1px solid #93A8FF;
 
color:#556CB5;
 
}
 
 
.success_msg,.error_msg,.notice_msg,.warning_msg {
 
background-position:10px center;
 
background-repeat:no-repeat;
 
font-size:12px;
 
font-weight:700;
 
min-height:14px;
 
line-height:14px;
 
margin-bottom:0;
 
margin-top:0;
 
display:block;
 
overflow:auto;
 
padding:6px 10px 6px 40px;
 
}
 
 
#msg_close {
 
background:transparent url("../../icons/cross_grey_small.png") no-repeat scroll 0 0;
 
cursor:pointer;
 
height:16px;
 
position:absolute;
 
right:5px;
 
top:5px;
 
width:16px;
 
}
 
 
div#legend_container table,div#legend_choices table {
 
width:auto !important;
 
}
 
 
table#permissions_manage {
 
width:0 !important;
 
}
 
 
table#permissions_manage span.private_repo_msg {
 
font-size:0.8em;
 
opacity:0.6px;
 
}
 
 
table#permissions_manage td.private_repo_msg {
 
font-size:0.8em;
 
}
 
 
table#permissions_manage tr#add_perm_input td {
 
vertical-align:middle;
 
}
 
 
div.gravatar {
 
background-color:#FFF;
 
border:1px solid #D0D0D0;
 
float:left;
 
margin-right:0.7em;
 
padding:2px 2px 0;
 
}
 
 
#header,#content,#footer {
 
min-width:1024px;
 
}
 
 
#content {
 
min-height:100%;
 
clear:both;
 
overflow:hidden;
 
padding:14px 30px;
 
}
 
 
#content div.box div.title div.search {
 
background:url("../../images/title_link.png") no-repeat top left;
 
border-left:1px solid #316293;
 
}
 
 
#content div.box div.title div.search div.input input {
 
border:1px solid #316293;
 
}
 
 
#content div.box div.title div.search div.button input.ui-state-default {
 
background:#4e85bb url("../../images/button_highlight.png") repeat-x;
 
border:1px solid #316293;
 
border-left:none;
 
color:#FFF;
 
}
 
 
#content div.box div.title div.search div.button input.ui-state-hover {
 
background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
 
border:1px solid #316293;
 
border-left:none;
 
color:#FFF;
 
}
 
 
#content div.box div.form div.fields div.field div.highlight .ui-state-default {
 
background:#4e85bb url("../../images/button_highlight.png") repeat-x;
 
border-top:1px solid #5c91a4;
 
border-left:1px solid #2a6f89;
 
border-right:1px solid #2b7089;
 
border-bottom:1px solid #1a6480;
 
color:#fff;
 
}
 
 
#content div.box div.form div.fields div.field div.highlight .ui-state-hover {
 
background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
 
border-top:1px solid #78acbf;
 
border-left:1px solid #34819e;
 
border-right:1px solid #35829f;
 
border-bottom:1px solid #257897;
 
color:#fff;
 
}
 
 
ins,div.options a:hover {
 
text-decoration:none;
 
}
 
 
img,#header #header-inner #quick li a:hover span.normal,#header #header-inner #quick li ul li.last,#content div.box div.form div.fields div.field div.textarea table td table td a,#clone_url {
 
border:none;
 
}
 
 
img.icon,.right .merge img {
 
vertical-align:bottom;
 
}
 
 
#header ul#logged-user,#content div.box div.title ul.links,#content div.box div.message div.dismiss,#content div.box div.traffic div.legend ul {
 
float:right;
 
margin:0;
 
padding:0;
 
}
 
 
#header #header-inner #home,#header #header-inner #logo,#content div.box ul.left,#content div.box ol.left,#content div.box div.pagination-left,div#commit_history,div#legend_data,div#legend_container,div#legend_choices {
 
float:left;
 
}
 
 
#header #header-inner #quick li:hover ul ul,#header #header-inner #quick li:hover ul ul ul,#header #header-inner #quick li:hover ul ul ul ul,#content #left #menu ul.closed,#content #left #menu li ul.collapsed,.yui-tt-shadow {
 
display:none;
 
}
 
 
#header #header-inner #quick li:hover ul,#header #header-inner #quick li li:hover ul,#header #header-inner #quick li li li:hover ul,#header #header-inner #quick li li li li:hover ul,#content #left #menu ul.opened,#content #left #menu li ul.expanded {
 
display:block;
 
}
 
 
#content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a {
 
color:#bfe3ff;
 
}
 
 
#content div.box ol.lower-roman,#content div.box ol.upper-roman,#content div.box ol.lower-alpha,#content div.box ol.upper-alpha,#content div.box ol.decimal {
 
margin:10px 24px 10px 44px;
 
}
 
 
#content div.box div.form,#content div.box div.table,#content div.box div.traffic {
 
clear:both;
 
overflow:hidden;
 
margin:0;
 
padding:0 20px 10px;
 
}
 
 
#content div.box div.form div.fields,#login div.form,#login div.form div.fields,#register div.form,#register div.form div.fields {
 
clear:both;
 
overflow:hidden;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.label span,#login div.form div.fields div.field div.label span,#register div.form div.fields div.field div.label span {
 
height:1%;
 
display:block;
 
color:#363636;
 
margin:0;
 
padding:2px 0 0;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.error,#login div.form div.fields div.field div.input input.error,#register div.form div.fields div.field div.input input.error {
 
background:#FBE3E4;
 
border-top:1px solid #e1b2b3;
 
border-left:1px solid #e1b2b3;
 
border-right:1px solid #FBC2C4;
 
border-bottom:1px solid #FBC2C4;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.success,#login div.form div.fields div.field div.input input.success,#register div.form div.fields div.field div.input input.success {
 
background:#E6EFC2;
 
border-top:1px solid #cebb98;
 
border-left:1px solid #cebb98;
 
border-right:1px solid #c6d880;
 
border-bottom:1px solid #c6d880;
 
}
 
 
#content div.box-left div.form div.fields div.field div.textarea,#content div.box-right div.form div.fields div.field div.textarea,#content div.box div.form div.fields div.field div.select select,#content div.box table th.selected input,#content div.box table td.selected input {
 
margin:0;
 
}
 
 
#content div.box-left div.form div.fields div.field div.select,#content div.box-left div.form div.fields div.field div.checkboxes,#content div.box-left div.form div.fields div.field div.radios,#content div.box-right div.form div.fields div.field div.select,#content div.box-right div.form div.fields div.field div.checkboxes,#content div.box-right div.form div.fields div.field div.radios{
 
margin:0 0 0 0px !important;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.select,#content div.box div.form div.fields div.field div.checkboxes,#content div.box div.form div.fields div.field div.radios {
 
margin:0 0 0 200px;
 
padding:0;
 
}
 
 
 
#content div.box div.form div.fields div.field div.select a:hover,#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover,#content div.box div.action a:hover {
 
color:#000;
 
text-decoration:none;
 
}
 
 
#content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus,#content div.box div.action a.ui-selectmenu-focus {
 
border:1px solid #666;
 
}
 
 
#content div.box div.form div.fields div.field div.checkboxes div.checkbox,#content div.box div.form div.fields div.field div.radios div.radio {
 
clear:both;
 
overflow:hidden;
 
margin:0;
 
padding:8px 0 2px;
 
}
 
 
#content div.box div.form div.fields div.field div.checkboxes div.checkbox input,#content div.box div.form div.fields div.field div.radios div.radio input {
 
float:left;
 
margin:0;
 
}
 
 
#content div.box div.form div.fields div.field div.checkboxes div.checkbox label,#content div.box div.form div.fields div.field div.radios div.radio label {
 
height:1%;
 
display:block;
 
float:left;
 
margin:2px 0 0 4px;
 
}
 
 
div.form div.fields div.field div.button input,#content div.box div.form div.fields div.buttons input,div.form div.fields div.buttons input,#content div.box div.action div.button input {
 
color:#000;
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
font-weight:700;
 
margin:0;
 
}
 
 
div.form div.fields div.field div.button .ui-state-default,#content div.box div.form div.fields div.buttons input.ui-state-default {
 
background:#e5e3e3 url("../images/button.png") repeat-x;
 
border-top:1px solid #DDD;
 
border-left:1px solid #c6c6c6;
 
border-right:1px solid #DDD;
 
border-bottom:1px solid #c6c6c6;
 
color:#515151;
 
outline:none;
 
margin:0;
 
padding:6px 12px;
 
}
 
 
div.form div.fields div.field div.button .ui-state-hover,#content div.box div.form div.fields div.buttons input.ui-state-hover {
 
background:#b4b4b4 url("../images/button_selected.png") repeat-x;
 
border-top:1px solid #ccc;
 
border-left:1px solid #bebebe;
 
border-right:1px solid #b1b1b1;
 
border-bottom:1px solid #afafaf;
 
color:#515151;
 
outline:none;
 
margin:0;
 
padding:6px 12px;
 
}
 
 
div.form div.fields div.field div.highlight,#content div.box div.form div.fields div.buttons div.highlight {
 
display:inline;
 
}
 
 
#content div.box div.form div.fields div.buttons,div.form div.fields div.buttons {
 
margin:10px 0 0 200px;
 
padding:0;
 
}
 
 
#content div.box-left div.form div.fields div.buttons,#content div.box-right div.form div.fields div.buttons,div.box-left div.form div.fields div.buttons,div.box-right div.form div.fields div.buttons {
 
margin:10px 0 0;
 
}
 
 
#content div.box table td.user,#content div.box table td.address {
 
width:10%;
 
text-align:center;
 
}
 
 
#content div.box div.action div.button,#login div.form div.fields div.field div.input div.link,#register div.form div.fields div.field div.input div.link {
 
text-align:right;
 
margin:6px 0 0;
 
padding:0;
 
}
 
 
#content div.box div.action div.button input.ui-state-default,#login div.form div.fields div.buttons input.ui-state-default,#register div.form div.fields div.buttons input.ui-state-default {
 
background:#e5e3e3 url("../images/button.png") repeat-x;
 
border-top:1px solid #DDD;
 
border-left:1px solid #c6c6c6;
 
border-right:1px solid #DDD;
 
border-bottom:1px solid #c6c6c6;
 
color:#515151;
 
margin:0;
 
padding:6px 12px;
 
}
 
 
#content div.box div.action div.button input.ui-state-hover,#login div.form div.fields div.buttons input.ui-state-hover,#register div.form div.fields div.buttons input.ui-state-hover {
 
background:#b4b4b4 url("../images/button_selected.png") repeat-x;
 
border-top:1px solid #ccc;
 
border-left:1px solid #bebebe;
 
border-right:1px solid #b1b1b1;
 
border-bottom:1px solid #afafaf;
 
color:#515151;
 
margin:0;
 
padding:6px 12px;
 
}
 
 
#content div.box div.pagination div.results,#content div.box div.pagination-wh div.results {
 
text-align:left;
 
float:left;
 
margin:0;
 
padding:0;
 
}
 
 
#content div.box div.pagination div.results span,#content div.box div.pagination-wh div.results span {
 
height:1%;
 
display:block;
 
float:left;
 
background:#ebebeb url("../images/pager.png") repeat-x;
 
border-top:1px solid #dedede;
 
border-left:1px solid #cfcfcf;
 
border-right:1px solid #c4c4c4;
 
border-bottom:1px solid #c4c4c4;
 
color:#4A4A4A;
 
font-weight:700;
 
margin:0;
 
padding:6px 8px;
 
}
 
 
#content div.box div.pagination ul.pager li.disabled,#content div.box div.pagination-wh a.disabled {
 
color:#B4B4B4;
 
padding:6px;
 
}
 
 
#login,#register {
 
width:420px;
 
margin:10% auto 0;
 
padding:0;
 
}
 
 
#login div.color,#register div.color {
 
clear:both;
 
overflow:hidden;
 
background:#FFF;
 
margin:10px auto 0;
 
padding:3px 3px 3px 0;
 
}
 
 
#login div.color a,#register div.color a {
 
width:20px;
 
height:20px;
 
display:block;
 
float:left;
 
margin:0 0 0 3px;
 
padding:0;
 
}
 
 
#login div.title h5,#register div.title h5 {
 
color:#fff;
 
margin:10px;
 
padding:0;
 
}
 
 
#login div.form div.fields div.field,#register div.form div.fields div.field {
 
clear:both;
 
overflow:hidden;
 
margin:0;
 
padding:0 0 10px;
 
}
 
 
#login div.form div.fields div.field span.error-message,#register div.form div.fields div.field span.error-message {
 
height:1%;
 
display:block;
 
color:red;
 
margin:8px 0 0;
 
padding:0;
 
}
 
 
#login div.form div.fields div.field div.label label,#register div.form div.fields div.field div.label label {
 
color:#000;
 
font-weight:700;
 
}
 
 
#login div.form div.fields div.field div.input,#register div.form div.fields div.field div.input {
 
float:left;
 
margin:0;
 
padding:0;
 
}
 
 
#login div.form div.fields div.field div.checkbox,#register div.form div.fields div.field div.checkbox {
 
margin:0 0 0 184px;
 
padding:0;
 
}
 
 
#login div.form div.fields div.field div.checkbox label,#register div.form div.fields div.field div.checkbox label {
 
color:#565656;
 
font-weight:700;
 
}
 
 
#login div.form div.fields div.buttons input,#register div.form div.fields div.buttons input {
 
color:#000;
 
font-size:1em;
 
font-weight:700;
 
font-family:Verdana, Helvetica, Sans-Serif;
 
margin:0;
 
}
 
 
#changeset_content .container .wrapper,#graph_content .container .wrapper {
 
width:600px;
 
}
 
 
#changeset_content .container .left,#graph_content .container .left {
 
float:left;
 
width:70%;
 
padding-left:5px;
 
}
 
 
#changeset_content .container .left .date,.ac .match {
 
font-weight:700;
 
padding-top: 5px;
 
padding-bottom:5px;
 
}
 
 
div#legend_container table td,div#legend_choices table td {
 
border:none !important;
 
height:20px !important;
 
padding:0 !important;
 
}
 
 
#q_filter{
 
border:0 none;
 
color:#AAAAAA;
 
margin-bottom:-4px;
 
margin-top:-4px;
 
padding-left:3px;
 
}
 
rhodecode/templates/admin/permissions/permissions.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Permissions administration')} - ${c.rhodecode_name}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_('Admin'),h.url('admin_home'))} 
 
    &raquo;
 
    ${_('Permissions')}    
 
</%def>
 

	
 
<%def name="page_nav()">
 
	${self.menu('admin')}
 
</%def>
 

	
 
<%def name="main()">
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}       
 
    </div>
 
    <h3>${_('Default permissions')}</h3>
 
    ${h.form(url('permission', id='default'),method='put')}
 
    <div class="form">
 
        <!-- fields -->
 
        <div class="fields">
 
            <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="anonymous">${_('Anonymous access')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    <div class="checkbox">
 
                        ${h.checkbox('anonymous',True)}
 
                    </div>
 
                </div>
 
            </div>        
 
			<div class="field">
 
				<div class="label label-select">
 
					<label for="default_perm">${_('Repository permission')}:</label>
 
				</div>
 
				<div class="select">
 
					${h.select('default_perm','',c.perms_choices)}
 
				
 
		                ${h.checkbox('overwrite_default','true')}
 
		                <label for="overwrite_default">
 
		                <span class="tooltip" 
 
		                tooltip_title="${h.tooltip(_('All default permissions on each repository will be reset to choosen permission, note that all custom default permission on repositories will be lost'))}">
 
		                ${_('overwrite existing settings')}</span> </label>
 
				</div>		                
 
			</div>   
 
			<div class="field">
 
		        <div class="label">
 
		            <label for="default_register">${_('Registration')}:</label>
 
		        </div>
 
				<div class="select">
 
					${h.select('default_register','',c.register_choices)}
 
				</div>
 
			</div> 		
 
             <div class="field">
 
                <div class="label">
 
                    <label for="default_create">${_('Repository creation')}:</label>
 
                </div>
 
				<div class="select">
 
					${h.select('default_create','',c.create_choices)}
 
				</div>
 
             </div>	
 
				        
 
	        <div class="buttons">
 
	        ${h.submit('set','set',class_="ui-button ui-widget ui-state-default ui-corner-all")}
 
	        </div>	                                                               
 
        </div>
 
    </div>  
 
    ${h.end_form()}
 
    ##LDAP
 
    <h3>${_('LDAP settings')}</h3>
 
    ${h.form(url('permissions_ldap',id_iser='default'),method='put')}
 
    <div class="form">
 
        <div class="fields">
 

	
 
            <div class="field">
 
                <div class="label label-checkbox"><label for="ldap_active">${_('Enable ldap')}</label></div>
 
	            <div class="checkboxes"><div class="checkbox">${h.checkbox('ldap_active',True,class_='small')}</div></div>
 
            </div>
 
            <div class="field">
 
                <div class="label"><label for="ldap_host">${_('Host')}</label></div>
 
                <div class="input">${h.text('ldap_host',class_='small')}</div>
 
            </div>
 
            <div class="field">
 
                <div class="label"><label for="ldap_port">${_('Port')}</label></div>
 
                <div class="input">${h.text('ldap_port',class_='small')}</div>
 
            </div>
 
            <div class="field">
 
                <div class="label label-checkbox"><label for="ldap_ldaps">${_('LDAPS')}</label></div>
 
                <div class="label label-checkbox"><label for="ldap_ldaps">${_('Enable LDAPS')}</label></div>
 
                <div class="checkboxes"><div class="checkbox">${h.checkbox('ldap_ldaps',True,class_='small')}</div></div>
 
            </div>
 
            <div class="field">
 
                <div class="label"><label for="ldap_dn_user">${_('Account')}</label></div>
 
                <div class="input">${h.text('ldap_dn_user',class_='small')}</div>
 
            </div>
 
            <div class="field">
 
                <div class="label"><label for="ldap_dn_pass">${_('Password')}</label></div>
 
                <div class="input">${h.password('ldap_dn_pass',class_='small')}</div>
 
            </div>
 
            <div class="field">
 
                <div class="label"><label for="ldap_base_dn">${_('Base DN')}</label></div>
 
                <div class="input">${h.text('ldap_base_dn',class_='small')}</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>    
 

	
 

	
 

	
 

	
 

	
 

	
 
   
rhodecode/templates/admin/repos/repo_edit.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Edit repository')} ${c.repo_info.repo_name} - ${c.rhodecode_name}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_('Admin'),h.url('admin_home'))} 
 
    &raquo; 
 
    ${h.link_to(_('Repositories'),h.url('repos'))} 
 
    &raquo;
 
    ${_('edit')} "${c.repo_name}"
 
</%def>
 

	
 
<%def name="page_nav()">
 
	${self.menu('admin')}
 
</%def>
 

	
 
<%def name="main()">
 
<div class="box box-left">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}      
 
    </div>
 
    ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
 
    <div class="form">
 
        <!-- fields -->
 
        <div class="fields">
 
            <div class="field">
 
                <div class="label">
 
                    <label for="repo_name">${_('Name')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('repo_name',class_="medium")}
 
                </div>
 
             </div>
 
            <div class="field">
 
                <div class="label">
 
                    <label for="repo_type">${_('Type')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.select('repo_type','hg',c.backends,class_="medium")}
 
                </div>
 
             </div>             
 
            <div class="field">
 
                <div class="label label-textarea">
 
                    <label for="description">${_('Description')}:</label>
 
                </div>
 
                <div class="textarea text-area editor">
 
                    ${h.textarea('description',cols=23,rows=5)}
 
                </div>
 
            </div>
 
            
 
            <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="private">${_('Private')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('private',value="True")}
 
                </div>
 
            </div>
 
             
 
            <div class="field">
 
                <div class="label">
 
                    <label for="user">${_('Owner')}:</label>
 
                </div>
 
                <div class="input input-small ac">
 
                    <div class="perm_ac">
 
                       ${h.text('user',class_='yui-ac-input')}
 
                       <div id="owner_container"></div>
 
                    </div>
 
                </div>
 
             </div>                
 
             
 
            <div class="field">
 
                <div class="label">
 
                    <label for="input">${_('Permissions')}:</label>
 
                </div>
 
                <div class="input">
 
                    <table id="permissions_manage">
 
                        <tr>
 
                            <td>${_('none')}</td>
 
                            <td>${_('read')}</td>
 
                            <td>${_('write')}</td>
 
                            <td>${_('admin')}</td>
 
                            <td>${_('user')}</td>
 
                            <td></td>
 
                        </tr>
 
                        
 
                        %for r2p in c.repo_info.repo_to_perm:
 
                            %if r2p.user.username =='default' and c.repo_info.private:
 
                                <tr>
 
                                    <td colspan="4">
 
                                        <span class="private_repo_msg">
 
                                        ${_('private repository')}
 
                                        </span>
 
                                    </td>
 
                                    <td class="private_repo_msg">${r2p.user.username}</td>
 
                                </tr>
 
                            %else:
 
                            <tr id="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%s'%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){
 
                                                var tr = YAHOO.util.Dom.get(String(field_id));
 
                                                tr.parentNode.removeChild(tr);},failure:function(o){
 
                                                    alert("${_('Failed to remove user')}");},};
 
                                                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
 

	
 
                        <tr id="add_perm_input">
 
                            <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 class="perm_ac" id="perm_ac">
 
                                    ${h.text('perm_new_user_name',class_='yui-ac-input')}
 
                                    <div id="perm_container"></div>
 
                                </div>
 
                            </td>
 
                            <td></td>
 
                        </tr>
 
                        <tr>
 
                            <td colspan="6">
 
                                <span id="add_perm" class="add_icon" style="cursor: pointer;">
 
                                ${_('Add another user')}
 
                                </span>
 
                            </td>
 
                        </tr>
 
                    </table>             
 
             </div>
 
             
 
            <div class="buttons">
 
              ${h.submit('save','Save',class_="ui-button ui-widget ui-state-default ui-corner-all")}
 
              ${h.reset('reset','Reset',class_="ui-button ui-widget ui-state-default ui-corner-all")}
 
            </div>                                                          
 
        </div>
 
    </div>
 
    </div>    
 
    ${h.end_form()}
 
        <script type="text/javascript">
 
            YAHOO.util.Event.onDOMReady(function(){
 
                var D = YAHOO.util.Dom;
 
                if(!D.hasClass('perm_new_user_name','error')){
 
                    D.setStyle('add_perm_input','display','none');
 
                }
 
                YAHOO.util.Event.addListener('add_perm','click',function(){
 
                    D.setStyle('add_perm_input','display','');
 
                    D.setStyle('add_perm','opacity','0.6');
 
                    D.setStyle('add_perm','cursor','default');
 
                });
 
            });
 
        </script>
 
        <script type="text/javascript">    
 
        YAHOO.example.FnMultipleFields = function(){
 
            var myContacts = ${c.users_array|n}
 
            
 
            // Define a custom search function for the DataSource
 
            var matchNames = function(sQuery) {
 
                // Case insensitive matching
 
                var query = sQuery.toLowerCase(),
 
                    contact,
 
                    i=0,
 
                    l=myContacts.length,
 
                    matches = [];
 
                
 
                // Match against each name of each contact
 
                for(; i<l; i++) {
 
                    contact = myContacts[i];
 
                    if((contact.fname.toLowerCase().indexOf(query) > -1) ||
 
                        (contact.lname.toLowerCase().indexOf(query) > -1) ||
 
                        (contact.nname && (contact.nname.toLowerCase().indexOf(query) > -1))) {
 
                        matches[matches.length] = contact;
 
                    }
 
                }
 
        
 
                return matches;
 
            };
 
        
 
            // Use a FunctionDataSource
 
            var oDS = new YAHOO.util.FunctionDataSource(matchNames);
 
            oDS.responseSchema = {
 
                fields: ["id", "fname", "lname", "nname"]
 
            }
 
        
 
            // Instantiate AutoComplete for perms
 
            var oAC_perms = new YAHOO.widget.AutoComplete("perm_new_user_name", "perm_container", oDS);
 
            oAC_perms.useShadow = false;
 
            oAC_perms.resultTypeList = false;
 
            
 
            // Instantiate AutoComplete for owner
 
            var oAC_owner = new YAHOO.widget.AutoComplete("user", "owner_container", oDS);
 
            oAC_owner.useShadow = false;
 
            oAC_owner.resultTypeList = false;
 
            
 
            
 
            // Custom formatter to highlight the matching letters
 
            var custom_formatter = function(oResultData, sQuery, sResultMatch) {
 
                var query = sQuery.toLowerCase(),
 
                    fname = oResultData.fname,
 
                    lname = oResultData.lname,
 
                    nname = oResultData.nname || "", // Guard against null value
 
                    query = sQuery.toLowerCase(),
 
                    fnameMatchIndex = fname.toLowerCase().indexOf(query),
 
                    lnameMatchIndex = lname.toLowerCase().indexOf(query),
 
                    nnameMatchIndex = nname.toLowerCase().indexOf(query),
 
                    displayfname, displaylname, displaynname;
 
                    
 
                if(fnameMatchIndex > -1) {
 
                    displayfname = highlightMatch(fname, query, fnameMatchIndex);
 
                }
 
                else {
 
                    displayfname = fname;
 
                }
 
        
 
                if(lnameMatchIndex > -1) {
 
                    displaylname = highlightMatch(lname, query, lnameMatchIndex);
 
                }
 
                else {
 
                    displaylname = lname;
 
                }
 
        
 
                if(nnameMatchIndex > -1) {
 
                    displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
 
                }
 
                else {
 
                    displaynname = nname ? "(" + nname + ")" : "";
 
                }
 
        
 
                return displayfname + " " + displaylname + " " + displaynname;
 
                
 
            };
 
            oAC_perms.formatResult = custom_formatter; 
 
            oAC_owner.formatResult = custom_formatter;
 
                            
 
            // Helper function for the formatter
 
            var highlightMatch = function(full, snippet, matchindex) {
 
                return full.substring(0, matchindex) + 
 
                        "<span class='match'>" + 
 
                        full.substr(matchindex, snippet.length) + 
 
                        "</span>" +
 
                        full.substring(matchindex + snippet.length);
 
            };
 
        
 
            var myHandler = function(sType, aArgs) {
 
                var myAC = aArgs[0]; // reference back to the AC instance
 
                var elLI = aArgs[1]; // reference to the selected LI element
 
                var oData = aArgs[2]; // object literal of selected item's result data
 
                myAC.getInputEl().value = oData.nname;
 
            };
 

	
 
            oAC_perms.itemSelectEvent.subscribe(myHandler);
 
            oAC_owner.itemSelectEvent.subscribe(myHandler);
 
            
 
            return {
 
                oDS: oDS,
 
                oAC_perms: oAC_perms,
 
                oAC_owner: oAC_owner, 
 
            };
 
        }();
 
            
 
        </script>      
 

	
 
</div>
 

	
 
<div class="box box-right">
 
    <div class="title">
 
        <h5>${_('Administration')}</h5>    
 
    </div>
 
    
 
    <div class="form">
 
    
 
        <h3>${_('Reset statistics')}</h3>
 
        <h3>${_('Reset cache')}</h3>
 
        <h3>${_('Delete')}</h3>
 
        <h3>${_('Statistics')}</h3>
 
        
 
        ${h.form(url('repo_stats', repo_name=c.repo_info.repo_name),method='delete')}
 
        <div class="form">
 
           <div class="fields">
 
               ${h.submit('reset_stats_%s' % c.repo_info.repo_name,_('Reset current statistics'),class_="refresh_icon action_button",onclick="return confirm('Confirm to remove current statistics');")}
 
               
 
               <div class="field">
 
               <ul>
 
                    <li>${_('Fetched to rev')}: ${c.stats_revision}/${c.repo_last_rev}</li>
 
                    <li>${_('Percentage of stats gathered')}: ${c.stats_percentage} %</li>
 
               </ul>
 
               </div>
 
               
 
           </div>
 
        </div>                    
 
        ${h.end_form()}
 
        
 
        <h3>${_('Cache')}</h3>
 
        ${h.form(url('repo_cache', repo_name=c.repo_info.repo_name),method='delete')}
 
        <div class="form">
 
           <div class="fields">
 
               ${h.submit('reset_cache_%s' % c.repo_info.repo_name,_('Invalidate repository cache'),class_="refresh_icon action_button",onclick="return confirm('Confirm to invalidate repository cache');")}
 
           </div>
 
        </div>                    
 
        ${h.end_form()}
 
        
 
        
 
    
 
    </div>
 
        <h3>${_('Delete')}</h3>
 
        ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='delete')}
 
        <div class="form">
 
           <div class="fields">
 
               ${h.submit('remove_%s' % c.repo_info.repo_name,_('Remove this repository'),class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
 
           </div>
 
        </div>                    
 
        ${h.end_form()}
 
    
 
</div>
 

	
 

	
 
</%def> 
 
\ No newline at end of file
0 comments (0 inline, 0 general)