changeset 2908:3148c08cf86f rhodecode-0.0.1.4.4

merge with beta
author Marcin Kuzminski <marcin@python-works.com>
date Tue, 09 Oct 2012 00:41:32 +0200
parents 1f7b8c73c94a (current diff) 0b86972de820 (diff)
children 52b1c6de19c2
files CONTRIBUTORS docs/api/api.rst docs/changelog.rst docs/setup.rst rhodecode/controllers/settings.py rhodecode/lib/db_manage.py rhodecode/lib/hooks.py rhodecode/lib/utils.py rhodecode/model/repo.py rhodecode/templates/admin/users/user_edit_my_account.html
diffstat 18 files changed, 144 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/CONTRIBUTORS	Mon Oct 08 22:37:09 2012 +0200
+++ b/CONTRIBUTORS	Tue Oct 09 00:41:32 2012 +0200
@@ -28,3 +28,4 @@
     Vincent Caron <vcaron@bearstech.com>
     Zachary Auclair <zach101@gmail.com>
     Stefan Engel <mail@engel-stefan.de>
+    Andrew Shadura <bugzilla@tut.by>
\ No newline at end of file
--- a/docs/api/api.rst	Mon Oct 08 22:37:09 2012 +0200
+++ b/docs/api/api.rst	Tue Oct 09 00:41:32 2012 +0200
@@ -438,21 +438,6 @@
                "users_group_id" : "<id>",
                "group_name" :     "<groupname>",
                "active":          "<bool>",
-               "members" :  [
-                              { 
-                                "user_id" :  "<user_id>",
-                                "username" : "<username>",
-                                "firstname": "<firstname>",
-                                "lastname" : "<lastname>",
-                                "email" :    "<email>",
-                                "emails":    "<list_of_all_additional_emails>",
-                                "active" :   "<bool>",
-                                "admin" :    "<bool>",
-                                "ldap_dn" :  "<ldap_dn>",
-                                "last_login": "<last_login>",
-                              },
-                              …
-                            ]
                },

               ]
@@ -485,21 +470,6 @@
                      "users_group_id" : "<id>",
                      "group_name" :     "<groupname>",
                      "active":          "<bool>",
-                     "members" :  [
-                                  { 
-                                    "user_id" :  "<user_id>",
-                                    "username" : "<username>",
-                                    "firstname": "<firstname>",
-                                    "lastname" : "<lastname>",
-                                    "email" :    "<email>",
-                                    "emails":    "<list_of_all_additional_emails>",
-                                    "active" :   "<bool>",
-                                    "admin" :    "<bool>",
-                                    "ldap_dn" :  "<ldap_dn>",
-                                    "last_login": "<last_login>",
-                                  },
-                                  …
-                     ]
                },
             }
     error:  null
--- a/docs/changelog.rst	Mon Oct 08 22:37:09 2012 +0200
+++ b/docs/changelog.rst	Tue Oct 09 00:41:32 2012 +0200
@@ -14,6 +14,7 @@
 - #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 @@
   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**)
 ----------------------
--- a/docs/setup.rst	Mon Oct 08 22:37:09 2012 +0200
+++ b/docs/setup.rst	Tue Oct 09 00:41:32 2012 +0200
@@ -71,8 +71,8 @@
 
 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.
 
--- a/rhodecode/config/rcextensions/__init__.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/config/rcextensions/__init__.py	Tue Oct 09 00:41:32 2012 +0200
@@ -40,12 +40,38 @@
      :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
 #==============================================================================
 
--- a/rhodecode/controllers/settings.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/controllers/settings.py	Tue Oct 09 00:41:32 2012 +0200
@@ -188,4 +188,3 @@
             h.flash(_('An error occurred during unlocking'),
                     category='error')
         return redirect(url('summary_home', repo_name=repo_name))
-
--- a/rhodecode/lib/db_manage.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/lib/db_manage.py	Tue Oct 09 00:41:32 2012 +0200
@@ -667,4 +667,4 @@
         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')
--- a/rhodecode/lib/hooks.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/lib/hooks.py	Tue Oct 09 00:41:32 2012 +0200
@@ -24,6 +24,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 import os
 import sys
+import time
 import binascii
 from inspect import isfunction
 
@@ -38,6 +39,7 @@
 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 @@
 
     :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 @@
 
     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:
--- a/rhodecode/lib/utils.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/lib/utils.py	Tue Oct 09 00:41:32 2012 +0200
@@ -136,7 +136,7 @@
         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 @@
     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 @@
 
     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 @@
     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 @@
         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 @@
         # 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 @@
         # 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 @@
 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 @@
         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
--- a/rhodecode/lib/utils2.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/lib/utils2.py	Tue Oct 09 00:41:32 2012 +0200
@@ -314,9 +314,14 @@
 
     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 @@
             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 @@
     url = url.make_url(engine)
     if url.password:
         url.password = 'XXXXX'
-    return str(url)
\ No newline at end of file
+    return str(url)
--- a/rhodecode/model/repo.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/model/repo.py	Tue Oct 09 00:41:32 2012 +0200
@@ -33,7 +33,7 @@
 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 @@
     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
--- a/rhodecode/templates/admin/users/user_edit_my_account.html	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/templates/admin/users/user_edit_my_account.html	Tue Oct 09 00:41:32 2012 +0200
@@ -118,7 +118,7 @@
     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 @@
     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 @@
     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 @@
     '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
--- a/rhodecode/templates/pullrequests/pullrequest.html	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/templates/pullrequests/pullrequest.html	Tue Oct 09 00:41:32 2012 +0200
@@ -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 <select> of changed repo
     	  YUD.get('other_ref').innerHTML = other_repos_info[repo_name]['revs'];
       });
-      
+
       ypjax(url,'pull_request_overview', function(data){
     	  var sel_box = YUQ('#pull_request_form #other_repo')[0];
     	  var repo_name = sel_box.options[sel_box.selectedIndex].value;
--- a/rhodecode/templates/pullrequests/pullrequest_show.html	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/templates/pullrequests/pullrequest_show.html	Tue Oct 09 00:41:32 2012 +0200
@@ -47,7 +47,7 @@
             % if len(c.pull_request_pending_reviewers) > 0:
                 <div class="tooltip" title="${h.tooltip(','.join([x.username for x in c.pull_request_pending_reviewers]))}">${ungettext('%d reviewer', '%d reviewers',len(c.pull_request_pending_reviewers)) % len(c.pull_request_pending_reviewers)}</div>
             %else:
-                <div>${_('pull request was reviewed by all reviewers')}</div>            
+                <div>${_('pull request was reviewed by all reviewers')}</div>
             %endif
           </div>
          </div>
--- a/rhodecode/templates/shortlog/shortlog_data.html	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/templates/shortlog/shortlog_data.html	Tue Oct 09 00:41:32 2012 +0200
@@ -25,7 +25,7 @@
                 %endif
                 </div>
               %endif
-            </div>            
+            </div>
             <pre><a href="${h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id)}">r${cs.revision}:${h.short_id(cs.raw_id)}</a></pre>
          </div>
         </td>
--- a/rhodecode/tests/functional/test_compare.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/tests/functional/test_compare.py	Tue Oct 09 00:41:32 2012 +0200
@@ -400,4 +400,4 @@
             self.assertFalse("""line1-from-new-parent"""  in response.body)
         finally:
             RepoModel().delete(r2_id)
-            RepoModel().delete(r1_id)
\ No newline at end of file
+            RepoModel().delete(r1_id)
--- a/rhodecode/tests/test_libs.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/tests/test_libs.py	Tue Oct 09 00:41:32 2012 +0200
@@ -129,10 +129,25 @@
         self.assertEqual(age(n - delt(hours=1)), u'1 hour ago')
         self.assertEqual(age(n - delt(hours=24)), u'1 day ago')
         self.assertEqual(age(n - delt(hours=24 * 5)), u'5 days ago')
-        self.assertEqual(age(n - delt(hours=24 * (calendar.mdays[n.month-1] + 2))),
+        self.assertEqual(age(n - delt(hours=24 * (calendar.mdays[n.month - 1] + 2))),
                          u'1 month and 2 days ago')
         self.assertEqual(age(n - delt(hours=24 * 400)), u'1 year and 1 month ago')
 
+    def test_age_in_future(self):
+        import calendar
+        from rhodecode.lib.utils2 import age
+        n = datetime.datetime.now()
+        delt = lambda *args, **kwargs: datetime.timedelta(*args, **kwargs)
+        self.assertEqual(age(n), u'just now')
+        self.assertEqual(age(n + delt(seconds=1)), u'in 1 second')
+        self.assertEqual(age(n + delt(seconds=60 * 2)), u'in 2 minutes')
+        self.assertEqual(age(n + delt(hours=1)), u'in 1 hour')
+        self.assertEqual(age(n + delt(hours=24)), u'in 1 day')
+        self.assertEqual(age(n + delt(hours=24 * 5)), u'in 5 days')
+        self.assertEqual(age(n + delt(hours=24 * (calendar.mdays[n.month - 1] + 2))),
+                         u'in 1 month and 1 day')
+        self.assertEqual(age(n + delt(hours=24 * 400)), u'in 1 year and 1 month')
+
     def test_tag_exctrator(self):
         sample = (
             "hello pta[tag] gog [[]] [[] sda ero[or]d [me =>>< sa]"
@@ -195,4 +210,3 @@
                 em = 'test@foo.com'
                 grav = gravatar_url(email_address=em, size=24)
                 assert grav == 'https://server.com/%s/%s' % (_md5(em), 24)
-
--- a/rhodecode/tests/test_validators.py	Mon Oct 08 22:37:09 2012 +0200
+++ b/rhodecode/tests/test_validators.py	Tue Oct 09 00:41:32 2012 +0200
@@ -10,7 +10,7 @@
 from rhodecode.model.meta import Session
 from rhodecode.model.repos_group import ReposGroupModel
 from rhodecode.config.routing import ADMIN_PREFIX
-from rhodecode.model.db import ChangesetStatus
+from rhodecode.model.db import ChangesetStatus, Repository
 from rhodecode.model.changeset_status import ChangesetStatusModel
 from rhodecode.model.comment import ChangesetCommentsModel
 
@@ -227,7 +227,8 @@
         self.assertRaises(formencode.Invalid, validator.to_python, 123)
 
     def test_NotReviewedRevisions(self):
-        validator = v.NotReviewedRevisions()
+        repo_id = Repository.get_by_repo_name(HG_REPO).repo_id
+        validator = v.NotReviewedRevisions(repo_id)
         rev = '0' * 40
         # add status for a rev, that should throw an error because it is already
         # reviewed