diff --git a/CONTRIBUTORS b/CONTRIBUTORS --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -28,3 +28,4 @@ List of contributors to RhodeCode projec Vincent Caron Zachary Auclair Stefan Engel + Andrew Shadura \ No newline at end of file diff --git a/docs/api/api.rst b/docs/api/api.rst --- a/docs/api/api.rst +++ b/docs/api/api.rst @@ -438,21 +438,6 @@ OUTPUT:: "users_group_id" : "", "group_name" : "", "active": "", - "members" : [ - { - "user_id" : "", - "username" : "", - "firstname": "", - "lastname" : "", - "email" : "", - "emails": "", - "active" : "", - "admin" :  "", - "ldap_dn" : "", - "last_login": "", - }, - … - ] }, … ] @@ -485,21 +470,6 @@ OUTPUT:: "users_group_id" : "", "group_name" : "", "active": "", - "members" : [ - { - "user_id" : "", - "username" : "", - "firstname": "", - "lastname" : "", - "email" : "", - "emails": "", - "active" : "", - "admin" :  "", - "ldap_dn" : "", - "last_login": "", - }, - … - ] }, } error: null diff --git a/docs/changelog.rst b/docs/changelog.rst --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -14,6 +14,7 @@ news - #574 Show pull request status also in shortlog (if any) - remember selected tab in my account page - Bumped mercurial version to 2.3.2 +- #595 rcextension hook for repository delete fixes +++++ @@ -30,6 +31,8 @@ fixes status. Checks now are made also for the repository. - fixes #591 git backend was causing encoding errors when handling binary files - added a test case for VCS lib tests +- fixed #597 commits in future get negative age. +- fixed #598 API docs methods had wrong members parameter as returned data 1.4.3 (**2012-09-28**) ---------------------- diff --git a/docs/setup.rst b/docs/setup.rst --- a/docs/setup.rst +++ b/docs/setup.rst @@ -71,8 +71,8 @@ functionality. To do this simply execute This will create `rcextensions` package in the same place that your `ini` file lives. With `rcextensions` it's possible to add additional mapping for whoosh, -stats and add additional code into the push/pull/create repo hooks. For example -for sending signals to build-bots such as jenkins. +stats and add additional code into the push/pull/create/delete repo hooks. +For example for sending signals to build-bots such as jenkins. Please see the `__init__.py` file inside `rcextensions` package for more details. diff --git a/rhodecode/config/rcextensions/__init__.py b/rhodecode/config/rcextensions/__init__.py --- a/rhodecode/config/rcextensions/__init__.py +++ b/rhodecode/config/rcextensions/__init__.py @@ -40,12 +40,38 @@ def _crhook(*args, **kwargs): :param group_id: :param created_by: """ - return 0 CREATE_REPO_HOOK = _crhook #============================================================================== +# POST DELETE REPOSITORY HOOK +#============================================================================== +# this function will be executed after each repository deletion +def _dlhook(*args, **kwargs): + """ + Post create repository HOOK + kwargs available: + :param repo_name: + :param repo_type: + :param description: + :param private: + :param created_on: + :param enable_downloads: + :param repo_id: + :param user_id: + :param enable_statistics: + :param clone_uri: + :param fork_id: + :param group_id: + :param deleted_by: + :param deleted_on: + """ + return 0 +DELETE_REPO_HOOK = _dlhook + + +#============================================================================== # POST PUSH HOOK #============================================================================== diff --git a/rhodecode/controllers/settings.py b/rhodecode/controllers/settings.py --- a/rhodecode/controllers/settings.py +++ b/rhodecode/controllers/settings.py @@ -188,4 +188,3 @@ class SettingsController(BaseRepoControl h.flash(_('An error occurred during unlocking'), category='error') return redirect(url('summary_home', repo_name=repo_name)) - diff --git a/rhodecode/lib/db_manage.py b/rhodecode/lib/db_manage.py --- a/rhodecode/lib/db_manage.py +++ b/rhodecode/lib/db_manage.py @@ -667,4 +667,4 @@ class DbManage(object): if not __py_version__ >= (2, 6): notify('Python2.5 detected, please switch ' 'egg:waitress#main -> egg:Paste#http ' - 'in your .ini file') \ No newline at end of file + 'in your .ini file') diff --git a/rhodecode/lib/hooks.py b/rhodecode/lib/hooks.py --- a/rhodecode/lib/hooks.py +++ b/rhodecode/lib/hooks.py @@ -24,6 +24,7 @@ # along with this program. If not, see . import os import sys +import time import binascii from inspect import isfunction @@ -38,6 +39,7 @@ from rhodecode.lib.exceptions import HTT from rhodecode.lib.utils2 import safe_str from rhodecode.model.db import Repository, User + def _get_scm_size(alias, root_path): if not alias.startswith('.'): @@ -262,7 +264,6 @@ def log_create_repository(repository_dic :param repository: dict dump of repository object :param created_by: username who created repository - :param created_date: date of creation available keys of repository_dict: @@ -291,6 +292,45 @@ def log_create_repository(repository_dic return 0 + +def log_delete_repository(repository_dict, deleted_by, **kwargs): + """ + Post delete repository Hook. This is a dummy function for admins to re-use + if needed. It's taken from rhodecode-extensions module and executed + if present + + :param repository: dict dump of repository object + :param deleted_by: username who deleted the repository + + available keys of repository_dict: + + 'repo_type', + 'description', + 'private', + 'created_on', + 'enable_downloads', + 'repo_id', + 'user_id', + 'enable_statistics', + 'clone_uri', + 'fork_id', + 'group_id', + 'repo_name' + + """ + from rhodecode import EXTENSIONS + callback = getattr(EXTENSIONS, 'DELETE_REPO_HOOK', None) + if isfunction(callback): + kw = {} + kw.update(repository_dict) + kw.update({'deleted_by': deleted_by, + 'deleted_on': time.time()}) + kw.update(kwargs) + return callback(**kw) + + return 0 + + handle_git_pre_receive = (lambda repo_path, revs, env: handle_git_receive(repo_path, revs, env, hook_type='pre')) handle_git_post_receive = (lambda repo_path, revs, env: diff --git a/rhodecode/lib/utils.py b/rhodecode/lib/utils.py --- a/rhodecode/lib/utils.py +++ b/rhodecode/lib/utils.py @@ -136,7 +136,7 @@ def action_logger(user, action, repo, ip elif isinstance(user, basestring): user_obj = User.get_by_username(user) else: - raise Exception('You have to provide user object or username') + raise Exception('You have to provide a user object or a username') if hasattr(repo, 'repo_id'): repo_obj = Repository.get(repo.repo_id) @@ -255,7 +255,7 @@ def is_valid_repos_group(repos_group_nam return False -def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): +def ask_ok(prompt, retries=4, complaint='Yes or no please!'): while True: ok = raw_input(prompt) if ok in ('y', 'ye', 'yes'): @@ -299,7 +299,7 @@ def make_ui(read_from='file', path=None, if read_from == 'file': if not os.path.isfile(path): - log.debug('hgrc file is not present at %s skipping...' % path) + log.debug('hgrc file is not present at %s, skipping...' % path) return False log.debug('reading hgrc from %s' % path) cfg = config.config() @@ -410,7 +410,7 @@ def repo2db_mapper(initial_repo_list, re rm = RepoModel() user = sa.query(User).filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account !') + raise Exception('Missing administrative account!') added = [] # # clear cache keys @@ -423,7 +423,7 @@ def repo2db_mapper(initial_repo_list, re db_repo = rm.get_by_repo_name(name) # found repo that is on filesystem not in RhodeCode database if not db_repo: - log.info('repository %s not found creating now' % name) + log.info('repository %s not found, creating now' % name) added.append(name) desc = (repo.description if repo.description != 'unknown' @@ -446,7 +446,7 @@ def repo2db_mapper(initial_repo_list, re # during starting install all cache keys for all repositories in the # system, this will register all repos and multiple instances key, _prefix, _org_key = CacheInvalidation._get_key(name) - log.debug("Creating cache key for %s instance_id:`%s`" % (name, _prefix)) + log.debug("Creating a cache key for %s instance_id:`%s`" % (name, _prefix)) CacheInvalidation._get_or_create_key(key, _prefix, _org_key, commit=False) sa.commit() removed = [] @@ -454,7 +454,7 @@ def repo2db_mapper(initial_repo_list, re # remove from database those repositories that are not in the filesystem for repo in sa.query(Repository).all(): if repo.repo_name not in initial_repo_list.keys(): - log.debug("Removing non existing repository found in db `%s`" % + log.debug("Removing non-existing repository found in db `%s`" % repo.repo_name) try: sa.delete(repo) @@ -677,7 +677,7 @@ class BasePasterCommand(Command): def check_git_version(): """ Checks what version of git is installed in system, and issues a warning - if it's to old for RhodeCode to properly work. + if it's too old for RhodeCode to properly work. """ import subprocess from distutils.version import StrictVersion @@ -703,7 +703,7 @@ def check_git_version(): if stderr: log.warning('Unable to detect git version org error was:%r' % stderr) elif to_old_git: - log.warning('RhodeCode detected git version %s, which is to old ' - 'for the system to function properly make sure ' - 'it is at least in version %s' % (ver, req_ver)) - return _ver \ No newline at end of file + log.warning('RhodeCode detected git version %s, which is too old ' + 'for the system to function properly. Make sure ' + 'its version is at least %s' % (ver, req_ver)) + return _ver diff --git a/rhodecode/lib/utils2.py b/rhodecode/lib/utils2.py --- a/rhodecode/lib/utils2.py +++ b/rhodecode/lib/utils2.py @@ -314,9 +314,14 @@ def age(prevdate): order = ['year', 'month', 'day', 'hour', 'minute', 'second'] deltas = {} + future = False # Get date parts deltas now = datetime.datetime.now() + if prevdate > now: + now, prevdate = prevdate, now + future = True + for part in order: deltas[part] = getattr(now, part) - getattr(prevdate, part) @@ -369,10 +374,16 @@ def age(prevdate): sub_value = 0 if sub_value == 0: - return _(u'%s ago') % fmt_funcs[part](value) - - return _(u'%s and %s ago') % (fmt_funcs[part](value), - fmt_funcs[sub_part](sub_value)) + if future: + return _(u'in %s') % fmt_funcs[part](value) + else: + return _(u'%s ago') % fmt_funcs[part](value) + if future: + return _(u'in %s and %s') % (fmt_funcs[part](value), + fmt_funcs[sub_part](sub_value)) + else: + return _(u'%s and %s ago') % (fmt_funcs[part](value), + fmt_funcs[sub_part](sub_value)) return _(u'just now') @@ -504,4 +515,4 @@ def obfuscate_url_pw(engine): url = url.make_url(engine) if url.password: url.password = 'XXXXX' - return str(url) \ No newline at end of file + return str(url) diff --git a/rhodecode/model/repo.py b/rhodecode/model/repo.py --- a/rhodecode/model/repo.py +++ b/rhodecode/model/repo.py @@ -33,7 +33,7 @@ from rhodecode.lib.vcs.backends import g from rhodecode.lib.compat import json from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode from rhodecode.lib.caching_query import FromCache -from rhodecode.lib.hooks import log_create_repository +from rhodecode.lib.hooks import log_create_repository, log_delete_repository from rhodecode.model import BaseModel from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \ @@ -336,9 +336,13 @@ class RepoModel(BaseModel): def delete(self, repo): repo = self._get_repo(repo) if repo: + old_repo_dict = repo.get_dict() + owner = repo.user try: self.sa.delete(repo) self.__delete_repo(repo) + log_delete_repository(old_repo_dict, + deleted_by=owner.username) except: log.error(traceback.format_exc()) raise diff --git a/rhodecode/templates/admin/users/user_edit_my_account.html b/rhodecode/templates/admin/users/user_edit_my_account.html --- a/rhodecode/templates/admin/users/user_edit_my_account.html +++ b/rhodecode/templates/admin/users/user_edit_my_account.html @@ -118,7 +118,7 @@ var show_perms = function(e){ YUD.setStyle('my','display','none'); YUD.setStyle('pullrequests','display','none'); YUD.setStyle('perms','display',''); - YUD.setStyle('q_filter','display','none'); + YUD.setStyle('q_filter','display','none'); } YUE.on('show_perms','click',function(e){ show_perms(); @@ -134,12 +134,12 @@ var show_my = function(e){ YUD.setStyle('my','display',''); YUD.setStyle('q_filter','display',''); - + var url = "${h.url('admin_settings_my_repos')}"; ypjax(url, 'my', function(){ table_sort(); filter_activate(); - }); + }); } YUE.on('show_my','click',function(e){ show_my(e); @@ -154,9 +154,9 @@ var show_pullrequests = function(e){ YUD.setStyle('perms','display','none'); YUD.setStyle('pullrequests','display',''); YUD.setStyle('q_filter','display','none'); - + var url = "${h.url('admin_settings_my_pullrequests')}"; - ypjax(url, 'pullrequests'); + ypjax(url, 'pullrequests'); } YUE.on('show_pullrequests','click',function(e){ show_pullrequests(e) @@ -167,12 +167,12 @@ var tabs = { 'my': show_my, 'pullrequests': show_pullrequests } -var url = location.href.split('#'); -if (url[1]) { - //We have a hash +var url = location.href.split('#'); +if (url[1]) { + //We have a hash var tabHash = url[1]; console.log(tabs, tabHash) - tabs[tabHash](); + tabs[tabHash](); } // main table sorting diff --git a/rhodecode/templates/pullrequests/pullrequest.html b/rhodecode/templates/pullrequests/pullrequest.html --- a/rhodecode/templates/pullrequests/pullrequest.html +++ b/rhodecode/templates/pullrequests/pullrequest.html @@ -133,7 +133,7 @@ PullRequestAutoComplete('user', 'reviewers_container', _USERS_AC_DATA, _GROUPS_AC_DATA); var other_repos_info = ${c.other_repos_info|n}; - + var loadPreview = function(){ YUD.setStyle(YUD.get('pull_request_overview_url').parentElement,'display','none'); var url = "${h.url('compare_url', @@ -150,18 +150,18 @@ var select_ref_data = select_ref.value.split(':'); var key = null; var val = null; - + if(select_ref_data.length>1){ key = select_ref.name+"_type"; val = select_ref_data[0]; url = url.replace(key,val); rev_data[key] = val; - + key = select_ref.name; val = select_ref_data[1]; url = url.replace(key,val); rev_data[key] = val; - + }else{ key = select_ref.name; val = select_ref.value; @@ -175,7 +175,7 @@ // replace the