# HG changeset patch # User Marcin Kuzminski # Date 2011-01-28 18:46:10 # Node ID 27dba61f07d3bb9c3fcbf20acd11723cf903a1a2 # Parent 1a5c41e4bb02ec8e5532bddd23989b47377bd0ae # Parent f6658c70eeeba2be03f1eb8490e043addf87be86 merge diff --git a/docs/changelog.rst b/docs/changelog.rst --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,13 +13,17 @@ news ---- - implemented #89 Can setup google analytics code from settings menu -- implemented #91 added nicer looking archive urls +- implemented #91 added nicer looking archive urls with more download options + like tags, branches - implemented #44 into file browsing, and added follow branch option +- implemented #102 allowing '.' in username +- implemented #84 downloads can be enabled/disabled for each repository - anonymous repository can be cloned without having to pass default:default into clone url - fixed #90 whoosh indexer can index chooses repositories passed in command line - added dynamic download links in summary. With quick branch/tag selection +- implemented #107 customizable code highlights on code sources fixes ----- @@ -28,6 +32,9 @@ fixes not changing - fixed propagation to error controller on simplehg and simplegit middlewares - fixed error when trying to make a download on empty repository +- fixed ehlo command on mailserver. Was not working on some hosting setups +- fixed problem with '[' chars in commit messages in journal +- fixed #99 Unicode errors, on file node paths with non utf-8 characters - fixed #106 relation issues on databases different than sqlite 1.1.2 (**2011-01-12**) diff --git a/docs/setup.rst b/docs/setup.rst --- a/docs/setup.rst +++ b/docs/setup.rst @@ -234,8 +234,8 @@ pushes and also on large pushes:: proxy_connect_timeout 3600; proxy_send_timeout 3600; proxy_read_timeout 3600; - proxy_buffer_size 8k; - proxy_buffers 8 32k; + proxy_buffer_size 16k; + proxy_buffers 4 16k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; diff --git a/rhodecode/controllers/admin/users_groups.py b/rhodecode/controllers/admin/users_groups.py --- a/rhodecode/controllers/admin/users_groups.py +++ b/rhodecode/controllers/admin/users_groups.py @@ -106,6 +106,41 @@ class UsersGroupsController(BaseControll # method='put') # url('users_group', id=ID) + + users_group_model = UsersGroupModel() + c.users_group = users_group_model.get(id) + c.group_members = [(x.user_id, x.user.username) for x in + c.users_group.members] + + c.available_members = [(x.user_id, x.username) for x in + self.sa.query(User).all()] + users_group_form = UsersGroupForm(edit=True, + old_data=c.users_group.get_dict(), + available_members=[str(x[0]) for x + in c.available_members])() + + try: + form_result = users_group_form.to_python(request.POST) + users_group_model.update(id, form_result) + h.flash(_('updated users group %s') % form_result['users_group_name'], + category='success') + #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa) + except formencode.Invalid, errors: + return htmlfill.render( + render('admin/users_groups/users_group_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 users group %s') \ + % request.POST.get('users_group_name'), category='error') + + return redirect(url('users_groups')) + + + def delete(self, id): """DELETE /users_groups/id: Delete an existing item""" # Forms posted to this method should contain a hidden field: @@ -114,6 +149,14 @@ class UsersGroupsController(BaseControll # h.form(url('users_group', id=ID), # method='delete') # url('users_group', id=ID) + users_group_model = UsersGroupModel() + try: + users_group_model.delete(id) + h.flash(_('successfully deleted users group'), category='success') + except Exception: + h.flash(_('An error occurred during deletion of users group'), + category='error') + return redirect(url('users_groups')) def show(self, id, format='html'): """GET /users_groups/id: Show a specific item""" @@ -122,3 +165,21 @@ class UsersGroupsController(BaseControll def edit(self, id, format='html'): """GET /users_groups/id/edit: Form to edit an existing item""" # url('edit_users_group', id=ID) + + c.users_group = self.sa.query(UsersGroup).get(id) + if not c.users_group: + return redirect(url('users_groups')) + + c.users_group.permissions = {} + c.group_members = [(x.user_id, x.user.username) for x in + c.users_group.members] + c.available_members = [(x.user_id, x.username) for x in + self.sa.query(User).all()] + defaults = c.users_group.get_dict() + + return htmlfill.render( + render('admin/users_groups/users_group_edit.html'), + defaults=defaults, + encoding="UTF-8", + force_defaults=False + ) diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -29,7 +29,7 @@ import datetime from sqlalchemy import * from sqlalchemy.exc import DatabaseError -from sqlalchemy.orm import relation, backref, class_mapper +from sqlalchemy.orm import relationship, backref, class_mapper from sqlalchemy.orm.session import Session from rhodecode.model.meta import Base @@ -107,11 +107,11 @@ class User(Base, BaseModel): 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') + user_log = relationship('UserLog', cascade='all') + user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') - repositories = relation('Repository') - user_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') + repositories = relationship('Repository') + user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') @property def full_contact(self): @@ -150,8 +150,8 @@ class UserLog(Base, BaseModel): action = Column("action", String(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') + user = relationship('User') + repository = relationship('Repository') class UsersGroup(Base, BaseModel): @@ -162,7 +162,7 @@ class UsersGroup(Base, BaseModel): users_group_name = Column("users_group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - members = relation('UsersGroupMember') + members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined") class UsersGroupMember(Base, BaseModel): __tablename__ = 'users_groups_members' @@ -172,8 +172,12 @@ class UsersGroupMember(Base, BaseModel): users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - user = relation('User') - users_group = relation('UsersGroup') + user = relationship('User', lazy='joined') + users_group = relationship('UsersGroup') + + def __init__(self, gr_id, u_id): + self.users_group_id = gr_id + self.user_id = u_id class Repository(Base, BaseModel): __tablename__ = 'repositories' @@ -189,13 +193,13 @@ class Repository(Base, BaseModel): fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) - user = relation('User') - fork = relation('Repository', remote_side=repo_id) - group = relation('Group') - repo_to_perm = relation('RepoToPerm', cascade='all') - stats = relation('Statistics', cascade='all', uselist=False) + user = relationship('User') + fork = relationship('Repository', remote_side=repo_id) + group = relationship('Group') + repo_to_perm = relationship('RepoToPerm', cascade='all') + stats = relationship('Statistics', cascade='all', uselist=False) - repo_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') + repo_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') logs = relation('UserLog', cascade='all') @@ -211,7 +215,7 @@ class Group(Base, BaseModel): group_name = Column("group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) - parent_group = relation('Group', remote_side=group_id) + parent_group = relationship('Group', remote_side=group_id) def __init__(self, group_name='', parent_group=None): @@ -241,9 +245,9 @@ class RepoToPerm(Base, BaseModel): permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - user = relation('User') - permission = relation('Permission') - repository = relation('Repository') + user = relationship('User') + permission = relationship('Permission') + repository = relationship('Repository') class UserToPerm(Base, BaseModel): __tablename__ = 'user_to_perm' @@ -252,8 +256,8 @@ class UserToPerm(Base, BaseModel): user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user = relation('User') - permission = relation('Permission') + user = relationship('User') + permission = relationship('Permission') class UsersGroupToPerm(Base, BaseModel): __tablename__ = 'users_group_to_perm' @@ -262,8 +266,8 @@ class UsersGroupToPerm(Base, BaseModel): users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relation('UsersGroup') - permission = relation('Permission') + users_group = relationship('UsersGroup') + permission = relationship('Permission') class GroupToPerm(Base, BaseModel): __tablename__ = 'group_to_perm' @@ -274,9 +278,9 @@ class GroupToPerm(Base, BaseModel): permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - user = relation('User') - permission = relation('Permission') - group = relation('Group') + user = relationship('User') + permission = relationship('Permission') + group = relationship('Group') class Statistics(Base, BaseModel): __tablename__ = 'statistics' @@ -288,7 +292,7 @@ class Statistics(Base, BaseModel): commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data languages = Column("languages", LargeBinary(), nullable=False)#JSON data - repository = relation('Repository', single_parent=True) + repository = relationship('Repository', single_parent=True) class UserFollowing(Base, BaseModel): __tablename__ = 'user_followings' @@ -301,10 +305,10 @@ class UserFollowing(Base, BaseModel): follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - user = relation('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') - follows_user = relation('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relation('Repository') + follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') + follows_repository = relationship('Repository') class CacheInvalidation(Base, BaseModel): __tablename__ = 'cache_invalidation' diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -26,7 +26,7 @@ import logging import formencode from formencode import All from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \ - Email, Bool, StringBoolean + Email, Bool, StringBoolean, Set from pylons.i18n.translation import _ @@ -99,11 +99,12 @@ def ValidUsersGroup(edit, old_data): if value in ['default']: raise formencode.Invalid(_('Invalid group name'), value, state) #check if group is unique - old_un = None + old_ugname = None if edit: - old_un = UserModel().get(old_data.get('users_group_id')).username + old_ugname = UsersGroupModel()\ + .get(old_data.get('users_group_id')).users_group_name - if old_un != value or not edit: + if old_ugname != value or not edit: if UsersGroupModel().get_by_groupname(value, cache=False, case_insensitive=True): raise formencode.Invalid(_('This users group already exists') , @@ -402,7 +403,7 @@ def UserForm(edit=False, old_data={}): return _UserForm -def UsersGroupForm(edit=False, old_data={}): +def UsersGroupForm(edit=False, old_data={}, available_members=[]): class _UsersGroupForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True @@ -412,6 +413,11 @@ def UsersGroupForm(edit=False, old_data= users_group_active = StringBoolean(if_missing=False) + if edit: + users_group_members = OneOf(available_members, hideList=False, + testValueList=True, + if_missing=None, not_empty=False) + return _UsersGroupForm def RegisterForm(edit=False, old_data={}): diff --git a/rhodecode/model/users_group.py b/rhodecode/model/users_group.py --- a/rhodecode/model/users_group.py +++ b/rhodecode/model/users_group.py @@ -32,9 +32,7 @@ from pylons.i18n.translation import _ from rhodecode.model import BaseModel from rhodecode.model.caching_query import FromCache -from rhodecode.model.db import UsersGroup - -from rhodecode.lib.exceptions import DefaultUserException, UserOwnsReposException +from rhodecode.model.db import UsersGroup, UsersGroupMember from sqlalchemy.exc import DatabaseError @@ -51,7 +49,8 @@ class UsersGroupModel(BaseModel): return users_group.get(users_group_id) - def get_by_groupname(self, users_group_name, cache=False, case_insensitive=False): + def get_by_groupname(self, users_group_name, cache=False, + case_insensitive=False): if case_insensitive: user = self.sa.query(UsersGroup)\ @@ -77,3 +76,36 @@ class UsersGroupModel(BaseModel): self.sa.rollback() raise + def update(self, users_group_id, form_data): + + try: + users_group = self.get(users_group_id, cache=False) + + for k, v in form_data.items(): + if k == 'users_group_members': + users_group.members = [] + self.sa.flush() + members_list = [] + if v: + for u_id in set(v): + members_list.append(UsersGroupMember(users_group_id, + u_id)) + setattr(users_group, 'members', members_list) + setattr(users_group, k, v) + + self.sa.add(users_group) + self.sa.commit() + except: + log.error(traceback.format_exc()) + self.sa.rollback() + raise + + def delete(self, users_group_id): + try: + users_group = self.get(users_group_id, cache=False) + self.sa.delete(users_group) + self.sa.commit() + except: + log.error(traceback.format_exc()) + self.sa.rollback() + raise diff --git a/rhodecode/templates/admin/users_groups/users_group_edit.html b/rhodecode/templates/admin/users_groups/users_group_edit.html --- a/rhodecode/templates/admin/users_groups/users_group_edit.html +++ b/rhodecode/templates/admin/users_groups/users_group_edit.html @@ -0,0 +1,166 @@ +## -*- coding: utf-8 -*- +<%inherit file="/base/base.html"/> + +<%def name="title()"> + ${_('Edit users group')} ${c.users_group.users_group_name} - ${c.rhodecode_name} + + +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} + » + ${h.link_to(_('UsersGroups'),h.url('users_groups'))} + » + ${_('edit')} "${c.users_group.users_group_name}" + + +<%def name="page_nav()"> + ${self.menu('admin')} + + +<%def name="main()"> +
+ +
+ ${self.breadcrumbs()} +
+ + ${h.form(url('users_group', id=c.users_group.users_group_id),method='put', id='edit_users_group')} +
+ +
+
+
+ +
+
+ ${h.text('users_group_name',class_='small')} +
+
+ +
+
+ +
+
+ ${h.checkbox('users_group_active',value=True)} +
+
+
+
+ +
+
+ + + + +
+
+
+
${_('Group members')}
+ ${h.select('users_group_members',[x[0] for x in c.group_members],c.group_members,multiple=True,size=8,style="min-width:210px")} +
+
+ add +
+ remove +
+
+
${_('Available members')}
+ ${h.select('available_members',[],c.available_members,multiple=True,size=8,style="min-width:210px")} +
+
+
+
+ +
+
+ ${h.submit('save','save',class_="ui-button")} +
+
+
+${h.end_form()} +
+ + + + \ No newline at end of file diff --git a/rhodecode/templates/admin/users_groups/users_groups.html b/rhodecode/templates/admin/users_groups/users_groups.html --- a/rhodecode/templates/admin/users_groups/users_groups.html +++ b/rhodecode/templates/admin/users_groups/users_groups.html @@ -37,7 +37,7 @@ %for cnt,u_group in enumerate(c.users_groups_list): ${h.link_to(u_group.users_group_name,h.url('edit_users_group', id=u_group.users_group_id))} - ${len(u_group.members)} + ${len(u_group.members)} ${h.bool2icon(u_group.users_group_active)} ${h.form(url('users_group', id=u_group.users_group_id),method='delete')} diff --git a/rhodecode/templates/files/files_source.html b/rhodecode/templates/files/files_source.html --- a/rhodecode/templates/files/files_source.html +++ b/rhodecode/templates/files/files_source.html @@ -42,6 +42,37 @@ ${_('File is to big to display')} ${h.link_to(_('show as raw'), h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} %endif + +