##// END OF EJS Templates
notification to commit author + gardening
marcink -
r1716:7d1fc253 beta
parent child Browse files
Show More
@@ -112,7 +112,7 b' class ApiController(JSONRPCController):'
112 :param ldap_dn:
112 :param ldap_dn:
113 """
113 """
114
114
115 if self.get_user(apiuser, username):
115 if User.get_by_username(username):
116 raise JSONRPCError("user %s already exist" % username)
116 raise JSONRPCError("user %s already exist" % username)
117
117
118 try:
118 try:
@@ -280,17 +280,17 b' class ChangesetController(BaseRepoContro'
280 revision=revision,
280 revision=revision,
281 f_path=request.POST.get('f_path'),
281 f_path=request.POST.get('f_path'),
282 line_no=request.POST.get('line'))
282 line_no=request.POST.get('line'))
283 Session.commit()
283 Session().commit()
284 return redirect(h.url('changeset_home', repo_name=repo_name,
284 return redirect(h.url('changeset_home', repo_name=repo_name,
285 revision=revision))
285 revision=revision))
286
286
287 @jsonify
287 @jsonify
288 def delete_comment(self, comment_id):
288 def delete_comment(self, repo_name, comment_id):
289 co = ChangesetComment.get(comment_id)
289 co = ChangesetComment.get(comment_id)
290 owner = lambda : co.author.user_id == c.rhodecode_user.user_id
290 owner = lambda : co.author.user_id == c.rhodecode_user.user_id
291 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
291 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
292 ChangesetCommentsModel().delete(comment=co)
292 ChangesetCommentsModel().delete(comment=co)
293 Session.commit()
293 Session().commit()
294 return True
294 return True
295 else:
295 else:
296 raise HTTPForbidden()
296 raise HTTPForbidden()
@@ -54,9 +54,11 b' log = logging.getLogger(__name__)'
54
54
55
55
56 class PasswordGenerator(object):
56 class PasswordGenerator(object):
57 """This is a simple class for generating password from
57 """
58 different sets of characters
58 This is a simple class for generating password from different sets of
59 usage:
59 characters
60 usage::
61
60 passwd_gen = PasswordGenerator()
62 passwd_gen = PasswordGenerator()
61 #print 8-letter password containing only big and small letters
63 #print 8-letter password containing only big and small letters
62 of alphabet
64 of alphabet
@@ -420,7 +422,8 b' class LoginRequired(object):'
420
422
421
423
422 class NotAnonymous(object):
424 class NotAnonymous(object):
423 """Must be logged in to execute this function else
425 """
426 Must be logged in to execute this function else
424 redirect to login page"""
427 redirect to login page"""
425
428
426 def __call__(self, func):
429 def __call__(self, func):
@@ -497,7 +500,8 b' class PermsDecorator(object):'
497
500
498
501
499 class HasPermissionAllDecorator(PermsDecorator):
502 class HasPermissionAllDecorator(PermsDecorator):
500 """Checks for access permission for all given predicates. All of them
503 """
504 Checks for access permission for all given predicates. All of them
501 have to be meet in order to fulfill the request
505 have to be meet in order to fulfill the request
502 """
506 """
503
507
@@ -508,7 +512,8 b' class HasPermissionAllDecorator(PermsDec'
508
512
509
513
510 class HasPermissionAnyDecorator(PermsDecorator):
514 class HasPermissionAnyDecorator(PermsDecorator):
511 """Checks for access permission for any of given predicates. In order to
515 """
516 Checks for access permission for any of given predicates. In order to
512 fulfill the request any of predicates must be meet
517 fulfill the request any of predicates must be meet
513 """
518 """
514
519
@@ -519,7 +524,8 b' class HasPermissionAnyDecorator(PermsDec'
519
524
520
525
521 class HasRepoPermissionAllDecorator(PermsDecorator):
526 class HasRepoPermissionAllDecorator(PermsDecorator):
522 """Checks for access permission for all given predicates for specific
527 """
528 Checks for access permission for all given predicates for specific
523 repository. All of them have to be meet in order to fulfill the request
529 repository. All of them have to be meet in order to fulfill the request
524 """
530 """
525
531
@@ -535,7 +541,8 b' class HasRepoPermissionAllDecorator(Perm'
535
541
536
542
537 class HasRepoPermissionAnyDecorator(PermsDecorator):
543 class HasRepoPermissionAnyDecorator(PermsDecorator):
538 """Checks for access permission for any of given predicates for specific
544 """
545 Checks for access permission for any of given predicates for specific
539 repository. In order to fulfill the request any of predicates must be meet
546 repository. In order to fulfill the request any of predicates must be meet
540 """
547 """
541
548
@@ -168,7 +168,7 b' class DbManage(object):'
168 #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
168 #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
169 for step in upgrade_steps:
169 for step in upgrade_steps:
170 print ('performing upgrade step %s' % step)
170 print ('performing upgrade step %s' % step)
171 callable = getattr(UpgradeSteps(self), 'step_%s' % step)()
171 getattr(UpgradeSteps(self), 'step_%s' % step)()
172
172
173 def fix_repo_paths(self):
173 def fix_repo_paths(self):
174 """Fixes a old rhodecode version path into new one without a '*'
174 """Fixes a old rhodecode version path into new one without a '*'
@@ -10,7 +10,7 b' import urllib'
10 import math
10 import math
11
11
12 from datetime import datetime
12 from datetime import datetime
13 from pygments.formatters import HtmlFormatter
13 from pygments.formatters.html import HtmlFormatter
14 from pygments import highlight as code_highlight
14 from pygments import highlight as code_highlight
15 from pylons import url, request, config
15 from pylons import url, request, config
16 from pylons.i18n.translation import _, ungettext
16 from pylons.i18n.translation import _, ungettext
@@ -151,7 +151,8 b' class SmtpMailer(object):'
151 'a dict in format {"filename":"filepath"}')
151 'a dict in format {"filename":"filepath"}')
152
152
153 def get_content(self, msg_file):
153 def get_content(self, msg_file):
154 """Get content based on type, if content is a string do open first
154 """
155 Get content based on type, if content is a string do open first
155 else just read because it's a probably open file object
156 else just read because it's a probably open file object
156
157
157 :param msg_file:
158 :param msg_file:
@@ -389,11 +389,7 b' def repo2db_mapper(initial_repo_list, re'
389 if user is None:
389 if user is None:
390 raise Exception('Missing administrative account !')
390 raise Exception('Missing administrative account !')
391 added = []
391 added = []
392 # fixup groups paths to new format on the fly
392
393 # TODO: remove this in future
394 for g in RepoGroup.query().all():
395 g.group_name = g.get_new_name(g.name)
396 sa.add(g)
397 for name, repo in initial_repo_list.items():
393 for name, repo in initial_repo_list.items():
398 group = map_groups(name.split(Repository.url_sep()))
394 group = map_groups(name.split(Repository.url_sep()))
399 if not rm.get_by_repo_name(name, cache=False):
395 if not rm.get_by_repo_name(name, cache=False):
@@ -485,8 +481,7 b' def create_test_env(repos_test_path, con'
485 install test repository into tmp dir
481 install test repository into tmp dir
486 """
482 """
487 from rhodecode.lib.db_manage import DbManage
483 from rhodecode.lib.db_manage import DbManage
488 from rhodecode.tests import HG_REPO, GIT_REPO, NEW_HG_REPO, NEW_GIT_REPO, \
484 from rhodecode.tests import HG_REPO, TESTS_TMP_PATH
489 HG_FORK, GIT_FORK, TESTS_TMP_PATH
490 import tarfile
485 import tarfile
491 import shutil
486 import shutil
492 from os.path import abspath
487 from os.path import abspath
@@ -73,7 +73,7 b' class BaseModel(object):'
73 else:
73 else:
74 self.sa = meta.Session()
74 self.sa = meta.Session()
75
75
76 def __get_instance(self, cls, instance):
76 def _get_instance(self, cls, instance):
77 """
77 """
78 Get's instance of given cls using some simple lookup mechanism
78 Get's instance of given cls using some simple lookup mechanism
79
79
@@ -41,7 +41,7 b' log = logging.getLogger(__name__)'
41 class ChangesetCommentsModel(BaseModel):
41 class ChangesetCommentsModel(BaseModel):
42
42
43 def __get_changeset_comment(self, changeset_comment):
43 def __get_changeset_comment(self, changeset_comment):
44 return self.__get_instance(ChangesetComment, changeset_comment)
44 return self._get_instance(ChangesetComment, changeset_comment)
45
45
46 def _extract_mentions(self, s):
46 def _extract_mentions(self, s):
47 user_objects = []
47 user_objects = []
@@ -65,7 +65,9 b' class ChangesetCommentsModel(BaseModel):'
65 """
65 """
66 if text:
66 if text:
67 repo = Repository.get(repo_id)
67 repo = Repository.get(repo_id)
68 desc = repo.scm_instance.get_changeset(revision).message
68 cs = repo.scm_instance.get_changeset(revision)
69 desc = cs.message
70 author = cs.author_email
69 comment = ChangesetComment()
71 comment = ChangesetComment()
70 comment.repo = repo
72 comment.repo = repo
71 comment.user_id = user_id
73 comment.user_id = user_id
@@ -90,11 +92,21 b' class ChangesetCommentsModel(BaseModel):'
90 )
92 )
91 body = text
93 body = text
92 recipients = ChangesetComment.get_users(revision=revision)
94 recipients = ChangesetComment.get_users(revision=revision)
93 recipients += self._extract_mentions(body)
95 # add changeset author
96 recipients += [User.get_by_email(author)]
97
94 NotificationModel().create(created_by=user_id, subject=subj,
98 NotificationModel().create(created_by=user_id, subject=subj,
95 body=body, recipients=recipients,
99 body=body, recipients=recipients,
96 type_=Notification.TYPE_CHANGESET_COMMENT)
100 type_=Notification.TYPE_CHANGESET_COMMENT)
97
101
102 mention_recipients = set(self._extract_mentions(body)).difference(recipients)
103 if mention_recipients:
104 subj = _('[Mention]') + ' ' + subj
105 NotificationModel().create(created_by=user_id, subject=subj,
106 body = body, recipients = mention_recipients,
107 type_=Notification.TYPE_CHANGESET_COMMENT)
108
109 self.sa.commit()
98 return comment
110 return comment
99
111
100 def delete(self, comment):
112 def delete(self, comment):
@@ -323,6 +323,15 b' class User(Base, BaseModel):'
323 "get_api_key_%s" % api_key))
323 "get_api_key_%s" % api_key))
324 return q.scalar()
324 return q.scalar()
325
325
326 @classmethod
327 def get_by_email(cls, email, cache=False):
328 q = cls.query().filter(cls.email == email)
329
330 if cache:
331 q = q.options(FromCache("sql_cache_short",
332 "get_api_key_%s" % email))
333 return q.scalar()
334
326 def update_lastlogin(self):
335 def update_lastlogin(self):
327 """Update user lastlogin"""
336 """Update user lastlogin"""
328
337
@@ -36,19 +36,15 b' from rhodecode.model.db import Notificat'
36
36
37 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
38
38
39
39 class NotificationModel(BaseModel):
40 class NotificationModel(BaseModel):
40
41
41
42
42 def __get_user(self, user):
43 def __get_user(self, user):
43 if isinstance(user, User):
44 if isinstance(user, basestring):
44 return user
45 elif isinstance(user, basestring):
46 return User.get_by_username(username=user)
45 return User.get_by_username(username=user)
47 elif isinstance(user, int):
48 return User.get(user)
49 else:
46 else:
50 raise Exception('Unsupported user must be one of int,'
47 return self._get_instance(User, user)
51 'str or User object')
52
48
53 def __get_notification(self, notification):
49 def __get_notification(self, notification):
54 if isinstance(notification, Notification):
50 if isinstance(notification, Notification):
@@ -82,7 +78,9 b' class NotificationModel(BaseModel):'
82
78
83 recipients_objs = []
79 recipients_objs = []
84 for u in recipients:
80 for u in recipients:
85 recipients_objs.append(self.__get_user(u))
81 obj = self.__get_user(u)
82 if obj:
83 recipients_objs.append(obj)
86 recipients_objs = set(recipients_objs)
84 recipients_objs = set(recipients_objs)
87 return Notification.create(created_by=created_by_obj, subject=subject,
85 return Notification.create(created_by=created_by_obj, subject=subject,
88 body=body, recipients=recipients_objs,
86 body=body, recipients=recipients_objs,
@@ -33,16 +33,17 b' from rhodecode.lib.caching_query import '
33 from rhodecode.model import BaseModel
33 from rhodecode.model import BaseModel
34 from rhodecode.model.db import User, Permission, UserToPerm, UserRepoToPerm
34 from rhodecode.model.db import User, Permission, UserToPerm, UserRepoToPerm
35
35
36
37 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
38
37
39
38
40 class PermissionModel(BaseModel):
39 class PermissionModel(BaseModel):
41 """Permissions model for RhodeCode
40 """
41 Permissions model for RhodeCode
42 """
42 """
43
43
44 def get_permission(self, permission_id, cache=False):
44 def get_permission(self, permission_id, cache=False):
45 """Get's permissions by id
45 """
46 Get's permissions by id
46
47
47 :param permission_id: id of permission to get from database
48 :param permission_id: id of permission to get from database
48 :param cache: use Cache for this query
49 :param cache: use Cache for this query
@@ -54,7 +55,8 b' class PermissionModel(BaseModel):'
54 return perm.get(permission_id)
55 return perm.get(permission_id)
55
56
56 def get_permission_by_name(self, name, cache=False):
57 def get_permission_by_name(self, name, cache=False):
57 """Get's permissions by given name
58 """
59 Get's permissions by given name
58
60
59 :param name: name to fetch
61 :param name: name to fetch
60 :param cache: Use cache for this query
62 :param cache: Use cache for this query
@@ -28,8 +28,6 b' import logging'
28 import traceback
28 import traceback
29 from datetime import datetime
29 from datetime import datetime
30
30
31 from sqlalchemy.orm import joinedload, make_transient
32
33 from vcs.utils.lazy import LazyProperty
31 from vcs.utils.lazy import LazyProperty
34 from vcs.backends import get_backend
32 from vcs.backends import get_backend
35
33
@@ -39,7 +37,6 b' from rhodecode.lib.caching_query import '
39 from rhodecode.model import BaseModel
37 from rhodecode.model import BaseModel
40 from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \
38 from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \
41 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup
39 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup
42 from rhodecode.model.user import UserModel
43
40
44 log = logging.getLogger(__name__)
41 log = logging.getLogger(__name__)
45
42
@@ -48,7 +45,8 b' class RepoModel(BaseModel):'
48
45
49 @LazyProperty
46 @LazyProperty
50 def repos_path(self):
47 def repos_path(self):
51 """Get's the repositories root path from database
48 """
49 Get's the repositories root path from database
52 """
50 """
53
51
54 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
52 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
@@ -141,8 +139,9 b' class RepoModel(BaseModel):'
141 # update permissions
139 # update permissions
142 for member, perm, member_type in form_data['perms_updates']:
140 for member, perm, member_type in form_data['perms_updates']:
143 if member_type == 'user':
141 if member_type == 'user':
142 _member = User.get_by_username(member)
144 r2p = self.sa.query(UserRepoToPerm)\
143 r2p = self.sa.query(UserRepoToPerm)\
145 .filter(UserRepoToPerm.user == User.get_by_username(member))\
144 .filter(UserRepoToPerm.user == _member)\
146 .filter(UserRepoToPerm.repository == cur_repo)\
145 .filter(UserRepoToPerm.repository == cur_repo)\
147 .one()
146 .one()
148
147
@@ -316,7 +315,7 b' class RepoModel(BaseModel):'
316 obj = self.sa.query(UsersGroupRepoToPerm)\
315 obj = self.sa.query(UsersGroupRepoToPerm)\
317 .filter(UsersGroupRepoToPerm.repository \
316 .filter(UsersGroupRepoToPerm.repository \
318 == self.get_by_repo_name(repo_name))\
317 == self.get_by_repo_name(repo_name))\
319 .filter(UsersGroupRepoToPerm.users_group_id \
318 .filter(UsersGroupRepoToPerm.users_group_id
320 == form_data['users_group_id']).one()
319 == form_data['users_group_id']).one()
321 self.sa.delete(obj)
320 self.sa.delete(obj)
322 self.sa.commit()
321 self.sa.commit()
@@ -351,7 +350,8 b' class RepoModel(BaseModel):'
351 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
350 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
352
351
353 if new_parent_id:
352 if new_parent_id:
354 paths = RepoGroup.get(new_parent_id).full_path.split(RepoGroup.url_sep())
353 paths = RepoGroup.get(new_parent_id)\
354 .full_path.split(RepoGroup.url_sep())
355 new_parent_path = os.sep.join(paths)
355 new_parent_path = os.sep.join(paths)
356 else:
356 else:
357 new_parent_path = ''
357 new_parent_path = ''
@@ -24,12 +24,14 b''
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 from rhodecode.model.db import BaseModel, UserRepoToPerm, Permission
27 from rhodecode.model import BaseModel
28 from rhodecode.model.meta import Session
28 from rhodecode.model.db import UserRepoToPerm, Permission
29
29
30 log = logging.getLogger(__name__)
30 log = logging.getLogger(__name__)
31
31
32
32 class RepositoryPermissionModel(BaseModel):
33 class RepositoryPermissionModel(BaseModel):
34
33 def get_user_permission(self, repository, user):
35 def get_user_permission(self, repository, user):
34 return UserRepoToPerm.query() \
36 return UserRepoToPerm.query() \
35 .filter(UserRepoToPerm.user == user) \
37 .filter(UserRepoToPerm.user == user) \
@@ -47,14 +49,14 b' class RepositoryPermissionModel(BaseMode'
47 p.user = user
49 p.user = user
48 p.repository = repository
50 p.repository = repository
49 p.permission = permission
51 p.permission = permission
50 Session.add(p)
52 self.sa.add(p)
51 Session.commit()
53 self.sa.commit()
52
54
53 def delete_user_permission(self, repository, user):
55 def delete_user_permission(self, repository, user):
54 current = self.get_user_permission(repository, user)
56 current = self.get_user_permission(repository, user)
55 if current:
57 if current:
56 Session.delete(current)
58 self.sa.delete(current)
57 Session.commit()
59 self.sa.commit()
58
60
59 def update_or_delete_user_permission(self, repository, user, permission):
61 def update_or_delete_user_permission(self, repository, user, permission):
60 if permission:
62 if permission:
@@ -27,8 +27,6 b' import time'
27 import traceback
27 import traceback
28 import logging
28 import logging
29
29
30 from sqlalchemy.exc import DatabaseError
31
32 from vcs import get_backend
30 from vcs import get_backend
33 from vcs.exceptions import RepositoryError
31 from vcs.exceptions import RepositoryError
34 from vcs.utils.lazy import LazyProperty
32 from vcs.utils.lazy import LazyProperty
@@ -119,12 +117,14 b' class CachedRepoList(object):'
119 yield tmp_d
117 yield tmp_d
120
118
121 class ScmModel(BaseModel):
119 class ScmModel(BaseModel):
122 """Generic Scm Model
120 """
121 Generic Scm Model
123 """
122 """
124
123
125 @LazyProperty
124 @LazyProperty
126 def repos_path(self):
125 def repos_path(self):
127 """Get's the repositories root path from database
126 """
127 Get's the repositories root path from database
128 """
128 """
129
129
130 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
130 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
@@ -132,7 +132,8 b' class ScmModel(BaseModel):'
132 return q.ui_value
132 return q.ui_value
133
133
134 def repo_scan(self, repos_path=None):
134 def repo_scan(self, repos_path=None):
135 """Listing of repositories in given path. This path should not be a
135 """
136 Listing of repositories in given path. This path should not be a
136 repository itself. Return a dictionary of repository objects
137 repository itself. Return a dictionary of repository objects
137
138
138 :param repos_path: path to directory containing repositories
139 :param repos_path: path to directory containing repositories
@@ -50,6 +50,7 b" PERM_WEIGHTS = {'repository.none': 0,"
50
50
51
51
52 class UserModel(BaseModel):
52 class UserModel(BaseModel):
53
53 def get(self, user_id, cache=False):
54 def get(self, user_id, cache=False):
54 user = self.sa.query(User)
55 user = self.sa.query(User)
55 if cache:
56 if cache:
@@ -26,17 +26,16 b''
26 import logging
26 import logging
27 import traceback
27 import traceback
28
28
29 from rhodecode.lib.caching_query import FromCache
30
31 from rhodecode.model import BaseModel
29 from rhodecode.model import BaseModel
32 from rhodecode.model.db import UsersGroupMember, UsersGroup
30 from rhodecode.model.db import UsersGroupMember, UsersGroup
33
31
34 log = logging.getLogger(__name__)
32 log = logging.getLogger(__name__)
35
33
34
36 class UsersGroupModel(BaseModel):
35 class UsersGroupModel(BaseModel):
37
36
38 def __get_users_group(self, users_group):
37 def __get_users_group(self, users_group):
39 return self.__get_instance(UsersGroup, users_group)
38 return self._get_instance(UsersGroup, users_group)
40
39
41 def get(self, users_group_id, cache = False):
40 def get(self, users_group_id, cache=False):
42 return UsersGroup.get(users_group_id)
41 return UsersGroup.get(users_group_id)
General Comments 0
You need to be logged in to leave comments. Login now