aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Kuzminski <marcin@python-works.com>2012-10-09 00:41:32 +0200
committerMarcin Kuzminski <marcin@python-works.com>2012-10-09 00:41:32 +0200
commit139b643db51d8097505b437337aa0e470be61250 (patch)
tree981dd6b9a7ccf121b835a5942df608958072bcf0
parent452651aca8cc01c8e94fd3c44c431a91247164c8 (diff)
parent547635a5a9633674896d58eba8859d3f12e5d002 (diff)
merge with betav1.4.4
-rw-r--r--CONTRIBUTORS1
-rw-r--r--docs/api/api.rst30
-rwxr-xr-xdocs/changelog.rst3
-rwxr-xr-xdocs/setup.rst4
-rw-r--r--rhodecode/config/rcextensions/__init__.py28
-rw-r--r--rhodecode/controllers/settings.py1
-rw-r--r--rhodecode/lib/db_manage.py2
-rw-r--r--rhodecode/lib/hooks.py42
-rw-r--r--rhodecode/lib/utils.py24
-rw-r--r--rhodecode/lib/utils2.py21
-rw-r--r--rhodecode/model/repo.py6
-rw-r--r--rhodecode/templates/admin/users/user_edit_my_account.html18
-rw-r--r--rhodecode/templates/pullrequests/pullrequest.html10
-rw-r--r--rhodecode/templates/pullrequests/pullrequest_show.html2
-rw-r--r--rhodecode/templates/shortlog/shortlog_data.html2
-rw-r--r--rhodecode/tests/functional/test_compare.py2
-rw-r--r--rhodecode/tests/test_libs.py18
-rw-r--r--rhodecode/tests/test_validators.py5
18 files changed, 144 insertions, 75 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index d45eb3c7..48b1c357 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -28,3 +28,4 @@ List of contributors to RhodeCode project:
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
diff --git a/docs/api/api.rst b/docs/api/api.rst
index 2eabeb73..82bfa22d 100644
--- a/docs/api/api.rst
+++ b/docs/api/api.rst
@@ -438,21 +438,6 @@ OUTPUT::
"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 @@ OUTPUT::
"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
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 46bca577..a8645d95 100755
--- 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
index 17fabc34..74324022 100755
--- 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
index 7c79fe68..803b6042 100644
--- 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
index c63be7de..37059b51 100644
--- a/rhodecode/controllers/settings.py
+++ b/rhodecode/controllers/settings.py
@@ -188,4 +188,3 @@ class SettingsController(BaseRepoController):
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
index cd860087..53b8185c 100644
--- 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
index ac0707cd..75e50ce5 100644
--- a/rhodecode/lib/hooks.py
+++ b/rhodecode/lib/hooks.py
@@ -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.exceptions import HTTPLockedRC
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_dict, created_by, **kwargs):
: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_dict, created_by, **kwargs):
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
index bf9acd35..0190cccc 100644
--- a/rhodecode/lib/utils.py
+++ b/rhodecode/lib/utils.py
@@ -136,7 +136,7 @@ def action_logger(user, action, repo, ipaddr='', sa=None, commit=False):
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_name, base_path):
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, checkpaths=True, clear_session=True):
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, remove_obsolete=False,
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, remove_obsolete=False,
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, remove_obsolete=False,
# 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, remove_obsolete=False,
# 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
index 8b699328..00b2d1e4 100644
--- 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
index e4b53767..40b49e51 100644
--- a/rhodecode/model/repo.py
+++ b/rhodecode/model/repo.py
@@ -33,7 +33,7 @@ from rhodecode.lib.vcs.backends import get_backend
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
index f9448acc..6d8eaa2c 100644
--- 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
index 0386d0f7..665331ac 100644
--- 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 <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;
diff --git a/rhodecode/templates/pullrequests/pullrequest_show.html b/rhodecode/templates/pullrequests/pullrequest_show.html
index bb865871..538fdb04 100644
--- a/rhodecode/templates/pullrequests/pullrequest_show.html
+++ b/rhodecode/templates/pullrequests/pullrequest_show.html
@@ -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>
diff --git a/rhodecode/templates/shortlog/shortlog_data.html b/rhodecode/templates/shortlog/shortlog_data.html
index 53b954c3..439ed1cd 100644
--- a/rhodecode/templates/shortlog/shortlog_data.html
+++ b/rhodecode/templates/shortlog/shortlog_data.html
@@ -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>
diff --git a/rhodecode/tests/functional/test_compare.py b/rhodecode/tests/functional/test_compare.py
index 7afbc2a7..255516fb 100644
--- a/rhodecode/tests/functional/test_compare.py
+++ b/rhodecode/tests/functional/test_compare.py
@@ -400,4 +400,4 @@ class TestCompareController(TestController):
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)
diff --git a/rhodecode/tests/test_libs.py b/rhodecode/tests/test_libs.py
index 349c8177..7dccaa21 100644
--- a/rhodecode/tests/test_libs.py
+++ b/rhodecode/tests/test_libs.py
@@ -129,10 +129,25 @@ class TestLibs(unittest.TestCase):
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 @@ class TestLibs(unittest.TestCase):
em = 'test@foo.com'
grav = gravatar_url(email_address=em, size=24)
assert grav == 'https://server.com/%s/%s' % (_md5(em), 24)
-
diff --git a/rhodecode/tests/test_validators.py b/rhodecode/tests/test_validators.py
index c1b2f0d2..fe29550c 100644
--- a/rhodecode/tests/test_validators.py
+++ b/rhodecode/tests/test_validators.py
@@ -10,7 +10,7 @@ from rhodecode.model.users_group import UsersGroupModel
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 @@ class TestReposGroups(unittest.TestCase):
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