⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 changeset.py

📁 trac是一款svn服务器的web客户端
💻 PY
📖 第 1 页 / 共 3 页
字号:
                ignore_case = options.get('ignorecase')                ignore_space = options.get('ignorewhitespace')                if not old_node_info[0]:                    old_node_info = new_node_info # support for 'A'dd changes                req.write('Index: ' + new_path + CRLF)                req.write('=' * 67 + CRLF)                req.write('--- %s (revision %s)' % old_node_info + CRLF)                req.write('+++ %s (revision %s)' % new_node_info + CRLF)                for line in unified_diff(old_content.splitlines(),                                         new_content.splitlines(), context,                                         ignore_blank_lines=ignore_blank_lines,                                         ignore_case=ignore_case,                                         ignore_space_changes=ignore_space):                    req.write(line + CRLF)        raise RequestDone    def _render_zip(self, req, filename, repos, data):        """ZIP archive with all the added and/or modified files."""        new_rev = data['new_rev']        req.send_response(200)        req.send_header('Content-Type', 'application/zip')        req.send_header('Content-Disposition',                        content_disposition('inline;', filename + '.zip'))        from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED        buf = StringIO()        zipfile = ZipFile(buf, 'w', ZIP_DEFLATED)        for old_node, new_node, kind, change in repos.get_changes(            new_path=data['new_path'], new_rev=data['new_rev'],            old_path=data['old_path'], old_rev=data['old_rev']):            if kind == Node.FILE and change != Changeset.DELETE:                assert new_node                zipinfo = ZipInfo()                zipinfo.filename = new_node.path.strip('/').encode('utf-8')                # Note: unicode filenames are not supported by zipfile.                # UTF-8 is not supported by all Zip tools either,                # but as some does, I think UTF-8 is the best option here.                zipinfo.date_time = new_node.last_modified.utctimetuple()[:6]                zipinfo.compress_type = ZIP_DEFLATED                zipfile.writestr(zipinfo, new_node.get_content().read())        zipfile.close()        buf.seek(0, 2) # be sure to be at the end        req.send_header("Content-Length", buf.tell())        req.end_headers()        req.write(buf.getvalue())        raise RequestDone    def title_for_diff(self, data):        if data['new_path'] == data['old_path']: # ''diff between 2 revisions'' mode            return 'Diff r%s:%s for %s' \                   % (data['old_rev'] or 'latest', data['new_rev'] or 'latest',                      data['new_path'] or '/')        else:                              # ''generalized diff'' mode            return 'Diff from %s@%s to %s@%s' \                   % (data['old_path'] or '/', data['old_rev'] or 'latest',                      data['new_path'] or '/', data['new_rev'] or 'latest')    def render_property_diff(self, name, old_node, old_props,                             new_node, new_props, options):        """Renders diffs of a node property to HTML."""        candidates = []        for renderer in self.property_diff_renderers:            quality = renderer.match_property_diff(name)            if quality > 0:                candidates.append((quality, renderer))        if candidates:            renderer = sorted(candidates, reverse=True)[0][1]            return renderer.render_property_diff(name, old_node, old_props,                                                 new_node, new_props, options)        else:            return None    def _get_location(self, files):        return '/'.join(os.path.commonprefix([f.split('/') for f in files]))    def _prepare_filestats(self):        filestats = {}        for chg in Changeset.ALL_CHANGES:            filestats[chg] = 0        return filestats    # ITimelineEventProvider methods    def get_timeline_filters(self, req):        if 'CHANGESET_VIEW' in req.perm:            yield ('changeset', _('Repository checkins'))    def get_timeline_events(self, req, start, stop, filters):        if 'changeset' in filters:            show_files = self.timeline_show_files            show_location = show_files == 'location'            if show_files in ('-1', 'unlimited'):                show_files = -1            elif show_files.isdigit():                show_files = int(show_files)            else:                show_files = 0 # disabled                        repos = self.env.get_repository(req.authname)            if self.timeline_collapse:                collapse_changesets = lambda c: (c.author, c.message)            else:                collapse_changesets = lambda c: c.rev                            for _, changesets in groupby(repos.get_changesets(start, stop),                                         key=collapse_changesets):                permitted_changesets = []                for chgset in changesets:                    if 'CHANGESET_VIEW' in req.perm('changeset', chgset.rev):                        permitted_changesets.append(chgset)                if permitted_changesets:                    chgset = permitted_changesets[-1]                    yield ('changeset', chgset.date, chgset.author,                           (permitted_changesets, chgset.message or '',                            show_location, show_files))    def render_timeline_event(self, context, field, event):        changesets, message, show_location, show_files = event[3]        rev_b, rev_a = changesets[0].rev, changesets[-1].rev                if field == 'url':            if rev_a == rev_b:                return context.href.changeset(rev_a)            else:                return context.href.log(rev=rev_b, stop_rev=rev_a)                    elif field == 'description':            if not self.timeline_long_messages:                message = shorten_line(message)            if self.wiki_format_messages:                markup = ''            else:                markup = message                message = None            if 'BROWSER_VIEW' in context.perm:                files = []                if show_location:                    filestats = self._prepare_filestats()                    for c in changesets:                        for chg in c.get_changes():                            filestats[chg[2]] += 1                            files.append(chg[0])                    stats = [(tag.div(class_=kind),                              tag.span(count, ' ',                                       count > 1 and                                       (kind == 'copy' and                                        'copies' or kind + 's') or kind))                             for kind in Changeset.ALL_CHANGES                             for count in (filestats[kind],) if count]                    markup = tag.ul(                        tag.li(stats, ' in ',                               tag.strong(self._get_location(files))),                        markup, class_="changes")                elif show_files:                    for c in changesets:                        for chg in c.get_changes():                            if show_files > 0 and len(files) > show_files:                                break                            files.append(tag.li(tag.div(class_=chg[2]),                                                chg[0] or '/'))                    if show_files > 0 and len(files) > show_files:                        files = files[:show_files] + [tag.li(u'\u2026')]                    markup = tag(tag.ul(files, class_="changes"), markup)            if message:                markup += format_to_html(self.env, context, message)            return markup        if rev_a == rev_b:            title = tag('Changeset ', tag.em('[%s]' % rev_a))        else:            title = tag('Changesets ', tag.em('[', rev_a, '-', rev_b, ']'))                    if field == 'title':            return title        elif field == 'summary':            return '%s: %s' % (title, shorten_line(message))            # IWikiSyntaxProvider methods    CHANGESET_ID = r"(?:\d+|[a-fA-F\d]{8,})" # only "long enough" hexa ids    def get_wiki_syntax(self):        yield (            # [...] form: start with optional intertrac: [T... or [trac ...            r"!?\[(?P<it_changeset>%s\s*)" % WikiParser.INTERTRAC_SCHEME +            # hex digits + optional /path for the restricted changeset            # + optional query and fragment            r"%s(?:/[^\]]*)?(?:\?[^\]]*)?(?:#[^\]]*)?\]|" % self.CHANGESET_ID +            # r... form: allow r1 but not r1:2 (handled by the log syntax)            r"(?:\b|!)r\d+\b(?!:\d)",            lambda x, y, z:            self._format_changeset_link(x, 'changeset',                                        y[0] == 'r' and y[1:] or y[1:-1],                                        y, z))    def get_link_resolvers(self):        yield ('changeset', self._format_changeset_link)        yield ('diff', self._format_diff_link)    def _format_changeset_link(self, formatter, ns, chgset, label,                               fullmatch=None):        intertrac = formatter.shorthand_intertrac_helper(ns, chgset, label,                                                         fullmatch)        if intertrac:            return intertrac        chgset, params, fragment = formatter.split_link(chgset)        sep = chgset.find('/')        if sep > 0:            rev, path = chgset[:sep], chgset[sep:]        else:            rev, path = chgset, None        try:            changeset = self.env.get_repository().get_changeset(rev)            return tag.a(label, class_="changeset",                         title=shorten_line(changeset.message),                         href=(formatter.href.changeset(rev, path) +                               params + fragment))        except TracError, e:            return tag.a(label, class_="missing changeset",                         href=formatter.href.changeset(rev, path),                         title=unicode(e), rel="nofollow")    def _format_diff_link(self, formatter, ns, target, label):        params, query, fragment = formatter.split_link(target)        def pathrev(path):            if '@' in path:                return path.split('@', 1)            else:                return (path, None)        if '//' in params:            p1, p2 = params.split('//', 1)            old, new = pathrev(p1), pathrev(p2)            data = {'old_path': old[0], 'old_rev': old[1],                    'new_path': new[0], 'new_rev': new[1]}        else:            old_path, old_rev = pathrev(params)            new_rev = None            if old_rev and ':' in old_rev:                old_rev, new_rev = old_rev.split(':', 1)            data = {'old_path': old_path, 'old_rev': old_rev,                    'new_path': old_path, 'new_rev': new_rev}        title = self.title_for_diff(data)        href = None        if any(data.values()):            if query:                query = '&' + query[1:]            href = formatter.href.changeset(new_path=data['new_path'] or None,                                            new=data['new_rev'],                                            old_path=data['old_path'] or None,                                            old=data['old_rev']) + query        return tag.a(label, class_="changeset", title=title, href=href)    # ISearchSource methods    def get_search_filters(self, req):        if 'CHANGESET_VIEW' in req.perm:            yield ('changeset', _('Changesets'))    def get_search_results(self, req, terms, filters):        if not 'changeset' in filters:            return        repos = self.env.get_repository(req.authname)        db = self.env.get_db_cnx()        sql, args = search_to_sql(db, ['rev', 'message', 'author'], terms)        cursor = db.cursor()        cursor.execute("SELECT rev,time,author,message "                       "FROM revision WHERE " + sql, args)        for rev, ts, author, log in cursor:            if not repos.authz.has_permission_for_changeset(rev):                continue            yield (req.href.changeset(rev),                   '[%s]: %s' % (rev, shorten_line(log)),                   datetime.fromtimestamp(ts, utc), author,                   shorten_result(log, terms))class AnyDiffModule(Component):    implements(IRequestHandler)    # IRequestHandler methods    def match_request(self, req):        return re.match(r'/diff$', req.path_info)    def process_request(self, req):        repos = self.env.get_repository(req.authname)        if req.get_header('X-Requested-With') == 'XMLHttpRequest':            dirname, prefix = posixpath.split(req.args.get('q'))            prefix = prefix.lower()            node = repos.get_node(dirname)            def kind_order(entry):                def name_order(entry):                    return embedded_numbers(entry.name)                return entry.isfile, name_order(entry)            html = tag.ul(                [tag.li(is_dir and tag.b(path) or path)                 for e in sorted(node.get_entries(), key=kind_order)                 for is_dir, path in [(e.isdir, '/' + e.path.lstrip('/'))]                 if e.name.lower().startswith(prefix)]            )            req.write(html.generate().render('xhtml'))            return        # -- retrieve arguments        new_path = req.args.get('new_path')        new_rev = req.args.get('new_rev')        old_path = req.args.get('old_path')        old_rev = req.args.get('old_rev')        # -- normalize        new_path = repos.normalize_path(new_path)        if not new_path.startswith('/'):            new_path = '/' + new_path        new_rev = repos.normalize_rev(new_rev)        old_path = repos.normalize_path(old_path)        if not old_path.startswith('/'):            old_path = '/' + old_path        old_rev = repos.normalize_rev(old_rev)        repos.authz.assert_permission_for_changeset(new_rev)        repos.authz.assert_permission_for_changeset(old_rev)        # -- prepare rendering        data = {'new_path': new_path, 'new_rev': new_rev,                'old_path': old_path, 'old_rev': old_rev}        add_script(req, 'common/js/suggest.js')        return 'diff_form.html', data, None

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -