Mercurial > public > src > rhodecode
changeset 2194:b567f5fde13e demo
merged stable into demo
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sat, 03 Mar 2012 03:41:38 +0200 |
parents | 1ea54d1ac8b2 (current diff) 8fd6650bb436 (diff) |
children | 6ee253bb18c1 |
files | rhodecode/controllers/admin/settings.py rhodecode/model/forms.py rhodecode/model/user.py rhodecode/templates/index_base.html |
diffstat | 43 files changed, 268 insertions(+), 147 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Feb 28 20:55:14 2012 +0200 +++ b/.hgtags Sat Mar 03 03:41:38 2012 +0200 @@ -49,3 +49,4 @@ dbc82e3362a25d2aece42060089824c4342efd17 v1.3.0 79a95f338fd0115b2cdb77118f39e17d22ff505c v1.3.1 9ab21c5ddb84935bea5c743b4e147ed5a398b30c v1.3.2 +934906f028b582a254e0028ba25e5d20dd32b9cd v1.3.3
--- a/CONTRIBUTORS Tue Feb 28 20:55:14 2012 +0200 +++ b/CONTRIBUTORS Sat Mar 03 03:41:38 2012 +0200 @@ -17,3 +17,4 @@ Matt Zuba <matt.zuba@goodwillaz.org> Aras Pranckevicius <aras@unity3d.com> Tony Bussieres <t.bussieres@gmail.com> + Erwin Kroon <e.kroon@smartmetersolutions.nl> \ No newline at end of file
--- a/docs/api/api.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/api/api.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,6 +1,6 @@ .. _api: - +=== API ===
--- a/docs/api/models.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/api/models.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,6 @@ .. _models: +======================== The :mod:`models` Module ========================
--- a/docs/changelog.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/changelog.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,9 +1,36 @@ .. _changelog: +========= Changelog ========= + +1.3.3 (**2012-03-02**) +---------------------- + +news +++++ + + +fixes ++++++ + +- fixed some python2.5 compatibility issues +- fixed issues with removed repos was accidentally added as groups, after + full rescan of paths +- fixes #376 Cannot edit user (using container auth) +- fixes #378 Invalid image urls on changeset screen with proxy-prefix + configuration +- fixed initial sorting of repos inside repo group +- fixes issue when user tried to resubmit same permission into user/user_groups +- bumped beaker version that fixes #375 leap error bug +- fixed raw_changeset for git. It was generated with hg patch headers +- fixed vcs issue with last_changeset for filenodes +- fixed missing commit after hook delete +- fixed #372 issues with git operation detection that caused a security issue + for git repos + 1.3.2 (**2012-02-28**) ----------------------
--- a/docs/contributing.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/contributing.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,6 @@ .. _contributing: +========================= Contributing to RhodeCode ========================= @@ -14,16 +15,19 @@ stable, and not the other way. Finally, when you are finished making a change, please send me a pull request. -To run RhodeCode in a development version you always need to install the tip -version of RhodeCode and the VCS library. +To run RhodeCode in a development version you always need to install the latest +required libs from `requires.txt` file. -after downloading RhodeCode make sure you run:: +after downloading/pulling RhodeCode make sure you run:: python setup.py develop -command to install all required packages, and prepare development enviroment +command to install/verify all required packages, and prepare development +enviroment. +After finishing your changes make sure all tests passes ok. You can run +the testsuite running nosetest from the project root. | Thank you for any contributions! | Marcin
--- a/docs/installation.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/installation.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,6 @@ .. _installation: +============ Installation ============
--- a/docs/setup.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/setup.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,6 @@ .. _setup: +===== Setup ===== @@ -648,6 +649,7 @@ threads=4 \ python-path=/home/web/rhodecode/pyenv/lib/python2.6/site-packages WSGIScriptAlias / /home/web/rhodecode/dispatch.wsgi + WSGIPassAuthorization On Example wsgi dispatch script::
--- a/docs/upgrade.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/upgrade.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,6 @@ .. _upgrade: +======= Upgrade ======= @@ -25,16 +26,17 @@ This will display any changes made by the new version of RhodeCode to your current configuration. It will try to perform an automerge. It's always better -to make a backup of your configuration file before hand and recheck the +to make a backup of your configuration file before hand and re check the content after the automerge. .. note:: - The next steps only apply to upgrading from non bugfix releases eg. from - any minor or major releases. Bugfix releases (eg. 1.1.2->1.1.3) will - not have any database schema changes or whoosh library updates. + Please always make sure your .ini files are up to date. Often errors are + caused by missing params added in new versions. + It is also recommended that you rebuild the whoosh index after upgrading since -the new whoosh version could introduce some incompatible index changes. +the new whoosh version could introduce some incompatible index changes. Please +Read the changelog to see if there were any changes to whoosh. The final step is to upgrade the database. To do this simply run::
--- a/docs/usage/backup.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/usage/backup.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,6 @@ .. _backup: +==================== Backing up RhodeCode ====================
--- a/docs/usage/general.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/usage/general.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,6 @@ .. _general: +======================= General RhodeCode usage =======================
--- a/docs/usage/git_support.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/usage/git_support.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,6 @@ .. _git_support: +=========== GIT support ===========
--- a/docs/usage/statistics.rst Tue Feb 28 20:55:14 2012 +0200 +++ b/docs/usage/statistics.rst Sat Mar 03 03:41:38 2012 +0200 @@ -1,6 +1,6 @@ .. _statistics: - +========== Statistics ==========
--- a/requires.txt Tue Feb 28 20:55:14 2012 +0200 +++ b/requires.txt Sat Mar 03 03:41:38 2012 +0200 @@ -1,5 +1,5 @@ Pylons==1.0.0 -Beaker==1.6.2 +Beaker==1.6.3 WebHelpers>=1.2 formencode==1.2.4 SQLAlchemy==0.7.4
--- a/rhodecode/__init__.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/__init__.py Sat Mar 03 03:41:38 2012 +0200 @@ -26,7 +26,7 @@ import sys import platform -VERSION = (1, 3, 2) +VERSION = (1, 3, 3) __version__ = '.'.join((str(each) for each in VERSION[:4])) __dbversion__ = 5 # defines current db version for migrations __platform__ = platform.system() @@ -38,7 +38,7 @@ requirements = [ "Pylons==1.0.0", - "Beaker==1.6.2", + "Beaker==1.6.3", "WebHelpers>=1.2", "formencode==1.2.4", "SQLAlchemy==0.7.4",
--- a/rhodecode/controllers/admin/settings.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/controllers/admin/settings.py Sat Mar 03 03:41:38 2012 +0200 @@ -248,7 +248,7 @@ if update: h.flash(_('Updated hooks'), category='success') - Session.commit() + self.sa.commit() except: log.error(traceback.format_exc()) h.flash(_('error occurred during hook creation'), @@ -285,7 +285,7 @@ if setting_id == 'hooks': hook_id = request.POST.get('hook_id') RhodeCodeUi.delete(hook_id) - + self.sa.commit() @HasPermissionAllDecorator('hg.admin') def show(self, setting_id, format='html'):
--- a/rhodecode/controllers/changeset.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/controllers/changeset.py Sat Mar 03 03:41:38 2012 +0200 @@ -53,7 +53,7 @@ def anchor_url(revision, path): fid = h.FID(revision, path) - return h.url.current(anchor=fid, **request.GET) + return h.url.current(anchor=fid, **dict(request.GET)) def get_ignore_ws(fid, GET): @@ -93,7 +93,7 @@ params[ctx_key] += [ctx_val] params['anchor'] = fileid - img = h.image('/images/icons/text_strikethrough.png', lbl, class_='icon') + img = h.image(h.url('/images/icons/text_strikethrough.png'), lbl, class_='icon') return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip') @@ -144,7 +144,7 @@ lbl = _('%s line context') % ln_ctx params['anchor'] = fileid - img = h.image('/images/icons/table_add.png', lbl, class_='icon') + img = h.image(h.url('/images/icons/table_add.png'), lbl, class_='icon') return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip') @@ -221,17 +221,20 @@ lim = self.cut_off_limit if cumulative_diff > self.cut_off_limit: lim = -1 - size, cs1, cs2, diff, st = wrapped_diff(filenode_old=None, - filenode_new=node, - cut_off_limit=lim, - ignore_whitespace=ign_whitespace_lcl, - line_context=line_context_lcl, - enable_comments=enable_comments) + size, cs1, cs2, diff, st = wrapped_diff( + filenode_old=None, + filenode_new=node, + cut_off_limit=lim, + ignore_whitespace=ign_whitespace_lcl, + line_context=line_context_lcl, + enable_comments=enable_comments + ) cumulative_diff += size c.lines_added += st[0] c.lines_deleted += st[1] - c.changes[changeset.raw_id].append(('added', node, diff, - cs1, cs2, st)) + c.changes[changeset.raw_id].append( + ('added', node, diff, cs1, cs2, st) + ) #================================================================== # CHANGED FILES @@ -249,24 +252,27 @@ lim = self.cut_off_limit if cumulative_diff > self.cut_off_limit: lim = -1 - size, cs1, cs2, diff, st = wrapped_diff(filenode_old=filenode_old, - filenode_new=node, - cut_off_limit=lim, - ignore_whitespace=ign_whitespace_lcl, - line_context=line_context_lcl, - enable_comments=enable_comments) + size, cs1, cs2, diff, st = wrapped_diff( + filenode_old=filenode_old, + filenode_new=node, + cut_off_limit=lim, + ignore_whitespace=ign_whitespace_lcl, + line_context=line_context_lcl, + enable_comments=enable_comments + ) cumulative_diff += size c.lines_added += st[0] c.lines_deleted += st[1] - c.changes[changeset.raw_id].append(('changed', node, diff, - cs1, cs2, st)) - + c.changes[changeset.raw_id].append( + ('changed', node, diff, cs1, cs2, st) + ) #================================================================== # REMOVED FILES #================================================================== for node in changeset.removed: - c.changes[changeset.raw_id].append(('removed', node, None, - None, None, (0, 0))) + c.changes[changeset.raw_id].append( + ('removed', node, None, None, None, (0, 0)) + ) # count inline comments for path, lines in c.inline_comments: @@ -311,7 +317,7 @@ format='gitdiff').raw_diff() cs1 = None - cs2 = node.last_changeset.raw_id + cs2 = node.changeset.raw_id c.changes.append(('added', node, diff, cs1, cs2)) for node in c.changeset.changed: @@ -325,8 +331,8 @@ diff = diffs.DiffProcessor(f_gitdiff, format='gitdiff').raw_diff() - cs1 = filenode_old.last_changeset.raw_id - cs2 = node.last_changeset.raw_id + cs1 = filenode_old.changeset.raw_id + cs2 = node.changeset.raw_id c.changes.append(('changed', node, diff, cs1, cs2)) response.content_type = 'text/plain' @@ -335,8 +341,8 @@ response.content_disposition = 'attachment; filename=%s.patch' \ % revision - c.parent_tmpl = ''.join(['# Parent %s\n' % x.raw_id for x in - c.changeset.parents]) + c.parent_tmpl = ''.join(['# Parent %s\n' % x.raw_id + for x in c.changeset.parents]) c.diffs = '' for x in c.changes:
--- a/rhodecode/controllers/files.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/controllers/files.py Sat Mar 03 03:41:38 2012 +0200 @@ -428,8 +428,9 @@ diff_name = '%s_vs_%s.diff' % (diff1, diff2) response.content_type = 'text/plain' - response.content_disposition = 'attachment; filename=%s' \ - % diff_name + response.content_disposition = ( + 'attachment; filename=%s' % diff_name + ) return diff.raw_diff() elif c.action == 'raw':
--- a/rhodecode/controllers/summary.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/controllers/summary.py Sat Mar 03 03:41:38 2012 +0200 @@ -28,8 +28,8 @@ import logging from time import mktime from datetime import timedelta, date -from itertools import product from urlparse import urlparse +from rhodecode.lib.compat import product from rhodecode.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, \ NodeDoesNotExistError
--- a/rhodecode/lib/compat.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/lib/compat.py Sat Mar 03 03:41:38 2012 +0200 @@ -379,3 +379,21 @@ else: kill = os.kill + + +#============================================================================== +# itertools.product +#============================================================================== + +try: + from itertools import product +except ImportError: + def product(*args, **kwds): + # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy + # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 + pools = map(tuple, args) * kwds.get('repeat', 1) + result = [[]] + for pool in pools: + result = [x + [y] for x in result for y in pool] + for prod in result: + yield tuple(prod)
--- a/rhodecode/lib/diffs.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/lib/diffs.py Sat Mar 03 03:41:38 2012 +0200 @@ -83,8 +83,8 @@ if not diff: diff = wrap_to_table(_('No changes detected')) - cs1 = filenode_old.last_changeset.raw_id - cs2 = filenode_new.last_changeset.raw_id + cs1 = filenode_old.changeset.raw_id + cs2 = filenode_new.changeset.raw_id return size, cs1, cs2, diff, stats
--- a/rhodecode/lib/middleware/simplegit.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/lib/middleware/simplegit.py Sat Mar 03 03:41:38 2012 +0200 @@ -121,6 +121,7 @@ #====================================================================== # CHECK ANONYMOUS PERMISSION #====================================================================== + if action in ['pull', 'push']: anonymous_user = self.__get_user('default') username = anonymous_user.username @@ -169,15 +170,13 @@ start_response) #check permissions for this repository - perm = self._check_permission(action, user, - repo_name) + perm = self._check_permission(action, user, repo_name) if perm is not True: return HTTPForbidden()(environ, start_response) #=================================================================== # GIT REQUEST HANDLING #=================================================================== - repo_path = safe_str(os.path.join(self.basepath, repo_name)) log.debug('Repository path is %s' % repo_path) @@ -203,7 +202,6 @@ :param repo_name: name of the repository :param repo_path: full path to the repository """ - _d = {'/' + repo_name: Repo(repo_path)} backend = dulserver.DictBackend(_d) gitserve = HTTPGitApplication(backend) @@ -229,19 +227,24 @@ return User.get_by_username(username) def __get_action(self, environ): - """Maps git request commands into a pull or push command. + """ + Maps git request commands into a pull or push command. :param environ: """ service = environ['QUERY_STRING'].split('=') + if len(service) > 1: service_cmd = service[1] mapping = { 'git-receive-pack': 'push', 'git-upload-pack': 'pull', } - - return mapping.get(service_cmd, - service_cmd if service_cmd else 'other') + op = mapping[service_cmd] + self._git_stored_op = op + return op else: - return 'other' + # try to fallback to stored variable as we don't know if the last + # operation is pull/push + op = getattr(self, '_git_stored_op', 'pull') + return op
--- a/rhodecode/lib/utils.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/lib/utils.py Sat Mar 03 03:41:38 2012 +0200 @@ -24,6 +24,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import os +import re import logging import datetime import traceback @@ -56,6 +57,8 @@ log = logging.getLogger(__name__) +REMOVED_REPO_PAT = re.compile(r'rm__\d{8}_\d{6}_\d{6}__.*') + def recursive_replace(str_, replace=' '): """Recursive replace of given sign to just one instance @@ -393,6 +396,10 @@ # group = rgm.create(group_name, desc, parent, just_db=True) # sa.commit() + # skip folders that are now removed repos + if REMOVED_REPO_PAT.match(group_name): + break + if group is None: log.debug('creating group level: %s group_name: %s' % (lvl, group_name)) group = RepoGroup(group_name, parent)
--- a/rhodecode/lib/vcs/backends/git/changeset.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/lib/vcs/backends/git/changeset.py Sat Mar 03 03:41:38 2012 +0200 @@ -247,7 +247,7 @@ iterating commits. """ cmd = 'log --pretty="format: %%H" --name-status -p %s -- "%s"' % ( - '', path + self.id, path ) so, se = self.repository.run_git_command(cmd) ids = re.findall(r'\w{40}', so)
--- a/rhodecode/lib/vcs/backends/hg/changeset.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/lib/vcs/backends/hg/changeset.py Sat Mar 03 03:41:38 2012 +0200 @@ -187,9 +187,8 @@ """ Returns last commit of the file at the given ``path``. """ - fctx = self._get_filectx(path) - changeset = self.repository.get_changeset(fctx.linkrev()) - return changeset + node = self.get_node(path) + return node.history[0] def get_file_history(self, path): """
--- a/rhodecode/lib/vcs/nodes.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/lib/vcs/nodes.py Sat Mar 03 03:41:38 2012 +0200 @@ -306,14 +306,14 @@ attribute to indicate that type should *NOT* be calculated). """ if hasattr(self, '_mimetype'): - if (isinstance(self._mimetype,(tuple,list,)) and + if (isinstance(self._mimetype, (tuple, list,)) and len(self._mimetype) == 2): return self._mimetype else: raise NodeError('given _mimetype attribute must be an 2 ' 'element list or tuple') - mtype,encoding = mimetypes.guess_type(self.name) + mtype, encoding = mimetypes.guess_type(self.name) if mtype is None: if self.is_binary: @@ -322,7 +322,7 @@ else: mtype = 'text/plain' encoding = None - return mtype,encoding + return mtype, encoding @LazyProperty def mimetype(self): @@ -392,8 +392,8 @@ """ Returns True if file has binary content. """ - bin = '\0' in self.content - return bin + _bin = '\0' in self.content + return _bin @LazyProperty def extension(self): @@ -406,6 +406,10 @@ """ return bool(self.mode & stat.S_IXUSR) + def __repr__(self): + return '<%s %r @ %s>' % (self.__class__.__name__, self.path, + self.changeset.short_id) + class RemovedFileNode(FileNode): """ @@ -537,6 +541,10 @@ return size + def __repr__(self): + return '<%s %r @ %s>' % (self.__class__.__name__, self.path, + self.changeset.short_id) + class RootNode(DirNode): """
--- a/rhodecode/lib/vcs/utils/diffs.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/lib/vcs/utils/diffs.py Sat Mar 03 03:41:38 2012 +0200 @@ -15,17 +15,17 @@ from rhodecode.lib.vcs.nodes import FileNode, NodeError -def get_udiff(filenode_old, filenode_new,show_whitespace=True): +def get_udiff(filenode_old, filenode_new, show_whitespace=True): """ Returns unified diff between given ``filenode_old`` and ``filenode_new``. """ try: - filenode_old_date = filenode_old.last_changeset.date + filenode_old_date = filenode_old.changeset.date except NodeError: filenode_old_date = None try: - filenode_new_date = filenode_new.last_changeset.date + filenode_new_date = filenode_new.changeset.date except NodeError: filenode_new_date = None
--- a/rhodecode/model/comment.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/model/comment.py Sat Mar 03 03:41:38 2012 +0200 @@ -67,7 +67,7 @@ repo = Repository.get(repo_id) cs = repo.scm_instance.get_changeset(revision) desc = cs.message - author = cs.author_email + author_email = cs.author_email comment = ChangesetComment() comment.repo = repo comment.user_id = user_id @@ -92,22 +92,27 @@ ) ) body = text + + # get the current participants of this changeset recipients = ChangesetComment.get_users(revision=revision) - # add changeset author - recipients += [User.get_by_email(author)] - NotificationModel().create(created_by=user_id, subject=subj, - body=body, recipients=recipients, - type_=Notification.TYPE_CHANGESET_COMMENT) + # add changeset author if it's in rhodecode system + recipients += [User.get_by_email(author_email)] + + NotificationModel().create( + created_by=user_id, subject=subj, body=body, + recipients=recipients, type_=Notification.TYPE_CHANGESET_COMMENT + ) mention_recipients = set(self._extract_mentions(body))\ .difference(recipients) if mention_recipients: subj = _('[Mention]') + ' ' + subj - NotificationModel().create(created_by=user_id, subject=subj, - body=body, - recipients=mention_recipients, - type_=Notification.TYPE_CHANGESET_COMMENT) + NotificationModel().create( + created_by=user_id, subject=subj, body=body, + recipients=mention_recipients, + type_=Notification.TYPE_CHANGESET_COMMENT + ) return comment
--- a/rhodecode/model/db.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/model/db.py Sat Mar 03 03:41:38 2012 +0200 @@ -807,7 +807,9 @@ @property def repositories(self): - return Repository.query().filter(Repository.group == self) + return Repository.query()\ + .filter(Repository.group == self)\ + .order_by(Repository.repo_name) @property def repositories_recursive_count(self):
--- a/rhodecode/model/forms.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/model/forms.py Sat Mar 03 03:41:38 2012 +0200 @@ -487,7 +487,7 @@ class _UniqSystemEmail(formencode.validators.FancyValidator): def to_python(self, value, state): value = value.lower() - if old_data.get('email', '').lower() != value: + if (old_data.get('email') or '').lower() != value: user = User.get_by_email(value, case_insensitive=True) if user: raise formencode.Invalid(
--- a/rhodecode/model/notification.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/model/notification.py Sat Mar 03 03:41:38 2012 +0200 @@ -85,13 +85,19 @@ if obj: recipients_objs.append(obj) recipients_objs = set(recipients_objs) + log.debug('sending notifications %s to %s' % ( + type_, recipients_objs) + ) else: # empty recipients means to all admins recipients_objs = User.query().filter(User.admin == True).all() - - notif = Notification.create(created_by=created_by_obj, subject=subject, - body=body, recipients=recipients_objs, - type_=type_) + log.debug('sending notifications %s to admins: %s' % ( + type_, recipients_objs) + ) + notif = Notification.create( + created_by=created_by_obj, subject=subject, + body=body, recipients=recipients_objs, type_=type_ + ) if with_email is False: return notif @@ -163,10 +169,12 @@ of notification object """ - _map = {notification.TYPE_CHANGESET_COMMENT:_('commented on commit'), - notification.TYPE_MESSAGE:_('sent message'), - notification.TYPE_MENTION:_('mentioned you'), - notification.TYPE_REGISTRATION:_('registered in RhodeCode')} + _map = { + notification.TYPE_CHANGESET_COMMENT: _('commented on commit'), + notification.TYPE_MESSAGE: _('sent message'), + notification.TYPE_MENTION: _('mentioned you'), + notification.TYPE_REGISTRATION: _('registered in RhodeCode') + } DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S" @@ -176,9 +184,10 @@ else: DTF = lambda d: datetime.datetime.strftime(d, DATETIME_FORMAT) when = DTF(notification.created_on) - data = dict(user=notification.created_by_user.username, - action=_map[notification.type_], - when=when) + data = dict( + user=notification.created_by_user.username, + action=_map[notification.type_], when=when, + ) return tmpl % data @@ -194,10 +203,10 @@ self._tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup self.email_types = { - self.TYPE_CHANGESET_COMMENT:'email_templates/changeset_comment.html', - self.TYPE_PASSWORD_RESET:'email_templates/password_reset.html', - self.TYPE_REGISTRATION:'email_templates/registration.html', - self.TYPE_DEFAULT:'email_templates/default.html' + self.TYPE_CHANGESET_COMMENT: 'email_templates/changeset_comment.html', + self.TYPE_PASSWORD_RESET: 'email_templates/password_reset.html', + self.TYPE_REGISTRATION: 'email_templates/registration.html', + self.TYPE_DEFAULT: 'email_templates/default.html' } def get_email_tmpl(self, type_, **kwargs): @@ -210,7 +219,7 @@ base = self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT]) email_template = self._tmpl_lookup.get_template(base) # translator inject - _kwargs = {'_':_} + _kwargs = {'_': _} _kwargs.update(kwargs) log.debug('rendering tmpl %s with kwargs %s' % (base, _kwargs)) return email_template.render(**_kwargs)
--- a/rhodecode/model/scm.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/model/scm.py Sat Mar 03 03:41:38 2012 +0200 @@ -38,7 +38,7 @@ from rhodecode.lib import safe_str from rhodecode.lib.auth import HasRepoPermissionAny, HasReposGroupPermissionAny from rhodecode.lib.utils import get_repos as get_filesystem_repos, make_ui, \ - action_logger, EmptyChangeset + action_logger, EmptyChangeset, REMOVED_REPO_PAT from rhodecode.model import BaseModel from rhodecode.model.db import Repository, RhodeCodeUi, CacheInvalidation, \ UserFollowing, UserLog, User, RepoGroup @@ -182,6 +182,9 @@ repos = {} for name, path in get_filesystem_repos(repos_path, recursive=True): + # skip removed repos + if REMOVED_REPO_PAT.match(name): + continue # name need to be decomposed and put back together using the / # since this is internal storage separator for rhodecode
--- a/rhodecode/model/user.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/model/user.py Sat Mar 03 03:41:38 2012 +0200 @@ -533,6 +533,13 @@ """ user = self.__get_user(user) perm = self.__get_perm(perm) + # if this permission is already granted skip it + _perm = UserToPerm.query()\ + .filter(UserToPerm.user == user)\ + .filter(UserToPerm.permission == perm)\ + .scalar() + if _perm: + return new = UserToPerm() new.user = user new.permission = perm @@ -548,7 +555,9 @@ user = self.__get_user(user) perm = self.__get_perm(perm) - obj = UserToPerm.query().filter(UserToPerm.user == user)\ - .filter(UserToPerm.permission == perm).scalar() + obj = UserToPerm.query()\ + .filter(UserToPerm.user == user)\ + .filter(UserToPerm.permission == perm)\ + .scalar() if obj: self.sa.delete(obj)
--- a/rhodecode/model/users_group.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/model/users_group.py Sat Mar 03 03:41:38 2012 +0200 @@ -172,6 +172,14 @@ users_group = self.__get_users_group(users_group) + # if this permission is already granted skip it + _perm = UsersGroupToPerm.query()\ + .filter(UsersGroupToPerm.users_group == users_group)\ + .filter(UsersGroupToPerm.permission == perm)\ + .scalar() + if _perm: + return + new = UsersGroupToPerm() new.users_group = users_group new.permission = perm
--- a/rhodecode/public/js/rhodecode.js Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/public/js/rhodecode.js Sat Mar 03 03:41:38 2012 +0200 @@ -613,16 +613,20 @@ * QUICK REPO MENU */ var quick_repo_menu = function(){ - YUE.on(YUQ('.quick_repo_menu'),'click',function(e){ - var menu = e.currentTarget.firstElementChild.firstElementChild; - if(YUD.hasClass(menu,'hidden')){ - YUD.addClass(e.currentTarget,'active'); - YUD.removeClass(menu,'hidden'); - }else{ - YUD.removeClass(e.currentTarget,'active'); - YUD.addClass(menu,'hidden'); - } - }) + YUE.on(YUQ('.quick_repo_menu'),'mouseenter',function(e){ + var menu = e.currentTarget.firstElementChild.firstElementChild; + if(YUD.hasClass(menu,'hidden')){ + YUD.replaceClass(e.currentTarget,'hidden', 'active'); + YUD.replaceClass(menu, 'hidden', 'active'); + } + }) + YUE.on(YUQ('.quick_repo_menu'),'mouseleave',function(e){ + var menu = e.currentTarget.firstElementChild.firstElementChild; + if(YUD.hasClass(menu,'active')){ + YUD.replaceClass(e.currentTarget, 'active', 'hidden'); + YUD.replaceClass(menu, 'active', 'hidden'); + } + }) };
--- a/rhodecode/templates/admin/repos/repos.html Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/templates/admin/repos/repos.html Sat Mar 03 03:41:38 2012 +0200 @@ -42,8 +42,8 @@ </tr> </thead> - %for cnt,repo in enumerate(c.repos_list,1): - <tr class="parity${cnt%2}"> + %for cnt,repo in enumerate(c.repos_list): + <tr class="parity${(cnt+1)%2}"> <td class="quick_repo_menu"> ${dt.quick_menu(repo['name'])} </td>
--- a/rhodecode/templates/changeset/raw_changeset.html Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/templates/changeset/raw_changeset.html Sat Mar 03 03:41:38 2012 +0200 @@ -1,8 +1,9 @@ +%if h.is_hg(c.scm_type): # ${c.scm_type.upper()} changeset patch # User ${c.changeset.author|n} # Date ${c.changeset.date} # Node ID ${c.changeset.raw_id} ${c.parent_tmpl} ${c.changeset.message} - +%endif ${c.diffs|n}
--- a/rhodecode/templates/files/files_annotate.html Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/templates/files/files_annotate.html Sat Mar 03 03:41:38 2012 +0200 @@ -34,8 +34,8 @@ <dd> <div> ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')} - ${h.hidden('diff2',c.file.last_changeset.raw_id)} - ${h.select('diff1',c.file.last_changeset.raw_id,c.file_history)} + ${h.hidden('diff2',c.file.changeset.raw_id)} + ${h.select('diff1',c.file.changeset.raw_id,c.file_history)} ${h.submit('diff','diff to revision',class_="ui-btn")} ${h.submit('show_rev','show at revision',class_="ui-btn")} ${h.end_form()} @@ -46,7 +46,7 @@ <div class="code-header"> <div class="stats"> <div class="left"><img src="${h.url('/images/icons/file.png')}"/></div> - <div class="left item">${h.link_to("r%s:%s" % (c.file.last_changeset.revision,h.short_id(c.file.last_changeset.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id))}</div> + <div class="left item">${h.link_to("r%s:%s" % (c.file.changeset.revision,h.short_id(c.file.changeset.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id))}</div> <div class="left item">${h.format_byte_size(c.file.size,binary=True)}</div> <div class="left item last">${c.file.mimetype}</div> <div class="buttons">
--- a/rhodecode/templates/files/files_browser.html Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/templates/files/files_browser.html Sat Mar 03 03:41:38 2012 +0200 @@ -47,7 +47,7 @@ <th>${_('Name')}</th> <th>${_('Size')}</th> <th>${_('Mimetype')}</th> - <th>${_('Revision')}</th> + <th>${_('Last Revision')}</th> <th>${_('Last modified')}</th> <th>${_('Last commiter')}</th> </tr> @@ -70,7 +70,7 @@ %for cnt,node in enumerate(c.file): <tr class="parity${cnt%2}"> <td> - ${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=h.safe_unicode(node.path)),class_=file_class(node)+" ypjax-link")} + ${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=h.safe_unicode(node.path)),class_=file_class(node)+" ypjax-link")} </td> <td> %if node.is_file():
--- a/rhodecode/templates/files/files_edit.html Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/templates/files/files_edit.html Sat Mar 03 03:41:38 2012 +0200 @@ -42,7 +42,7 @@ <div class="code-header"> <div class="stats"> <div class="left"><img src="${h.url('/images/icons/file.png')}"/></div> - <div class="left item">${h.link_to("r%s:%s" % (c.file.last_changeset.revision,h.short_id(c.file.last_changeset.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id))}</div> + <div class="left item">${h.link_to("r%s:%s" % (c.file.changeset.revision,h.short_id(c.file.changeset.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id))}</div> <div class="left item">${h.format_byte_size(c.file.size,binary=True)}</div> <div class="left item last">${c.file.mimetype}</div> <div class="buttons">
--- a/rhodecode/templates/files/files_source.html Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/templates/files/files_source.html Sat Mar 03 03:41:38 2012 +0200 @@ -3,8 +3,8 @@ <dd> <div> ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')} - ${h.hidden('diff2',c.file.last_changeset.raw_id)} - ${h.select('diff1',c.file.last_changeset.raw_id,c.file_history)} + ${h.hidden('diff2',c.file.changeset.raw_id)} + ${h.select('diff1',c.file.changeset.raw_id,c.file_history)} ${h.submit('diff','diff to revision',class_="ui-btn")} ${h.submit('show_rev','show at revision',class_="ui-btn")} ${h.end_form()} @@ -16,27 +16,27 @@ <div class="code-header"> <div class="stats"> <div class="left img"><img src="${h.url('/images/icons/file.png')}"/></div> - <div class="left item"><pre>${h.link_to("r%s:%s" % (c.file.last_changeset.revision,h.short_id(c.file.last_changeset.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id))}</pre></div> + <div class="left item"><pre>${h.link_to("r%s:%s" % (c.file.changeset.revision,h.short_id(c.file.changeset.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id))}</pre></div> <div class="left item"><pre>${h.format_byte_size(c.file.size,binary=True)}</pre></div> <div class="left item last"><pre>${c.file.mimetype}</pre></div> <div class="buttons"> - ${h.link_to(_('show annotation'),h.url('files_annotate_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id,f_path=c.f_path),class_="ui-btn")} - ${h.link_to(_('show as raw'),h.url('files_raw_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id,f_path=c.f_path),class_="ui-btn")} - ${h.link_to(_('download as raw'),h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id,f_path=c.f_path),class_="ui-btn")} + ${h.link_to(_('show annotation'),h.url('files_annotate_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id,f_path=c.f_path),class_="ui-btn")} + ${h.link_to(_('show as raw'),h.url('files_raw_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id,f_path=c.f_path),class_="ui-btn")} + ${h.link_to(_('download as raw'),h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id,f_path=c.f_path),class_="ui-btn")} % if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name): % if not c.file.is_binary: - ${h.link_to(_('edit'),h.url('files_edit_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id,f_path=c.f_path),class_="ui-btn")} + ${h.link_to(_('edit'),h.url('files_edit_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id,f_path=c.f_path),class_="ui-btn")} % endif % endif </div> </div> <div class="author"> <div class="gravatar"> - <img alt="gravatar" src="${h.gravatar_url(h.email(c.file.last_changeset.author),16)}"/> + <img alt="gravatar" src="${h.gravatar_url(h.email(c.file.changeset.author),16)}"/> </div> - <div title="${c.file.last_changeset.author}" class="user">${h.person(c.file.last_changeset.author)}</div> + <div title="${c.file.changeset.author}" class="user">${h.person(c.file.changeset.author)}</div> </div> - <div class="commit">${h.urlify_commit(c.file.last_changeset.message,c.repo_name)}</div> + <div class="commit">${h.urlify_commit(c.file.changeset.message,c.repo_name)}</div> </div> <div class="code-body"> %if c.file.is_binary: @@ -46,7 +46,7 @@ ${h.pygmentize(c.file,linenos=True,anchorlinenos=True,lineanchors='L',cssclass="code-highlight")} %else: ${_('File is too big to display')} ${h.link_to(_('show as raw'), - h.url('files_raw_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id,f_path=c.f_path))} + h.url('files_raw_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id,f_path=c.f_path))} %endif <script type="text/javascript"> function highlight_lines(lines){
--- a/rhodecode/templates/index_base.html Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/templates/index_base.html Sat Mar 03 03:41:38 2012 +0200 @@ -126,8 +126,8 @@ </tr> </thead> <tbody> - %for cnt,repo in enumerate(c.repos_list,1): - <tr class="parity${cnt%2}"> + %for cnt,repo in enumerate(c.repos_list): + <tr class="parity${(cnt+1)%2}"> ##QUICK MENU <td class="quick_repo_menu"> ${dt.quick_menu(repo['name'])} @@ -172,7 +172,7 @@ </div> </div> <script> - YUD.get('repo_count').innerHTML = ${cnt}; + YUD.get('repo_count').innerHTML = ${cnt+1}; var func = function(node){ return node.parentNode.parentNode.parentNode.parentNode; }
--- a/rhodecode/tests/functional/test_files.py Tue Feb 28 20:55:14 2012 +0200 +++ b/rhodecode/tests/functional/test_files.py Sat Mar 03 03:41:38 2012 +0200 @@ -75,7 +75,7 @@ #test or history response.mustcontain("""<optgroup label="Changesets"> -<option selected="selected" value="8911406ad776fdd3d0b9932a2e89677e57405a48">r167:8911406ad776 (default)</option> +<option value="8911406ad776fdd3d0b9932a2e89677e57405a48">r167:8911406ad776 (default)</option> <option value="aa957ed78c35a1541f508d2ec90e501b0a9e3167">r165:aa957ed78c35 (default)</option> <option value="48e11b73e94c0db33e736eaeea692f990cb0b5f1">r140:48e11b73e94c (default)</option> <option value="adf3cbf483298563b968a6c673cd5bde5f7d5eea">r126:adf3cbf48329 (default)</option> @@ -110,23 +110,20 @@ <option value="3803844fdbd3b711175fc3da9bdacfcd6d29a6fb">r7:3803844fdbd3 (default)</option> </optgroup> <optgroup label="Branches"> -<option value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">default</option> +<option selected="selected" value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">default</option> <option value="97e8b885c04894463c51898e14387d80c30ed1ee">git</option> <option value="2e6a2bf9356ca56df08807f4ad86d480da72a8f4">web</option> </optgroup> <optgroup label="Tags"> -<option value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">tip</option> +<option selected="selected" value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">tip</option> <option value="fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200">0.1.4</option> <option value="17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">0.1.3</option> <option value="a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720">0.1.2</option> <option value="eb3a60fc964309c1a318b8dfe26aa2d1586c85ae">0.1.1</option> -</optgroup>""") +</optgroup> +""") - response.mustcontain("""<div class="commit">Partially implemented #16. filecontent/commit message/author/node name are safe_unicode now. -In addition some other __str__ are unicode as well -Added test for unicode -Improved test to clone into uniq repository. -removed extra unicode conversion in diff.</div>""") + response.mustcontain("""<div class="commit">merge</div>""") response.mustcontain("""<span style="text-transform: uppercase;"><a href="#">branch: default</a></span>""") @@ -139,7 +136,7 @@ response.mustcontain("""<optgroup label="Changesets"> -<option selected="selected" value="8911406ad776fdd3d0b9932a2e89677e57405a48">r167:8911406ad776 (default)</option> +<option value="8911406ad776fdd3d0b9932a2e89677e57405a48">r167:8911406ad776 (default)</option> <option value="aa957ed78c35a1541f508d2ec90e501b0a9e3167">r165:aa957ed78c35 (default)</option> <option value="48e11b73e94c0db33e736eaeea692f990cb0b5f1">r140:48e11b73e94c (default)</option> <option value="adf3cbf483298563b968a6c673cd5bde5f7d5eea">r126:adf3cbf48329 (default)</option> @@ -174,18 +171,17 @@ <option value="3803844fdbd3b711175fc3da9bdacfcd6d29a6fb">r7:3803844fdbd3 (default)</option> </optgroup> <optgroup label="Branches"> -<option value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">default</option> +<option selected="selected" value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">default</option> <option value="97e8b885c04894463c51898e14387d80c30ed1ee">git</option> <option value="2e6a2bf9356ca56df08807f4ad86d480da72a8f4">web</option> </optgroup> <optgroup label="Tags"> -<option value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">tip</option> +<option selected="selected" value="27cd5cce30c96924232dffcd24178a07ffeb5dfc">tip</option> <option value="fd4bdb5e9b2a29b4393a4ac6caef48c17ee1a200">0.1.4</option> <option value="17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">0.1.3</option> <option value="a7e60bff65d57ac3a1a1ce3b12a70f8a9e8a7720">0.1.2</option> <option value="eb3a60fc964309c1a318b8dfe26aa2d1586c85ae">0.1.1</option> -</optgroup> -""") +</optgroup>""") response.mustcontain("""<span style="text-transform: uppercase;"><a href="#">branch: default</a></span>""")