Show More
@@ -13,13 +13,17 b' news' | |||||
13 | ---- |
|
13 | ---- | |
14 |
|
14 | |||
15 | - implemented #89 Can setup google analytics code from settings menu |
|
15 | - implemented #89 Can setup google analytics code from settings menu | |
16 | - implemented #91 added nicer looking archive urls |
|
16 | - implemented #91 added nicer looking archive urls with more download options | |
|
17 | like tags, branches | |||
17 | - implemented #44 into file browsing, and added follow branch option |
|
18 | - implemented #44 into file browsing, and added follow branch option | |
|
19 | - implemented #102 allowing '.' in username | |||
|
20 | - implemented #84 downloads can be enabled/disabled for each repository | |||
18 | - anonymous repository can be cloned without having to pass default:default |
|
21 | - anonymous repository can be cloned without having to pass default:default | |
19 | into clone url |
|
22 | into clone url | |
20 | - fixed #90 whoosh indexer can index chooses repositories passed in command |
|
23 | - fixed #90 whoosh indexer can index chooses repositories passed in command | |
21 | line |
|
24 | line | |
22 | - added dynamic download links in summary. With quick branch/tag selection |
|
25 | - added dynamic download links in summary. With quick branch/tag selection | |
|
26 | - implemented #107 customizable code highlights on code sources | |||
23 |
|
27 | |||
24 | fixes |
|
28 | fixes | |
25 | ----- |
|
29 | ----- | |
@@ -28,6 +32,9 b' fixes' | |||||
28 | not changing |
|
32 | not changing | |
29 | - fixed propagation to error controller on simplehg and simplegit middlewares |
|
33 | - fixed propagation to error controller on simplehg and simplegit middlewares | |
30 | - fixed error when trying to make a download on empty repository |
|
34 | - fixed error when trying to make a download on empty repository | |
|
35 | - fixed ehlo command on mailserver. Was not working on some hosting setups | |||
|
36 | - fixed problem with '[' chars in commit messages in journal | |||
|
37 | - fixed #99 Unicode errors, on file node paths with non utf-8 characters | |||
31 | - fixed #106 relation issues on databases different than sqlite |
|
38 | - fixed #106 relation issues on databases different than sqlite | |
32 |
|
39 | |||
33 | 1.1.2 (**2011-01-12**) |
|
40 | 1.1.2 (**2011-01-12**) |
@@ -234,8 +234,8 b' pushes and also on large pushes::' | |||||
234 | proxy_connect_timeout 3600; |
|
234 | proxy_connect_timeout 3600; | |
235 | proxy_send_timeout 3600; |
|
235 | proxy_send_timeout 3600; | |
236 | proxy_read_timeout 3600; |
|
236 | proxy_read_timeout 3600; | |
237 |
proxy_buffer_size |
|
237 | proxy_buffer_size 16k; | |
238 |
proxy_buffers |
|
238 | proxy_buffers 4 16k; | |
239 | proxy_busy_buffers_size 64k; |
|
239 | proxy_busy_buffers_size 64k; | |
240 | proxy_temp_file_write_size 64k; |
|
240 | proxy_temp_file_write_size 64k; | |
241 |
|
241 |
@@ -106,6 +106,41 b' class UsersGroupsController(BaseControll' | |||||
106 | # method='put') |
|
106 | # method='put') | |
107 | # url('users_group', id=ID) |
|
107 | # url('users_group', id=ID) | |
108 |
|
108 | |||
|
109 | ||||
|
110 | users_group_model = UsersGroupModel() | |||
|
111 | c.users_group = users_group_model.get(id) | |||
|
112 | c.group_members = [(x.user_id, x.user.username) for x in | |||
|
113 | c.users_group.members] | |||
|
114 | ||||
|
115 | c.available_members = [(x.user_id, x.username) for x in | |||
|
116 | self.sa.query(User).all()] | |||
|
117 | users_group_form = UsersGroupForm(edit=True, | |||
|
118 | old_data=c.users_group.get_dict(), | |||
|
119 | available_members=[str(x[0]) for x | |||
|
120 | in c.available_members])() | |||
|
121 | ||||
|
122 | try: | |||
|
123 | form_result = users_group_form.to_python(request.POST) | |||
|
124 | users_group_model.update(id, form_result) | |||
|
125 | h.flash(_('updated users group %s') % form_result['users_group_name'], | |||
|
126 | category='success') | |||
|
127 | #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa) | |||
|
128 | except formencode.Invalid, errors: | |||
|
129 | return htmlfill.render( | |||
|
130 | render('admin/users_groups/users_group_edit.html'), | |||
|
131 | defaults=errors.value, | |||
|
132 | errors=errors.error_dict or {}, | |||
|
133 | prefix_error=False, | |||
|
134 | encoding="UTF-8") | |||
|
135 | except Exception: | |||
|
136 | log.error(traceback.format_exc()) | |||
|
137 | h.flash(_('error occurred during update of users group %s') \ | |||
|
138 | % request.POST.get('users_group_name'), category='error') | |||
|
139 | ||||
|
140 | return redirect(url('users_groups')) | |||
|
141 | ||||
|
142 | ||||
|
143 | ||||
109 | def delete(self, id): |
|
144 | def delete(self, id): | |
110 | """DELETE /users_groups/id: Delete an existing item""" |
|
145 | """DELETE /users_groups/id: Delete an existing item""" | |
111 | # Forms posted to this method should contain a hidden field: |
|
146 | # Forms posted to this method should contain a hidden field: | |
@@ -114,6 +149,14 b' class UsersGroupsController(BaseControll' | |||||
114 | # h.form(url('users_group', id=ID), |
|
149 | # h.form(url('users_group', id=ID), | |
115 | # method='delete') |
|
150 | # method='delete') | |
116 | # url('users_group', id=ID) |
|
151 | # url('users_group', id=ID) | |
|
152 | users_group_model = UsersGroupModel() | |||
|
153 | try: | |||
|
154 | users_group_model.delete(id) | |||
|
155 | h.flash(_('successfully deleted users group'), category='success') | |||
|
156 | except Exception: | |||
|
157 | h.flash(_('An error occurred during deletion of users group'), | |||
|
158 | category='error') | |||
|
159 | return redirect(url('users_groups')) | |||
117 |
|
160 | |||
118 | def show(self, id, format='html'): |
|
161 | def show(self, id, format='html'): | |
119 | """GET /users_groups/id: Show a specific item""" |
|
162 | """GET /users_groups/id: Show a specific item""" | |
@@ -122,3 +165,21 b' class UsersGroupsController(BaseControll' | |||||
122 | def edit(self, id, format='html'): |
|
165 | def edit(self, id, format='html'): | |
123 | """GET /users_groups/id/edit: Form to edit an existing item""" |
|
166 | """GET /users_groups/id/edit: Form to edit an existing item""" | |
124 | # url('edit_users_group', id=ID) |
|
167 | # url('edit_users_group', id=ID) | |
|
168 | ||||
|
169 | c.users_group = self.sa.query(UsersGroup).get(id) | |||
|
170 | if not c.users_group: | |||
|
171 | return redirect(url('users_groups')) | |||
|
172 | ||||
|
173 | c.users_group.permissions = {} | |||
|
174 | c.group_members = [(x.user_id, x.user.username) for x in | |||
|
175 | c.users_group.members] | |||
|
176 | c.available_members = [(x.user_id, x.username) for x in | |||
|
177 | self.sa.query(User).all()] | |||
|
178 | defaults = c.users_group.get_dict() | |||
|
179 | ||||
|
180 | return htmlfill.render( | |||
|
181 | render('admin/users_groups/users_group_edit.html'), | |||
|
182 | defaults=defaults, | |||
|
183 | encoding="UTF-8", | |||
|
184 | force_defaults=False | |||
|
185 | ) |
@@ -29,7 +29,7 b' import datetime' | |||||
29 |
|
29 | |||
30 | from sqlalchemy import * |
|
30 | from sqlalchemy import * | |
31 | from sqlalchemy.exc import DatabaseError |
|
31 | from sqlalchemy.exc import DatabaseError | |
32 | from sqlalchemy.orm import relation, backref, class_mapper |
|
32 | from sqlalchemy.orm import relationship, backref, class_mapper | |
33 | from sqlalchemy.orm.session import Session |
|
33 | from sqlalchemy.orm.session import Session | |
34 |
|
34 | |||
35 | from rhodecode.model.meta import Base |
|
35 | from rhodecode.model.meta import Base | |
@@ -107,11 +107,11 b' class User(Base, BaseModel):' | |||||
107 | last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) |
|
107 | last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) | |
108 | is_ldap = Column("is_ldap", Boolean(), nullable=False, unique=None, default=False) |
|
108 | is_ldap = Column("is_ldap", Boolean(), nullable=False, unique=None, default=False) | |
109 |
|
109 | |||
110 | user_log = relation('UserLog', cascade='all') |
|
110 | user_log = relationship('UserLog', cascade='all') | |
111 | user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') |
|
111 | user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') | |
112 |
|
112 | |||
113 | repositories = relation('Repository') |
|
113 | repositories = relationship('Repository') | |
114 | user_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') |
|
114 | user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') | |
115 |
|
115 | |||
116 | @property |
|
116 | @property | |
117 | def full_contact(self): |
|
117 | def full_contact(self): | |
@@ -150,8 +150,8 b' class UserLog(Base, BaseModel):' | |||||
150 | action = Column("action", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
150 | action = Column("action", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) | |
151 | action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) |
|
151 | action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) | |
152 |
|
152 | |||
153 | user = relation('User') |
|
153 | user = relationship('User') | |
154 | repository = relation('Repository') |
|
154 | repository = relationship('Repository') | |
155 |
|
155 | |||
156 |
|
156 | |||
157 | class UsersGroup(Base, BaseModel): |
|
157 | class UsersGroup(Base, BaseModel): | |
@@ -162,7 +162,7 b' class UsersGroup(Base, BaseModel):' | |||||
162 | users_group_name = Column("users_group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) |
|
162 | users_group_name = Column("users_group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) | |
163 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) |
|
163 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) | |
164 |
|
164 | |||
165 | members = relation('UsersGroupMember') |
|
165 | members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined") | |
166 |
|
166 | |||
167 | class UsersGroupMember(Base, BaseModel): |
|
167 | class UsersGroupMember(Base, BaseModel): | |
168 | __tablename__ = 'users_groups_members' |
|
168 | __tablename__ = 'users_groups_members' | |
@@ -172,8 +172,12 b' class UsersGroupMember(Base, BaseModel):' | |||||
172 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
172 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
173 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
173 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
174 |
|
174 | |||
175 | user = relation('User') |
|
175 | user = relationship('User', lazy='joined') | |
176 | users_group = relation('UsersGroup') |
|
176 | users_group = relationship('UsersGroup') | |
|
177 | ||||
|
178 | def __init__(self, gr_id, u_id): | |||
|
179 | self.users_group_id = gr_id | |||
|
180 | self.user_id = u_id | |||
177 |
|
181 | |||
178 | class Repository(Base, BaseModel): |
|
182 | class Repository(Base, BaseModel): | |
179 | __tablename__ = 'repositories' |
|
183 | __tablename__ = 'repositories' | |
@@ -189,13 +193,13 b' class Repository(Base, BaseModel):' | |||||
189 | fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) |
|
193 | fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) | |
190 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) |
|
194 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) | |
191 |
|
195 | |||
192 | user = relation('User') |
|
196 | user = relationship('User') | |
193 | fork = relation('Repository', remote_side=repo_id) |
|
197 | fork = relationship('Repository', remote_side=repo_id) | |
194 | group = relation('Group') |
|
198 | group = relationship('Group') | |
195 | repo_to_perm = relation('RepoToPerm', cascade='all') |
|
199 | repo_to_perm = relationship('RepoToPerm', cascade='all') | |
196 | stats = relation('Statistics', cascade='all', uselist=False) |
|
200 | stats = relationship('Statistics', cascade='all', uselist=False) | |
197 |
|
201 | |||
198 | repo_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') |
|
202 | repo_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') | |
199 |
|
203 | |||
200 | logs = relation('UserLog', cascade='all') |
|
204 | logs = relation('UserLog', cascade='all') | |
201 |
|
205 | |||
@@ -211,7 +215,7 b' class Group(Base, BaseModel):' | |||||
211 | group_name = Column("group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) |
|
215 | group_name = Column("group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) | |
212 | group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) |
|
216 | group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) | |
213 |
|
217 | |||
214 | parent_group = relation('Group', remote_side=group_id) |
|
218 | parent_group = relationship('Group', remote_side=group_id) | |
215 |
|
219 | |||
216 |
|
220 | |||
217 | def __init__(self, group_name='', parent_group=None): |
|
221 | def __init__(self, group_name='', parent_group=None): | |
@@ -241,9 +245,9 b' class RepoToPerm(Base, BaseModel):' | |||||
241 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
245 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
242 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
246 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
243 |
|
247 | |||
244 | user = relation('User') |
|
248 | user = relationship('User') | |
245 | permission = relation('Permission') |
|
249 | permission = relationship('Permission') | |
246 | repository = relation('Repository') |
|
250 | repository = relationship('Repository') | |
247 |
|
251 | |||
248 | class UserToPerm(Base, BaseModel): |
|
252 | class UserToPerm(Base, BaseModel): | |
249 | __tablename__ = 'user_to_perm' |
|
253 | __tablename__ = 'user_to_perm' | |
@@ -252,8 +256,8 b' class UserToPerm(Base, BaseModel):' | |||||
252 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
256 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
253 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
257 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
254 |
|
258 | |||
255 | user = relation('User') |
|
259 | user = relationship('User') | |
256 | permission = relation('Permission') |
|
260 | permission = relationship('Permission') | |
257 |
|
261 | |||
258 | class UsersGroupToPerm(Base, BaseModel): |
|
262 | class UsersGroupToPerm(Base, BaseModel): | |
259 | __tablename__ = 'users_group_to_perm' |
|
263 | __tablename__ = 'users_group_to_perm' | |
@@ -262,8 +266,8 b' class UsersGroupToPerm(Base, BaseModel):' | |||||
262 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
266 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
263 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
267 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
264 |
|
268 | |||
265 | users_group = relation('UsersGroup') |
|
269 | users_group = relationship('UsersGroup') | |
266 | permission = relation('Permission') |
|
270 | permission = relationship('Permission') | |
267 |
|
271 | |||
268 | class GroupToPerm(Base, BaseModel): |
|
272 | class GroupToPerm(Base, BaseModel): | |
269 | __tablename__ = 'group_to_perm' |
|
273 | __tablename__ = 'group_to_perm' | |
@@ -274,9 +278,9 b' class GroupToPerm(Base, BaseModel):' | |||||
274 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
278 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
275 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) |
|
279 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) | |
276 |
|
280 | |||
277 | user = relation('User') |
|
281 | user = relationship('User') | |
278 | permission = relation('Permission') |
|
282 | permission = relationship('Permission') | |
279 | group = relation('Group') |
|
283 | group = relationship('Group') | |
280 |
|
284 | |||
281 | class Statistics(Base, BaseModel): |
|
285 | class Statistics(Base, BaseModel): | |
282 | __tablename__ = 'statistics' |
|
286 | __tablename__ = 'statistics' | |
@@ -288,7 +292,7 b' class Statistics(Base, BaseModel):' | |||||
288 | commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data |
|
292 | commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data | |
289 | languages = Column("languages", LargeBinary(), nullable=False)#JSON data |
|
293 | languages = Column("languages", LargeBinary(), nullable=False)#JSON data | |
290 |
|
294 | |||
291 | repository = relation('Repository', single_parent=True) |
|
295 | repository = relationship('Repository', single_parent=True) | |
292 |
|
296 | |||
293 | class UserFollowing(Base, BaseModel): |
|
297 | class UserFollowing(Base, BaseModel): | |
294 | __tablename__ = 'user_followings' |
|
298 | __tablename__ = 'user_followings' | |
@@ -301,10 +305,10 b' class UserFollowing(Base, BaseModel):' | |||||
301 | follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) |
|
305 | follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) | |
302 | follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) |
|
306 | follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) | |
303 |
|
307 | |||
304 | user = relation('User', primaryjoin='User.user_id==UserFollowing.user_id') |
|
308 | user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') | |
305 |
|
309 | |||
306 | follows_user = relation('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') |
|
310 | follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') | |
307 | follows_repository = relation('Repository') |
|
311 | follows_repository = relationship('Repository') | |
308 |
|
312 | |||
309 | class CacheInvalidation(Base, BaseModel): |
|
313 | class CacheInvalidation(Base, BaseModel): | |
310 | __tablename__ = 'cache_invalidation' |
|
314 | __tablename__ = 'cache_invalidation' |
@@ -26,7 +26,7 b' import logging' | |||||
26 | import formencode |
|
26 | import formencode | |
27 | from formencode import All |
|
27 | from formencode import All | |
28 | from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \ |
|
28 | from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \ | |
29 | Email, Bool, StringBoolean |
|
29 | Email, Bool, StringBoolean, Set | |
30 |
|
30 | |||
31 | from pylons.i18n.translation import _ |
|
31 | from pylons.i18n.translation import _ | |
32 |
|
32 | |||
@@ -99,11 +99,12 b' def ValidUsersGroup(edit, old_data):' | |||||
99 | if value in ['default']: |
|
99 | if value in ['default']: | |
100 | raise formencode.Invalid(_('Invalid group name'), value, state) |
|
100 | raise formencode.Invalid(_('Invalid group name'), value, state) | |
101 | #check if group is unique |
|
101 | #check if group is unique | |
102 | old_un = None |
|
102 | old_ugname = None | |
103 | if edit: |
|
103 | if edit: | |
104 | old_un = UserModel().get(old_data.get('users_group_id')).username |
|
104 | old_ugname = UsersGroupModel()\ | |
|
105 | .get(old_data.get('users_group_id')).users_group_name | |||
105 |
|
106 | |||
106 | if old_un != value or not edit: |
|
107 | if old_ugname != value or not edit: | |
107 | if UsersGroupModel().get_by_groupname(value, cache=False, |
|
108 | if UsersGroupModel().get_by_groupname(value, cache=False, | |
108 | case_insensitive=True): |
|
109 | case_insensitive=True): | |
109 | raise formencode.Invalid(_('This users group already exists') , |
|
110 | raise formencode.Invalid(_('This users group already exists') , | |
@@ -402,7 +403,7 b' def UserForm(edit=False, old_data={}):' | |||||
402 | return _UserForm |
|
403 | return _UserForm | |
403 |
|
404 | |||
404 |
|
405 | |||
405 | def UsersGroupForm(edit=False, old_data={}): |
|
406 | def UsersGroupForm(edit=False, old_data={}, available_members=[]): | |
406 | class _UsersGroupForm(formencode.Schema): |
|
407 | class _UsersGroupForm(formencode.Schema): | |
407 | allow_extra_fields = True |
|
408 | allow_extra_fields = True | |
408 | filter_extra_fields = True |
|
409 | filter_extra_fields = True | |
@@ -412,6 +413,11 b' def UsersGroupForm(edit=False, old_data=' | |||||
412 |
|
413 | |||
413 | users_group_active = StringBoolean(if_missing=False) |
|
414 | users_group_active = StringBoolean(if_missing=False) | |
414 |
|
415 | |||
|
416 | if edit: | |||
|
417 | users_group_members = OneOf(available_members, hideList=False, | |||
|
418 | testValueList=True, | |||
|
419 | if_missing=None, not_empty=False) | |||
|
420 | ||||
415 | return _UsersGroupForm |
|
421 | return _UsersGroupForm | |
416 |
|
422 | |||
417 | def RegisterForm(edit=False, old_data={}): |
|
423 | def RegisterForm(edit=False, old_data={}): |
@@ -32,9 +32,7 b' from pylons.i18n.translation import _' | |||||
32 |
|
32 | |||
33 | from rhodecode.model import BaseModel |
|
33 | from rhodecode.model import BaseModel | |
34 | from rhodecode.model.caching_query import FromCache |
|
34 | from rhodecode.model.caching_query import FromCache | |
35 | from rhodecode.model.db import UsersGroup |
|
35 | from rhodecode.model.db import UsersGroup, UsersGroupMember | |
36 |
|
||||
37 | from rhodecode.lib.exceptions import DefaultUserException, UserOwnsReposException |
|
|||
38 |
|
36 | |||
39 | from sqlalchemy.exc import DatabaseError |
|
37 | from sqlalchemy.exc import DatabaseError | |
40 |
|
38 | |||
@@ -51,7 +49,8 b' class UsersGroupModel(BaseModel):' | |||||
51 | return users_group.get(users_group_id) |
|
49 | return users_group.get(users_group_id) | |
52 |
|
50 | |||
53 |
|
51 | |||
54 |
def get_by_groupname(self, users_group_name, cache=False, |
|
52 | def get_by_groupname(self, users_group_name, cache=False, | |
|
53 | case_insensitive=False): | |||
55 |
|
54 | |||
56 | if case_insensitive: |
|
55 | if case_insensitive: | |
57 | user = self.sa.query(UsersGroup)\ |
|
56 | user = self.sa.query(UsersGroup)\ | |
@@ -77,3 +76,36 b' class UsersGroupModel(BaseModel):' | |||||
77 | self.sa.rollback() |
|
76 | self.sa.rollback() | |
78 | raise |
|
77 | raise | |
79 |
|
78 | |||
|
79 | def update(self, users_group_id, form_data): | |||
|
80 | ||||
|
81 | try: | |||
|
82 | users_group = self.get(users_group_id, cache=False) | |||
|
83 | ||||
|
84 | for k, v in form_data.items(): | |||
|
85 | if k == 'users_group_members': | |||
|
86 | users_group.members = [] | |||
|
87 | self.sa.flush() | |||
|
88 | members_list = [] | |||
|
89 | if v: | |||
|
90 | for u_id in set(v): | |||
|
91 | members_list.append(UsersGroupMember(users_group_id, | |||
|
92 | u_id)) | |||
|
93 | setattr(users_group, 'members', members_list) | |||
|
94 | setattr(users_group, k, v) | |||
|
95 | ||||
|
96 | self.sa.add(users_group) | |||
|
97 | self.sa.commit() | |||
|
98 | except: | |||
|
99 | log.error(traceback.format_exc()) | |||
|
100 | self.sa.rollback() | |||
|
101 | raise | |||
|
102 | ||||
|
103 | def delete(self, users_group_id): | |||
|
104 | try: | |||
|
105 | users_group = self.get(users_group_id, cache=False) | |||
|
106 | self.sa.delete(users_group) | |||
|
107 | self.sa.commit() | |||
|
108 | except: | |||
|
109 | log.error(traceback.format_exc()) | |||
|
110 | self.sa.rollback() | |||
|
111 | raise |
@@ -0,0 +1,166 b'' | |||||
|
1 | ## -*- coding: utf-8 -*- | |||
|
2 | <%inherit file="/base/base.html"/> | |||
|
3 | ||||
|
4 | <%def name="title()"> | |||
|
5 | ${_('Edit users group')} ${c.users_group.users_group_name} - ${c.rhodecode_name} | |||
|
6 | </%def> | |||
|
7 | ||||
|
8 | <%def name="breadcrumbs_links()"> | |||
|
9 | ${h.link_to(_('Admin'),h.url('admin_home'))} | |||
|
10 | » | |||
|
11 | ${h.link_to(_('UsersGroups'),h.url('users_groups'))} | |||
|
12 | » | |||
|
13 | ${_('edit')} "${c.users_group.users_group_name}" | |||
|
14 | </%def> | |||
|
15 | ||||
|
16 | <%def name="page_nav()"> | |||
|
17 | ${self.menu('admin')} | |||
|
18 | </%def> | |||
|
19 | ||||
|
20 | <%def name="main()"> | |||
|
21 | <div class="box"> | |||
|
22 | <!-- box / title --> | |||
|
23 | <div class="title"> | |||
|
24 | ${self.breadcrumbs()} | |||
|
25 | </div> | |||
|
26 | <!-- end box / title --> | |||
|
27 | ${h.form(url('users_group', id=c.users_group.users_group_id),method='put', id='edit_users_group')} | |||
|
28 | <div class="form"> | |||
|
29 | <!-- fields --> | |||
|
30 | <div class="fields"> | |||
|
31 | <div class="field"> | |||
|
32 | <div class="label"> | |||
|
33 | <label for="users_group_name">${_('Group name')}:</label> | |||
|
34 | </div> | |||
|
35 | <div class="input"> | |||
|
36 | ${h.text('users_group_name',class_='small')} | |||
|
37 | </div> | |||
|
38 | </div> | |||
|
39 | ||||
|
40 | <div class="field"> | |||
|
41 | <div class="label label-checkbox"> | |||
|
42 | <label for="users_group_active">${_('Active')}:</label> | |||
|
43 | </div> | |||
|
44 | <div class="checkboxes"> | |||
|
45 | ${h.checkbox('users_group_active',value=True)} | |||
|
46 | </div> | |||
|
47 | </div> | |||
|
48 | <div class="field"> | |||
|
49 | <div class="label label-checkbox"> | |||
|
50 | <label for="users_group_active">${_('Members')}:</label> | |||
|
51 | </div> | |||
|
52 | <div class="checkboxes"> | |||
|
53 | <table> | |||
|
54 | <tr> | |||
|
55 | <td> | |||
|
56 | <div> | |||
|
57 | <div style="float:left"> | |||
|
58 | <div class="text">${_('Group members')}</div> | |||
|
59 | ${h.select('users_group_members',[x[0] for x in c.group_members],c.group_members,multiple=True,size=8,style="min-width:210px")} | |||
|
60 | </div> | |||
|
61 | <div style="float:left;width:20px;padding-top:50px"> | |||
|
62 | <img alt="add" id="add_element" | |||
|
63 | style="padding:2px;cursor:pointer" | |||
|
64 | src="/images/icons/arrow_left.png"> | |||
|
65 | <br /> | |||
|
66 | <img alt="remove" id="remove_element" | |||
|
67 | style="padding:2px;cursor:pointer" | |||
|
68 | src="/images/icons/arrow_right.png"> | |||
|
69 | </div> | |||
|
70 | <div style="float:left"> | |||
|
71 | <div class="text">${_('Available members')}</div> | |||
|
72 | ${h.select('available_members',[],c.available_members,multiple=True,size=8,style="min-width:210px")} | |||
|
73 | </div> | |||
|
74 | </div> | |||
|
75 | </td> | |||
|
76 | </tr> | |||
|
77 | </table> | |||
|
78 | </div> | |||
|
79 | ||||
|
80 | </div> | |||
|
81 | <div class="buttons"> | |||
|
82 | ${h.submit('save','save',class_="ui-button")} | |||
|
83 | </div> | |||
|
84 | </div> | |||
|
85 | </div> | |||
|
86 | ${h.end_form()} | |||
|
87 | </div> | |||
|
88 | ||||
|
89 | <script type="text/javascript"> | |||
|
90 | YAHOO.util.Event.onDOMReady(function(){ | |||
|
91 | var D = YAHOO.util.Dom; | |||
|
92 | var E = YAHOO.util.Event; | |||
|
93 | ||||
|
94 | //definition of containers ID's | |||
|
95 | var available_container = 'available_members'; | |||
|
96 | var selected_container = 'users_group_members'; | |||
|
97 | //form containing containers id | |||
|
98 | var form_id = 'edit_users_group'; | |||
|
99 | ||||
|
100 | //temp container for storage. | |||
|
101 | var cache = new Array(); | |||
|
102 | var c = D.get(selected_container); | |||
|
103 | ||||
|
104 | //get only selected options for further fullfilment | |||
|
105 | for(var i = 0;node =c.options[i];i++){ | |||
|
106 | if(node.selected){ | |||
|
107 | //push selected to my temp storage left overs :) | |||
|
108 | cache.push(node); | |||
|
109 | } | |||
|
110 | } | |||
|
111 | ||||
|
112 | //clear 'selected' select | |||
|
113 | c.options.length = 0; | |||
|
114 | ||||
|
115 | //fill it with remembered options | |||
|
116 | for(var i = 0;node = cache[i];i++){ | |||
|
117 | c.options[i]=new Option(node.text, node.value, false, false); | |||
|
118 | } | |||
|
119 | ||||
|
120 | function prompts_action_callback(e){ | |||
|
121 | ||||
|
122 | var choosen = D.get(selected_container); | |||
|
123 | var availible = D.get(available_container); | |||
|
124 | ||||
|
125 | if (this.id=='add_element'){ | |||
|
126 | for(var i=0; node = availible.options[i];i++){ | |||
|
127 | if(node.selected){ | |||
|
128 | choosen.appendChild(new Option(node.text, node.value, false, false)); | |||
|
129 | } | |||
|
130 | } | |||
|
131 | } | |||
|
132 | else if (this.id=='remove_element'){ | |||
|
133 | ||||
|
134 | //temp container for storage. | |||
|
135 | cache = new Array(); | |||
|
136 | ||||
|
137 | for(var i = 0;node = choosen.options[i];i++){ | |||
|
138 | if(!node.selected){ | |||
|
139 | //push left overs :) | |||
|
140 | cache.push(node); | |||
|
141 | } | |||
|
142 | } | |||
|
143 | //clear select | |||
|
144 | choosen.options.length = 0; | |||
|
145 | for(var i = 0;node = cache[i];i++){ | |||
|
146 | choosen.options[i]=new Option(node.text, node.value, false, false); | |||
|
147 | } | |||
|
148 | } | |||
|
149 | else{ | |||
|
150 | ||||
|
151 | } | |||
|
152 | } | |||
|
153 | ||||
|
154 | ||||
|
155 | E.addListener(['add_element','remove_element'],'click',prompts_action_callback) | |||
|
156 | ||||
|
157 | E.addListener(form_id,'submit',function(){ | |||
|
158 | var choosen = D.get(selected_container); | |||
|
159 | for (var i = 0; i < choosen.options.length; i++) { | |||
|
160 | choosen.options[i].selected = 'selected'; | |||
|
161 | } | |||
|
162 | }) | |||
|
163 | }); | |||
|
164 | </script> | |||
|
165 | ||||
|
166 | </%def> No newline at end of file |
@@ -37,7 +37,7 b'' | |||||
37 | %for cnt,u_group in enumerate(c.users_groups_list): |
|
37 | %for cnt,u_group in enumerate(c.users_groups_list): | |
38 | <tr class="parity${cnt%2}"> |
|
38 | <tr class="parity${cnt%2}"> | |
39 | <td>${h.link_to(u_group.users_group_name,h.url('edit_users_group', id=u_group.users_group_id))}</td> |
|
39 | <td>${h.link_to(u_group.users_group_name,h.url('edit_users_group', id=u_group.users_group_id))}</td> | |
40 | <td>${len(u_group.members)}</td> |
|
40 | <td><span class="tooltip" title="${', '.join([x.user.username for x in u_group.members[:50]])}">${len(u_group.members)}</span></td> | |
41 | <td>${h.bool2icon(u_group.users_group_active)}</td> |
|
41 | <td>${h.bool2icon(u_group.users_group_active)}</td> | |
42 | <td> |
|
42 | <td> | |
43 | ${h.form(url('users_group', id=u_group.users_group_id),method='delete')} |
|
43 | ${h.form(url('users_group', id=u_group.users_group_id),method='delete')} |
@@ -42,6 +42,37 b'' | |||||
42 | ${_('File is to big to display')} ${h.link_to(_('show as raw'), |
|
42 | ${_('File is to big to display')} ${h.link_to(_('show as raw'), | |
43 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} |
|
43 | h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))} | |
44 | %endif |
|
44 | %endif | |
|
45 | ||||
|
46 | <script type="text/javascript"> | |||
|
47 | function highlight_lines(lines){ | |||
|
48 | for(pos in lines){ | |||
|
49 | console.log('L'+lines[pos]); | |||
|
50 | YUD.setStyle('L'+lines[pos],'background-color','#FFFFBE'); | |||
|
51 | } | |||
|
52 | } | |||
|
53 | page_highlights = location.href.substring(location.href.indexOf('#')+1).split('L'); | |||
|
54 | if (page_highlights.length == 2){ | |||
|
55 | highlight_ranges = page_highlights[1].split(","); | |||
|
56 | ||||
|
57 | var h_lines = []; | |||
|
58 | for (pos in highlight_ranges){ | |||
|
59 | var _range = highlight_ranges[pos].split('-'); | |||
|
60 | if(_range.length == 2){ | |||
|
61 | var start = parseInt(_range[0]); | |||
|
62 | var end = parseInt(_range[1]); | |||
|
63 | if (start < end){ | |||
|
64 | for(var i=start;i<=end;i++){ | |||
|
65 | h_lines.push(i); | |||
|
66 | } | |||
|
67 | } | |||
|
68 | } | |||
|
69 | else{ | |||
|
70 | h_lines.push(parseInt(highlight_ranges[pos])); | |||
|
71 | } | |||
|
72 | } | |||
|
73 | highlight_lines(h_lines); | |||
|
74 | } | |||
|
75 | </script> | |||
45 | </div> |
|
76 | </div> | |
46 | </div> |
|
77 | </div> | |
47 |
|
78 |
General Comments 0
You need to be logged in to leave comments.
Login now