Mercurial > kallithea
changeset 2385:a455b2c79c85 beta
Improved RSS/ATOM feeds
- rewrote using new diff lib
- added shorter commit as title and full commit message in body
- increased feed size from 10 to 20 entries
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Mon, 04 Jun 2012 18:40:39 +0200 |
parents | 5563af834d92 |
children | ed8c2fc8dd3b |
files | rhodecode/controllers/api/api.py rhodecode/controllers/feed.py rhodecode/lib/diffs.py |
diffstat | 3 files changed, 68 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/rhodecode/controllers/api/api.py Mon Jun 04 17:26:34 2012 +0200 +++ b/rhodecode/controllers/api/api.py Mon Jun 04 18:40:39 2012 +0200 @@ -544,6 +544,15 @@ raise JSONRPCError('failed to create repository %s' % repo_name) @HasPermissionAnyDecorator('hg.admin') + def fork_repo(self, apiuser, repoid): + repo = RepoModel().get_repo(repoid) + if repo is None: + raise JSONRPCError('unknown repository "%s"' % (repo or repoid)) + + RepoModel().create_fork(form_data, cur_user) + + + @HasPermissionAnyDecorator('hg.admin') def delete_repo(self, apiuser, repo_name): """ Deletes a given repository
--- a/rhodecode/controllers/feed.py Mon Jun 04 17:26:34 2012 +0200 +++ b/rhodecode/controllers/feed.py Mon Jun 04 18:40:39 2012 +0200 @@ -28,11 +28,12 @@ from pylons import url, response, tmpl_context as c from pylons.i18n.translation import _ -from rhodecode.lib.utils2 import safe_unicode +from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed + +from rhodecode.lib import helpers as h from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.base import BaseRepoController - -from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed +from rhodecode.lib.diffs import DiffProcessor log = logging.getLogger(__name__) @@ -49,31 +50,36 @@ self.title = self.title = _('%s %s feed') % (c.rhodecode_name, '%s') self.language = 'en-us' self.ttl = "5" - self.feed_nr = 10 + self.feed_nr = 20 def _get_title(self, cs): - return "R%s:%s - %s" % ( - cs.revision, cs.short_id, cs.message + return "%s" % ( + h.shorter(cs.message, 160) ) def __changes(self, cs): changes = [] - a = [safe_unicode(n.path) for n in cs.added] - if a: - changes.append('\nA ' + '\nA '.join(a)) - - m = [safe_unicode(n.path) for n in cs.changed] - if m: - changes.append('\nM ' + '\nM '.join(m)) + diffprocessor = DiffProcessor(cs.diff()) + stats = diffprocessor.prepare(inline_diff=False) + for st in stats: + st.update({'added': st['stats'][0], + 'removed': st['stats'][1]}) + changes.append('\n %(operation)s %(filename)s ' + '(%(added)s lines added, %(removed)s lines removed)' + % st) + return changes - d = [safe_unicode(n.path) for n in cs.removed] - if d: - changes.append('\nD ' + '\nD '.join(d)) - - changes.append('</pre>') - - return ''.join(changes) + def __get_desc(self, cs): + desc_msg = [] + desc_msg.append('%s %s %s:<br/>' % (cs.author, _('commited on'), + cs.date)) + desc_msg.append('<pre>') + desc_msg.append(cs.message) + desc_msg.append('\n') + desc_msg.extend(self.__changes(cs)) + desc_msg.append('</pre>') + return desc_msg def atom(self, repo_name): """Produce an atom-1.0 feed via feedgenerator module""" @@ -87,15 +93,13 @@ ) for cs in reversed(list(c.rhodecode_repo[-self.feed_nr:])): - desc_msg = [] - desc_msg.append('%s - %s<br/><pre>' % (cs.author, cs.date)) - desc_msg.append(self.__changes(cs)) - feed.add_item(title=self._get_title(cs), link=url('changeset_home', repo_name=repo_name, revision=cs.raw_id, qualified=True), author_name=cs.author, - description=''.join(desc_msg)) + description=''.join(self.__get_desc(cs)), + pubdate=cs.date, + ) response.content_type = feed.mime_type return feed.writeString('utf-8') @@ -112,15 +116,12 @@ ) for cs in reversed(list(c.rhodecode_repo[-self.feed_nr:])): - desc_msg = [] - desc_msg.append('%s - %s<br/><pre>' % (cs.author, cs.date)) - desc_msg.append(self.__changes(cs)) - feed.add_item(title=self._get_title(cs), link=url('changeset_home', repo_name=repo_name, revision=cs.raw_id, qualified=True), author_name=cs.author, - description=''.join(desc_msg), + description=''.join(self.__get_desc(cs)), + pubdate=cs.date, ) response.content_type = feed.mime_type
--- a/rhodecode/lib/diffs.py Mon Jun 04 17:26:34 2012 +0200 +++ b/rhodecode/lib/diffs.py Mon Jun 04 18:40:39 2012 +0200 @@ -128,7 +128,7 @@ """ _chunk_re = re.compile(r'@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)') - def __init__(self, diff, differ='diff', format='udiff'): + def __init__(self, diff, differ='diff', format='gitdiff'): """ :param diff: a text in diff format or generator :param format: format of diff passed, `udiff` or `gitdiff` @@ -171,7 +171,7 @@ def _extract_rev(self, line1, line2): """ - Extract the filename and revision hint from a line. + Extract the operation (A/M/D), filename and revision hint from a line. """ try: @@ -189,11 +189,15 @@ filename = (old_filename if old_filename != '/dev/null' else new_filename) - return filename, new_rev, old_rev + operation = 'D' if new_filename == '/dev/null' else None + if not operation: + operation = 'M' if old_filename != '/dev/null' else 'A' + + return operation, filename, new_rev, old_rev except (ValueError, IndexError): pass - return None, None, None + return None, None, None, None def _parse_gitdiff(self, diffiterator): def line_decoder(l): @@ -278,7 +282,7 @@ do(line) do(next_) - def _parse_udiff(self): + def _parse_udiff(self, inline_diff=True): """ Parse the diff an return data for the template. """ @@ -293,13 +297,16 @@ continue chunks = [] - filename, old_rev, new_rev = \ + stats = [0, 0] + operation, filename, old_rev, new_rev = \ self._extract_rev(line, lineiter.next()) files.append({ 'filename': filename, 'old_revision': old_rev, 'new_revision': new_rev, - 'chunks': chunks + 'chunks': chunks, + 'operation': operation, + 'stats': stats, }) line = lineiter.next() @@ -331,7 +338,6 @@ }) line = lineiter.next() - while old_line < old_end or new_line < new_end: if line: command, line = line[0], line[1:] @@ -345,9 +351,11 @@ elif command == '+': affects_new = True action = 'add' + stats[0] += 1 elif command == '-': affects_old = True action = 'del' + stats[1] += 1 else: affects_old = affects_new = True action = 'unmod' @@ -371,13 +379,16 @@ }) line = lineiter.next() - except StopIteration: pass + sorter = lambda info: {'A': 0, 'M': 1, 'D': 2}.get(info['operation']) + if inline_diff is False: + return sorted(files, key=sorter) + # highlight inline changes - for _ in files: - for chunk in chunks: + for diff_data in files: + for chunk in diff_data['chunks']: lineiter = iter(chunk) try: while 1: @@ -391,14 +402,14 @@ except StopIteration: pass - return files + return sorted(files, key=sorter) - def prepare(self): + def prepare(self, inline_diff=True): """ Prepare the passed udiff for HTML rendering. It'l return a list of dicts """ - return self._parse_udiff() + return self._parse_udiff(inline_diff=inline_diff) def _safe_id(self, idstring): """Make a string safe for including in an id attribute. @@ -432,7 +443,7 @@ def as_html(self, table_class='code-difftable', line_class='line', new_lineno_class='lineno old', old_lineno_class='lineno new', - code_class='code', enable_comments=False): + code_class='code', enable_comments=False, diff_lines=None): """ Return udiff as html table with customized css classes """ @@ -448,7 +459,8 @@ } else: return label - diff_lines = self.prepare() + if diff_lines is None: + diff_lines = self.prepare() _html_empty = True _html = [] _html.append('''<table class="%(table_class)s">\n''' % {