@@ -162,6 +162,8 @@ class ReposController(BaseController):
c.repo_last_rev) * 100)
c.users_array = repo_model.get_users_js()
c.users_groups_array = repo_model.get_users_groups_js()
errors.value.update({'user':c.repo_info.user.username})
return htmlfill.render(
render('admin/repos/repo_edit.html'),
@@ -300,6 +302,7 @@ class ReposController(BaseController):
defaults.update({'user':replacement_user})
for p in c.repo_info.repo_to_perm:
defaults.update({'perm_%s' % p.user.username:
#!/usr/bin/env python
# encoding: utf-8
# Model for RhodeCode settings
# Copyright (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
#
# -*- coding: utf-8 -*-
"""
rhodecode.model.settings
~~~~~~~~~~~~~~~~~~~~~~~~
Settings model for RhodeCode
:created on Nov 17, 2010
:author: marcink
:copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING for more details.
# 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
@@ -17,18 +24,12 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
Created on Nov 17, 2010
Model for RhodeCode
from rhodecode.lib import helpers as h
import logging
from rhodecode.model import BaseModel
from rhodecode.model.caching_query import FromCache
from rhodecode.model.db import RhodeCodeSettings
from sqlalchemy.orm import joinedload
log = logging.getLogger(__name__)
@@ -99,7 +99,7 @@
<td>${_('read')}</td>
<td>${_('write')}</td>
<td>${_('admin')}</td>
<td>${_('user')}</td>
<td>${_('member')}</td>
<td></td>
</tr>
@@ -141,13 +141,14 @@
%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>${h.radio('perm_new_member','repository.none')}</td>
<td>${h.radio('perm_new_member','repository.read')}</td>
<td>${h.radio('perm_new_member','repository.write')}</td>
<td>${h.radio('perm_new_member','repository.admin')}</td>
<td class='ac'>
<div class="perm_ac" id="perm_ac">
${h.text('perm_new_user_name',class_='yui-ac-input')}
${h.text('perm_new_member_name',class_='yui-ac-input')}
${h.hidden('perm_new_member_type')}
<div id="perm_container"></div>
</div>
</td>
@@ -156,7 +157,7 @@
<tr>
<td colspan="6">
<span id="add_perm" class="add_icon" style="cursor: pointer;">
${_('Add another user')}
${_('Add another member')}
</span>
@@ -174,7 +175,7 @@
<script type="text/javascript">
YAHOO.util.Event.onDOMReady(function(){
var D = YAHOO.util.Dom;
if(!D.hasClass('perm_new_user_name','error')){
if(!D.hasClass('perm_new_member_name','error')){
D.setStyle('add_perm_input','display','none');
}
YAHOO.util.Event.addListener('add_perm','click',function(){
@@ -186,87 +187,78 @@
</script>
YAHOO.example.FnMultipleFields = function(){
var myContacts = ${c.users_array|n}
var myUsers = ${c.users_array|n};
var myGroups = ${c.users_groups_array|n};
// Define a custom search function for the DataSource
var matchNames = function(sQuery) {
// Define a custom search function for the DataSource of users
var matchUsers = function(sQuery) {
// Case insensitive matching
var query = sQuery.toLowerCase(),
contact,
i=0,
l=myContacts.length,
matches = [];
var query = sQuery.toLowerCase();
var i=0;
var l=myUsers.length;
var matches = [];
// Match against each name of each contact
for(; i<l; i++) {
contact = myContacts[i];
contact = myUsers[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 = {
// Define a custom search function for the DataSource of usersGroups
var matchGroups = function(sQuery) {
var l=myGroups.length;
matched_group = myGroups[i];
if(matched_group.grname.toLowerCase().indexOf(query) > -1) {
matches[matches.length] = matched_group;
//match all
var matchAll = function(sQuery){
u = matchUsers(sQuery);
g = matchGroups(sQuery);
return u.concat(g);
// DataScheme for members
var memberDS = new YAHOO.util.FunctionDataSource(matchAll);
memberDS.responseSchema = {
fields: ["id", "fname", "lname", "nname", "grname", "grmembers"]
// DataScheme for owner
var ownerDS = new YAHOO.util.FunctionDataSource(matchUsers);
ownerDS.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;
var membersAC = new YAHOO.widget.AutoComplete("perm_new_member_name", "perm_container", memberDS);
membersAC.useShadow = false;
membersAC.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;
var ownerAC = new YAHOO.widget.AutoComplete("user", "owner_container", ownerDS);
ownerAC.useShadow = false;
ownerAC.resultTypeList = false;
// Custom formatter to highlight the matching letters
var custom_formatter = function(oResultData, sQuery, sResultMatch) {
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);
displaylname = lname;
if(nnameMatchIndex > -1) {
displaynname = "(" + highlightMatch(nname, query, nnameMatchIndex) + ")";
displaynname = nname ? "(" + nname + ")" : "";
return displayfname + " " + displaylname + " " + displaynname;
oAC_perms.formatResult = custom_formatter;
oAC_owner.formatResult = custom_formatter;
// Helper function for the formatter
// Helper highlight function for the formatter
var highlightMatch = function(full, snippet, matchindex) {
return full.substring(0, matchindex) +
"<span class='match'>" +
@@ -274,21 +266,92 @@
"</span>" +
full.substring(matchindex + snippet.length);
if (oResultData.grname != undefined){
var grname = oResultData.grname;
var grmembers = oResultData.grmembers;
var grnameMatchIndex = grname.toLowerCase().indexOf(query);
var grprefix = "${_('Group')}: ";
var grsuffix = " ("+grmembers+" ${_('members')})";
if (grnameMatchIndex > -1){
return grprefix+highlightMatch(grname,query,grnameMatchIndex)+grsuffix;
return grprefix+oResultData.grname+grsuffix;
else if(oResultData.fname != undefined){
var fname = oResultData.fname,
else{
return '';
membersAC.formatResult = custom_formatter;
ownerAC.formatResult = custom_formatter;
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;
//fill the autocomplete with value
if(oData.nname != undefined){
//users
YUD.get('perm_new_member_type').value = 'user';
//groups
myAC.getInputEl().value = oData.grname;
YUD.get('perm_new_member_type').value = 'users_group';
oAC_perms.itemSelectEvent.subscribe(myHandler);
oAC_owner.itemSelectEvent.subscribe(myHandler);
membersAC.itemSelectEvent.subscribe(myHandler);
ownerAC.itemSelectEvent.subscribe(myHandler);
return {
oDS: oDS,
oAC_perms: oAC_perms,
oAC_owner: oAC_owner,
memberDS: memberDS,
ownerDS: ownerDS,
membersAC: membersAC,
ownerAC: ownerAC,
}();
Status change: