Пример #1
0
 def render_timeline_event(self, context, field, event):
     bp_resource, bp, bc = event[3]
     compat_format_0_11_2 = 'oneliner'
     if hasattr(context, '_hints'):
          compat_format_0_11_2 = None
     if bc: # A blog comment
         if field == 'url':
             return context.href.blog(bp.name) + '#comment-%d' % bc.number
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title), ' comment added')
         elif field == 'description':
             comment = compat_format_0_11_2 and shorten_line(bc.comment) \
                         or bc.comment
             return format_to(self.env, compat_format_0_11_2,
                         context(resource=bp_resource), comment)
     else: # A blog post
         if field == 'url':
             return context.href.blog(bp.name)
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title),
                     bp.version > 1 and ' edited' or ' created')
         elif field == 'description':
             comment = compat_format_0_11_2 and shorten_line(bp.version_comment) \
                         or bp.version_comment
             return format_to(self.env, compat_format_0_11_2,
                     context(resource=bp_resource), comment)
Пример #2
0
 def short_value(self):
     if self.is_scalar:
         if isinstance(self.value, basestring):
             value = self.value
             if not isinstance(self.value, unicode):
                 value = unicode(self.value, 'utf-8', 'replace')
             return tag.q(shorten_line(value, 60)).generate()
         else:
             return shorten_line(repr(self.value), 60)
     elif self.is_collection:
         if isinstance(self.value, (dict, DictMixin)):
             return u'{…}'
         elif isinstance(self.value, list):
             return u'[…]'
         elif isinstance(self.value, tuple):
             return u'(…)'
         elif isinstance(self.value, set):
             return u'set([…])'
         elif isinstance(self.value, frozenset):
             return u'frozenset([…])'
     else:
         try:
             return tag.code(shorten_line(str(self.value), 60))
         except:
             return '?'
Пример #3
0
 def render_timeline_event(self, context, field, event):
     bp_resource, bp, bc = event[3]
     compat_format_0_11_2 = 'oneliner'
     if hasattr(context, '_hints'):
         compat_format_0_11_2 = None
     if bc:  # A blog comment
         if field == 'url':
             return context.href.blog(bp.name) + '#comment-%d' % bc.number
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title), ' comment added')
         elif field == 'description':
             comment = compat_format_0_11_2 and shorten_line(bc.comment) \
                         or bc.comment
             return format_to(self.env, compat_format_0_11_2,
                              context(resource=bp_resource), comment)
     else:  # A blog post
         if field == 'url':
             return context.href.blog(bp.name)
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title),
                        bp.version > 1 and ' edited' or ' created')
         elif field == 'description':
             comment = compat_format_0_11_2 and shorten_line(bp.version_comment) \
                         or bp.version_comment
             return format_to(self.env, compat_format_0_11_2,
                              context(resource=bp_resource), comment)
Пример #4
0
def _ticket_links(env, formatter, t, a_class=""):
    """Build links to tickets."""
    tkt_id = str(t.get("id"))
    status = t.get("status")
    summary = to_unicode(t.get("summary"))
    owner = to_unicode(t.get("owner"))
    description = to_unicode(t.get("description"))
    url = t.get("href")

    if status == "closed":
        a_class = a_class + "closed"
    else:
        a_class = a_class + "open"

    # Reduce content for tooltips.
    markup = format_to_html(env, formatter.context, description)
    extractor = TextExtractor()
    extractor.feed(markup)
    tip = tag.span(shorten_line(extractor.getvalue()))

    ticket = tag.a("#" + tkt_id, href=url)
    ticket(tip, class_="tip", target="_blank")
    ticket = tag.div(ticket, class_=a_class, align="left")
    # Fix stripping of regular leading space in IE.
    blank = " "
    ticket(Markup(blank), summary, " (", owner, ")")

    summary = tag(summary, " (", owner, ")")
    ticket_short = tag.span(tag.a("#" + tkt_id, href=url, target="_blank", title_=summary), class_=a_class)
    return ticket, ticket_short
Пример #5
0
 def render_timeline_event(self, context, field, event):
     ticket,summary,status,resolution,type, started, comment = event[4]
     if field == 'url':
         return context.href.ticket(ticket.id)
     elif field == 'title':
         title = TicketSystem(self.env).format_summary(summary, status,
                                                       resolution, type)
         return tag('Work ', started and 'stopped' or 'started',
                    ' on Ticket ', tag.em('#', ticket.id, title=title),
                    ' (', shorten_line(summary), ') ')
     elif field == 'description':
         if self.config['timeline'].getbool('abbreviated_messages'):
             comment = shorten_line(comment)
         markup = format_to_oneliner(self.env, context(resource=ticket),
                                     comment)
         return markup
Пример #6
0
    def train(self, req, log_id, spam=True):
        environ = {}
        for name, value in req.environ.items():
            if not name.startswith('HTTP_'):
                environ[name] = value

        entry = LogEntry.fetch(self.env, log_id)
        if entry:
            self.log.debug('Marking as %s: %r submitted by "%s"',
                           spam and 'spam' or 'ham',
                           shorten_line(entry.content),
                           entry.author)
            fakeenv = environ.copy()
            for header in entry.headers.splitlines():
                name, value = header.split(':', 1)
                if name == 'Cookie': # breaks SimpleCookie somehow
                    continue
                cgi_name = 'HTTP_%s' % name.strip().replace('-', '_').upper()
                fakeenv[cgi_name] = value.strip()
            fakeenv['REQUEST_METHOD'] = 'POST'
            fakeenv['PATH_INFO'] = entry.path
            fakeenv['wsgi.input'] = StringIO('')
            fakeenv['REMOTE_ADDR'] = entry.ipnr
            if entry.authenticated:
                fakeenv['REMOTE_USER'] = entry.author

            for strategy in self.strategies:
                strategy.train(Request(fakeenv, None),
                               entry.author or 'anonymous',
                               entry.content, spam=spam)

            entry.update(rejected=spam)
Пример #7
0
 def get_search_results(self, req, terms, filters):
     """
     Search through requirements.
     
     The search term may be <x y z> or x-y-z; both are interpreted as
     component, fp, and object.
     """
     
     if not 'requirement' in filters:
         return
     
     if re.match(r'^([a-zA-Z_\d]+)-([a-zA-Z_\d]+)-([a-zA-Z_\d]+)$', terms[0]):
         terms = string.split(terms[0], '-')
         
     db = self.env.get_db_cnx()
     sql, args = search_to_sql(db, ['b.newvalue'], terms)
     sql2, args2 = search_to_sql(db, ['a.component', 'a.fp', 'a.object',
                                      'a.description', 'a.creator'], terms)
     
     cursor = db.cursor()
     cursor.execute("SELECT DISTINCT a.component, a.fp, a.object, "
                    "a.description, a.creator, a.time "
                    "FROM requirement a "
                    "LEFT JOIN requirement_change b "
                    "ON a.component = b.component AND a.fp = b.fp AND a.object = b.object "
                    "WHERE (b.field='comment' AND %s ) OR %s" % (sql, sql2),
                    args + args2)
     
     for component, fp, object, desc, creator, date in cursor:
         requirement = '<%s %s %s> ' % (component, fp, object)
         yield (req.href.requirement('%s-%s-%s' % (component, fp, object)),
                requirement + shorten_line(desc),
                date, creator, shorten_result(desc, terms))
Пример #8
0
    def get_search_results(self, req, terms, filters):
        if not 'wiki' in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = search_to_sql(db, ['w1.name', 'w1.author', 'w1.text'],
                                        terms)
        cursor = db.cursor()
        cursor.execute("SELECT w1.name,w1.time,w1.author,w1.text "
                       "FROM wiki w1,"
                       "(SELECT name,max(version) AS ver "
                       "FROM wiki GROUP BY name) w2 "
                       "WHERE w1.version = w2.ver AND w1.name = w2.name "
                       "AND " + sql_query, args)

        wiki_realm = Resource('wiki')
        for name, ts, author, text in cursor:
            page = wiki_realm(id=name)
            if 'WIKI_VIEW' in req.perm(page):
                yield (get_resource_url(self.env, page, req.href),
                       '%s: %s' % (name, shorten_line(text)),
                       datetime.fromtimestamp(ts, utc), author,
                       shorten_result(text, terms))
        
        # Attachments
        for result in AttachmentModule(self.env).get_search_results(
            req, wiki_realm, terms):
            yield result
Пример #9
0
    def changeset_added(self, repos, changeset):
        """Called after a changeset has been added to a repository."""
        #Index the commit message
        so = FullTextSearchObject(
                self.project, changeset.resource,
                title=u'[%s]: %s' % (changeset.rev,
                                       shorten_line(changeset.message)),
                oneline=shorten_result(changeset.message),
                body=changeset.message,
                author=changeset.author,
                created=changeset.date,
                changed=changeset.date,
                )
        self.backend.create(so, quiet=True)
        self._update_changeset(changeset)

        # Index the file contents of this revision, a changeset can involve
        # thousands of files - so submit in batches to avoid exceeding the
        # available file handles
        sos = (so for so in self._changes(repos, changeset))
        for chunk in grouper(sos, 25):
            try:
                self.backend.add(chunk, quiet=True)
                self.log.debug("Indexed %i repository changes at revision %i",
                               len(chunk), changeset.rev)
            finally:
                for so in chunk:
                    if hasattr(so.body, 'close'):
                        so.body.close()
Пример #10
0
def _ticket_links(env, formatter, t, a_class=''):
    """Build links to tickets."""
    tkt_id = str(t.get('id'))
    status = t.get('status')
    summary = to_unicode(t.get('summary'))
    owner = to_unicode(t.get('owner'))
    description = to_unicode(t.get('description'))
    url = t.get('href')

    if status == 'closed':
        a_class = a_class + 'closed'
    else:
        a_class = a_class + 'open'

    # Reduce content for tooltips.
    markup = format_to_html(env, formatter.context, description)
    extractor = TextExtractor()
    extractor.feed(markup)
    tip = tag.span(shorten_line(extractor.getvalue()))

    ticket = tag.a('#' + tkt_id, href=url)
    ticket(tip, class_='tip', target='_blank')
    ticket = tag.div(ticket, class_=a_class, align='left')
    # Fix stripping of regular leading space in IE.
    blank = '&nbsp;'
    ticket(Markup(blank), summary, ' (', owner, ')')

    summary = tag(summary, ' (', owner, ')')
    ticket_short = tag.span(tag.a('#' + tkt_id,
                                  href=url,
                                  target='_blank',
                                  title_=summary),
                            class_=a_class)
    return ticket, ticket_short
Пример #11
0
    def _format_sha_link(self, formatter, sha, label):
        # FIXME: this function needs serious rethinking...

        reponame = ''

        context = formatter.context
        while context:
            if context.resource.realm in ('source', 'changeset'):
                reponame = context.resource.parent.id
                break
            context = context.parent

        try:
            repos = RepositoryManager(self.env).get_repository(reponame)

            if not repos:
                raise Exception("Repository '%s' not found" % reponame)

            sha = repos.normalize_rev(sha) # in case it was abbreviated
            changeset = repos.get_changeset(sha)
            return tag.a(label, class_='changeset',
                         title=shorten_line(changeset.message),
                         href=formatter.href.changeset(sha, repos.reponame))
        except Exception as e:
            return tag.a(label, class_='missing changeset',
                         title=to_unicode(e), rel='nofollow')
Пример #12
0
    def get_search_results(self, req, terms, filters):
        if not 'wiki' in filters:
            return
        with self.env.db_query as db:
            sql_query, args = search_to_sql(
                db, ['w1.name', 'w1.author', 'w1.text'], terms)
            wiki_realm = Resource('wiki')
            for name, ts, author, text in db(
                    """
                    SELECT w1.name, w1.time, w1.author, w1.text
                    FROM wiki w1,(SELECT name, max(version) AS ver
                                  FROM wiki GROUP BY name) w2
                    WHERE w1.version = w2.ver AND w1.name = w2.name
                    AND """ + sql_query, args):
                page = wiki_realm(id=name)
                if 'WIKI_VIEW' in req.perm(page):
                    yield (get_resource_url(self.env, page, req.href),
                           '%s: %s' % (name, shorten_line(text)),
                           from_utimestamp(ts), author,
                           shorten_result(text, terms))

        # Attachments
        for result in AttachmentModule(self.env).get_search_results(
                req, wiki_realm, terms):
            yield result
Пример #13
0
    def _link_tickets(self, req, tickets, fetch_tickets=False):
        items = []

        for i, word in enumerate(re.split(r'([;,\s]+)', tickets or '')):
            if i % 2:
                items.append(word)
            elif word:
                try:
                    ticketid = int(word)
                except ValueError:
                    return None
                word = '#%s' % word

                if fetch_tickets:
                    try:
                        ticket = Ticket(self.env, ticketid)
                        if 'TICKET_VIEW' in req.perm(ticket.resource):
                            word = \
                                tag.a(
                                    '#%s' % ticket.id,
                                    class_=ticket['status'],
                                    href=req.href.ticket(int(ticket.id)),
                                    title=shorten_line(ticket['summary'])
                                )
                    except ResourceNotFound:
                        pass

                items.append(word)

        if items:
            return tag(items)
        else:
            return None
Пример #14
0
 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
     if 'CHANGESET_VIEW' in formatter.perm('changeset', rev):
         try:
             changeset = self.env.get_repository().get_changeset(rev)
             title = shorten_line(changeset.message)
         except TracError, e:
             title = None
         href = self._format_gitorious(path=path,
                                       rev=rev,
                                       obj_type="changeset")
         return tag.a(label, class_="changeset", href=href, title=title)
Пример #15
0
 def _link_refs(self, req, refs_text, verbose_link=False):
     items_tag = None
     items, verbose_items = [], []
     elem = verbose_elem = "#%s" % refs_text
     try:
         c = self.cursor
         c.execute("SELECT id,name FROM assets_feature WHERE id ='%s'" % refs_text)
         row = c.fetchone()
         if row:
             title = shorten_line(row[1])
             attr = {
                 "class_": "assigned",
                 "href": "/splice/tractab/SPLICE/projects/feature/" + str(row[0]),
                 "title": title,
             }
             elem = tag.a("#%s %s" % (refs_text, title), **attr)
             verbose_elem = tag.a("#%s %s" % (refs_text, title), **attr)
     except ResourceNotFound:
         pass  # not supposed to happen, just in case
     items.extend([elem, ", "])
     verbose_items.extend([verbose_elem, tag.br()])
     if items:
         items_tag = [tag.span(items[:-1], id="tref_ticketid")]
         if verbose_link:
             vattr = {"id": "tref_summary", "class_": "tref-display-none"}
             items_tag.append(tag.span(verbose_items[:-1], **vattr))
     return tag(items_tag)
Пример #16
0
    def changeset_added(self, repos, changeset):
        """Called after a changeset has been added to a repository."""
        #Index the commit message
        so = FullTextSearchObject(
            self.project,
            changeset.resource,
            title=u'[%s]: %s' %
            (changeset.rev, shorten_line(changeset.message)),
            oneline=shorten_result(changeset.message),
            body=changeset.message,
            author=changeset.author,
            created=changeset.date,
            changed=changeset.date,
        )
        self.backend.create(so, quiet=True)
        self._update_changeset(changeset)

        # Index the file contents of this revision, a changeset can involve
        # thousands of files - so submit in batches to avoid exceeding the
        # available file handles
        sos = (so for so in self._changes(repos, changeset))
        for chunk in grouper(sos, 25):
            try:
                self.backend.add(chunk, quiet=True)
                self.log.debug("Indexed %i repository changes at revision %i",
                               len(chunk), changeset.rev)
            finally:
                for so in chunk:
                    if hasattr(so.body, 'close'):
                        so.body.close()
Пример #17
0
    def _link_tickets(self, req, tickets):
        items = []

        for i, word in enumerate(re.split(r'([;,\s]+)', tickets)):
            if i % 2:
                items.append(word)
            elif word:
                ticketid = word
                word = '#%s' % word

                try:
                    ticket = Ticket(self.env, ticketid)
                    if 'TICKET_VIEW' in req.perm(ticket.resource):
                        word = \
                            tag.a(
                                '#%s' % ticket.id,
                                class_=ticket['status'],
                                href=req.href.ticket(int(ticket.id)),
                                title=shorten_line(ticket['summary'])
                            )
                except ResourceNotFound:
                    pass

                items.append(word)

        if items:
            return tag(items)
        else:
            return None
Пример #18
0
 def format_summary(self, summary, status=None, resolution=None, type=None):
     summary = shorten_line(summary)
     if type:
         summary = type + ': ' + summary
     if status:
         if status == 'closed' and resolution:
             status += ': ' + resolution
         return "%s (%s)" % (summary, status)
     else:
         return summary
Пример #19
0
 def format_summary(self, summary, status=None, resolution=None, type=None):
     summary = shorten_line(summary)
     if type:
         summary = type + ': ' + summary
     if status:
         if status == 'closed' and resolution:
             status += ': ' + resolution
         return "%s (%s)" % (summary, status)
     else:
         return summary
Пример #20
0
 def render_timeline_event(self, context, field, event):
     bp_resource, bp, bc = event[3]
     compat_format_0_11_2 = "oneliner"
     if hasattr(context, "_hints"):
         compat_format_0_11_2 = None
     if bc:  # A blog comment
         if field == "url":
             return context.href.blog(bp.name) + "#comment-%d" % bc.number
         elif field == "title":
             return tag("Blog: ", tag.em(bp.title), " comment added")
         elif field == "description":
             comment = compat_format_0_11_2 and shorten_line(bc.comment) or bc.comment
             return format_to(self.env, compat_format_0_11_2, context(resource=bp_resource), comment)
     else:  # A blog post
         if field == "url":
             return context.href.blog(bp.name)
         elif field == "title":
             return tag("Blog: ", tag.em(bp.title), bp.version > 1 and " edited" or " created")
         elif field == "description":
             comment = compat_format_0_11_2 and shorten_line(bp.version_comment) or bp.version_comment
             return format_to(self.env, compat_format_0_11_2, context(resource=bp_resource), comment)
 def _index_milestone(self, milestone):
     so = FullTextSearchObject(
         self.project,
         milestone.resource,
         title=u"%s: %s" % (milestone.name, shorten_line(milestone.description)),
         changed=milestone.completed or milestone.due or datetime.now(utc),
         involved=(),
         popularity=0,  # FIXME
         oneline=shorten_result(milestone.description),
         body=milestone.description,
     )
     self.backend.create(so, quiet=True)
Пример #22
0
 def _link_textarea(self, req, refs_text):
     items = []
     for ref_id in sorted(cnv_text2list(refs_text)):
         elem = u"#%s" % ref_id
         try:
             ticket = Ticket(self.env, ref_id)
             if "TICKET_VIEW" in req.perm(ticket.resource):
                 title = shorten_line(ticket["summary"])
                 elem = u"#%s %s" % (ref_id, title)
         except ResourceNotFound:
             pass  # not supposed to happen, just in case
         items.extend([elem, u", "])
     return u"".join(item for item in items[:-1])
Пример #23
0
    def test(self, req, author, content, ip):
        i = req.args.getfirst(self.name)
        h = req.args.getfirst(self.name_hidden)
        r = self.getlink(req)

        if i and h:
            i = shorten_line(javascript_quote(i), 50)
            h = shorten_line(javascript_quote(h), 50)
            return -abs(self.karma_points), \
                   N_("Both trap fields says this is spam (%s, %s)"), i, h
        elif i:
            i = shorten_line(javascript_quote(i), 50)
            return -abs(self.karma_points), \
                   N_("Invisible trap field says this is spam (%s)"), i
        elif h:
            h = shorten_line(javascript_quote(h), 50)
            return -abs(self.karma_points), \
                   N_("Hidden trap field says this is spam (%s)"), h
        elif r:
            r = shorten_line(javascript_quote(r), 50)
            return -abs(self.karma_points), \
                   N_("Register trap field starts with HTTP URL (%s)"), r
Пример #24
0
 def _link(resource):
     if resource.realm == 'tag':
         # Keep realm selection in tag links.
         return builder.a(resource.id,
                          href=self.get_href(req, tag=resource))
     elif resource.realm == 'ticket':
         # Return resource link including ticket status dependend
         #   class to allow for common Trac ticket link style.
         ticket = Ticket(env, resource.id)
         return builder.a('#%s' % ticket.id,
                          class_=ticket['status'],
                          href=formatter.href.ticket(ticket.id),
                          title=shorten_line(ticket['summary']))
     return render_resource_link(env, context, resource, 'compact')
Пример #25
0
 def render_property(self, name, mode, context, props):
     repos, value = props[name]
     if name == 'transplant_source':
         try:
             chgset = MercurialChangeset(repos, value)
             link = tag.a(chgset.rev, class_="changeset",
                          title=shorten_line(chgset.message),
                          href=context.href.changeset(short(value),
                                                      repos.reponame))
         except LookupError:
             link = tag.a(hex(value), class_="missing changeset",
                          title=_("no such changeset"), rel="nofollow")
         return RenderedProperty(name=_("Transplant:"), content=link,
                                 name_attributes=[("class", "property")])
Пример #26
0
 def milestone_created(self, milestone):
     so = FullTextSearchObject(
         self.project,
         milestone.resource,
         title=u'%s: %s' %
         (milestone.name, shorten_line(milestone.description)),
         changed=milestone.completed or milestone.due or datetime.now(utc),
         involved=(),
         popularity=0,  #FIXME
         oneline=shorten_result(milestone.description),
         body=milestone.description,
     )
     self.backend.create(so, quiet=True)
     self.log.debug("Milestone created for indexing: %s", milestone)
Пример #27
0
 def _link(resource):
     if resource.realm == 'tag':
         # Keep realm selection in tag links.
         return builder.a(resource.id,
                          href=self.get_href(req, tag=resource))
     elif resource.realm == 'ticket':
         # Return resource link including ticket status dependend
         #   class to allow for common Trac ticket link style.
         ticket = Ticket(env, resource.id)
         return builder.a('#%s' % ticket.id,
                          class_=ticket['status'],
                          href=formatter.href.ticket(ticket.id),
                          title=shorten_line(ticket['summary']))
     return render_resource_link(env, context, resource, 'compact')
Пример #28
0
    def get_timeline_events(self, req, start, stop, filters):
        if 'changeset' in filters:
            format = req.args.get('format')
            wiki_format = self.wiki_format_messages
            show_files = self.timeline_show_files
            db = self.env.get_db_cnx()
            repos = self.env.get_repository(req.authname)
            for chgset in repos.get_changesets(start, stop):
                message = chgset.message or '--'
                if wiki_format:
                    shortlog = wiki_to_oneliner(message, self.env, db,
                                                shorten=True)
                else:
                    shortlog = shorten_line(message)

                if format == 'rss':
                    title = Markup(u'변경사항 [%s]: %s', chgset.rev, shortlog)
                    href = req.abs_href.changeset(chgset.rev)
                    if wiki_format:
                        message = wiki_to_html(message, self.env, req, db,
                                               absurls=True)
                    else:
                        message = html.PRE(message)
                else:
                    title = Markup(u'변경사항 <em>[%s]</em> : %s에 의해 수정됨', chgset.rev,
                                   chgset.author)
                    href = req.href.changeset(chgset.rev)

                    if wiki_format:
                        if self.timeline_long_messages:
                            message = wiki_to_html(message, self.env, req, db,
                                                   absurls=True)
                        else:
                            message = wiki_to_oneliner(message, self.env, db,
                                                       shorten=True)
                    else:
                        message = shortlog

                if show_files and req.perm.has_permission('BROWSER_VIEW'):
                    files = []
                    for chg in chgset.get_changes():
                        if show_files > 0 and len(files) >= show_files:
                            files.append(html.LI(Markup('&hellip;')))
                            break
                        files.append(html.LI(html.DIV(class_=chg[2]),
                                             chg[0] or '/'))
                    message = html.UL(files, class_="changes") + message

                yield 'changeset', href, title, chgset.date, chgset.author,\
                      message
Пример #29
0
    def get_timeline_events(self, req, start, stop, filters):
        if 'changeset' in filters:
            format = req.args.get('format')
            wiki_format = self.wiki_format_messages
            show_files = self.timeline_show_files
            db = self.env.get_db_cnx()
            repos = self.env.get_repository(req.authname)
            for chgset in repos.get_changesets(start, stop):
                message = chgset.message or '--'
                if wiki_format:
                    shortlog = wiki_to_oneliner(message, self.env, db,
                                                shorten=True)
                else:
                    shortlog = shorten_line(message)

                if format == 'rss':
                    title = Markup('Changeset [%s]: %s', chgset.rev, shortlog)
                    href = req.abs_href.changeset(chgset.rev)
                    if wiki_format:
                        message = wiki_to_html(message, self.env, req, db,
                                               absurls=True)
                    else:
                        message = html.PRE(message)
                else:
                    title = Markup('Changeset <em>[%s]</em> by %s', chgset.rev,
                                   chgset.author)
                    href = req.href.changeset(chgset.rev)

                    if wiki_format:
                        if self.timeline_long_messages:
                            message = wiki_to_html(message, self.env, req, db,
                                                   absurls=True)
                        else:
                            message = wiki_to_oneliner(message, self.env, db,
                                                       shorten=True)
                    else:
                        message = shortlog

                if show_files and req.perm.has_permission('BROWSER_VIEW'):
                    files = []
                    for chg in chgset.get_changes():
                        if show_files > 0 and len(files) >= show_files:
                            files.append(html.LI(Markup('&hellip;')))
                            break
                        files.append(html.LI(html.DIV(class_=chg[2]),
                                             chg[0] or '/'))
                    message = html.UL(files, class_="changes") + message

                yield 'changeset', href, title, chgset.date, chgset.author,\
                      message
Пример #30
0
def get_changes(env, repos, revs, full=None, req=None, format=None):
    db = env.get_db_cnx()
    changes = {}
    for rev in revs:
        try:
            changeset = repos.get_changeset(rev)
        except NoSuchChangeset:
            changes[rev] = {}
            continue

        wiki_format = env.config['changeset'].getbool('wiki_format_messages')
        message = changeset.message or '--'
        absurls = (format == 'rss')
        if wiki_format:
            shortlog = wiki_to_oneliner(message,
                                        env,
                                        db,
                                        shorten=True,
                                        absurls=absurls)
        else:
            shortlog = Markup.escape(shorten_line(message))

        if full:
            if wiki_format:
                message = wiki_to_html(message,
                                       env,
                                       req,
                                       db,
                                       absurls=absurls,
                                       escape_newlines=True)
            else:
                message = html.PRE(message)
        else:
            message = shortlog

        if format == 'rss':
            if isinstance(shortlog, Markup):
                shortlog = shortlog.plaintext(keeplinebreaks=False)
            message = unicode(message)

        changes[rev] = {
            'date_seconds': changeset.date,
            'date': format_datetime(changeset.date),
            'age': pretty_timedelta(changeset.date),
            'author': changeset.author or 'anonymous',
            'message': message,
            'shortlog': shortlog,
        }
    return changes
Пример #31
0
 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, ['message', 'author'], terms)
     cursor = db.cursor()
     cursor.execute("SELECT rev,time,author,message "
                    "FROM revision WHERE " + sql, args)
     for rev, date, 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)),
                date, author, shorten_result(log, terms))
Пример #32
0
 def _link_ticket_by_id(self, req, ticketid):
     ret = None
     try:
         ticket = Ticket(self.env, ticketid)
         if 'TICKET_VIEW' in req.perm(ticket.resource):
             ret = \
                 tag.a(
                     '#%s' % ticket.id,
                     class_=ticket['status'],
                     href=req.href.ticket(int(ticket.id)),
                     title=shorten_line(ticket['summary'])
                 )
     except ResourceNotFound:
         pass
     return ret
Пример #33
0
 def _format_revision_link(self, formatter, ns, reponame, rev, label,
                           fullmatch=None):
     rev, params, fragment = formatter.split_link(rev)
     try:
         repos = RepositoryManager(self.env).get_repository(reponame)
         if repos:
             changeset = repos.get_changeset(rev)
             return tag.a(label, class_="changeset",
                          title=shorten_line(changeset.message),
                          href=(formatter.href.changeset(rev) +
                                params + fragment))
     except NoSuchChangeset:
         pass
     return tag.a(label, class_="missing changeset", rel="nofollow",
                  href=formatter.href.changeset(rev))
Пример #34
0
 def _link_ticket_by_id(self, req, ticketid):
     ret = None
     try:
         ticket = Ticket(self.env, ticketid)
         if 'TICKET_VIEW' in req.perm(ticket.resource):
             ret = \
                 tag.a(
                     '#%s' % ticket.id,
                     class_=ticket['status'],
                     href=req.href.ticket(int(ticket.id)),
                     title=shorten_line(ticket['summary'])
                 )
     except ResourceNotFound:
         pass
     return ret
 def changeset_added(self, repos, changeset):
     """Called after a changeset has been added to a repository."""
     #Index the commit message
     so = FullTextSearchObject(
             self.project, changeset.resource,
             title=u'[%s]: %s' % (changeset.rev,
                                    shorten_line(changeset.message)),
             oneline=shorten_result(changeset.message),
             body=changeset.message,
             author=changeset.author,
             created=changeset.date,
             changed=changeset.date,
             )
     self.backend.create(so, quiet=True)
     self._update_changeset(changeset)
Пример #36
0
    def format_subj(self, tickets_descr):
        template = self.config.get('notification', 'batch_subject_template')
        template = NewTextTemplate(template.encode('utf8'))

        prefix = self.config.get('notification', 'smtp_subject_prefix')
        if prefix == '__default__':
            prefix = '[%s]' % self.env.project_name

        data = {
            'prefix': prefix,
            'tickets_descr': tickets_descr,
            'env': self.env,
        }
        subj = template.generate(**data).render('text', encoding=None).strip()
        return shorten_line(subj)
Пример #37
0
 def _pydoc_formatter(self, formatter, ns, object, label):
     object = urllib.unquote(object)
     label = urllib.unquote(label)
     if not object or object == 'index':
         return html.a(label, class_='wiki', href=formatter.href.pydoc())
     else:
         try:
             _, target = PyDoc(self.env).load_object(object)
             doc = pydoc.getdoc(target)
             if doc: doc = doc.strip().splitlines()[0]
             return html.a(label, class_='wiki', title=shorten_line(doc),
                           href=formatter.href.pydoc(object))
         except ImportError:
             return html.a(label, class_='missing wiki',
                           href=formatter.href.pydoc(object))
Пример #38
0
 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, ['message', 'author'], terms)
     cursor = db.cursor()
     cursor.execute("SELECT rev,time,author,message "
                    "FROM revision WHERE " + sql, args)
     for rev, date, 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)),
                date, author, shorten_result(log, terms))
Пример #39
0
 def _format_revision_link(self, formatter, ns, reponame, rev, label,
                           fullmatch=None):
     rev, params, fragment = formatter.split_link(rev)
     try:
         repos = RepositoryManager(self.env).get_repository(reponame)
         if repos:
             changeset = repos.get_changeset(rev)
             return tag.a(label, class_="changeset",
                          title=shorten_line(changeset.message),
                          href=(formatter.href.changeset(rev) +
                                params + fragment))
     except NoSuchChangeset:
         pass
     return tag.a(label, class_="missing changeset", rel="nofollow",
                  href=formatter.href.changeset(rev))
Пример #40
0
    def format_subj(self, tickets_descr):
        template = self.config.get('notification', 'batch_subject_template')
        template = NewTextTemplate(template.encode('utf8'))

        prefix = self.config.get('notification', 'smtp_subject_prefix')
        if prefix == '__default__':
            prefix = '[%s]' % self.env.project_name

        data = {
            'prefix': prefix,
            'tickets_descr': tickets_descr,
            'env': self.env,
        }
        subj = template.generate(**data).render('text', encoding=None).strip()
        return shorten_line(subj)
 def add_bulk_changesets(self, changesets):
     sos = []
     for changeset in changesets:
         so = FullTextSearchObject(
                 self.project, changeset.resource,
                 title=u'[%s]: %s' % (changeset.rev,
                                     shorten_line(changeset.message)),
                 oneline=shorten_result(changeset.message),
                 body=changeset.message,
                 author=changeset.author,
                 created=changeset.date,
                 changed=changeset.date,
                 )
         self._update_changeset(changeset)
         sos.append(so)
     self.backend.add(sos, quiet=True)
Пример #42
0
    def get_search_results(self, req, terms, filters):
        if not 'wiki' in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = search_to_sql(db, ['w1.name', 'w1.author', 'w1.text'], terms)
        cursor = db.cursor()
        cursor.execute("SELECT w1.name,w1.time,w1.author,w1.text "
                       "FROM wiki w1,"
                       "(SELECT name,max(version) AS ver "
                       "FROM wiki GROUP BY name) w2 "
                       "WHERE w1.version = w2.ver AND w1.name = w2.name "
                       "AND " + sql_query, args)

        for name, date, author, text in cursor:
            yield (req.href.wiki(name), '%s: %s' % (name, shorten_line(text)),
                   date, author, shorten_result(text, terms))
Пример #43
0
    def _format_subj_batchmodify(self, tickets):
        tickets_descr = ', '.join('#%s' % t for t in tickets)

        template = jinja2template(self.batch_subject_template, text=True)

        prefix = self.config.get('notification', 'smtp_subject_prefix')
        if prefix == '__default__':
            prefix = '[%s]' % self.env.project_name

        data = {
            'prefix': prefix,
            'tickets_descr': tickets_descr,
            'env': self.env,
        }
        subj = template.render(**data).strip()
        return shorten_line(subj)
Пример #44
0
        def sha_link(sha, label=None):
            # sha is assumed to be a non-abbreviated 40-chars sha id
            try:
                reponame = context.resource.parent.id
                repos = RepositoryManager(self.env).get_repository(reponame)
                cset = repos.get_changeset(sha)
                if label is None:
                    label = repos.display_rev(sha)

                return tag.a(label, class_='changeset',
                             title=shorten_line(cset.message),
                             href=context.href.changeset(sha, repos.reponame))

            except Exception as e:
                return tag.a(sha, class_='missing changeset',
                             title=to_unicode(e), rel='nofollow')
Пример #45
0
 def ticket_anchor(ticket):
     try:
         pvalue = ticket.get('product') or GLOBAL_PRODUCT
         envhref = hrefcache[pvalue]
     except KeyError:
         try:
             env = lookup_product_env(self.env, prefix= pvalue,
                                      name=pvalue)
         except LookupError:
             return tag.a('#%s' % ticket['id'], 
                          class_='missing product')
         hrefcache[pvalue] = envhref = resolve_product_href(
                  to_env=env, at_env=self.env)
     return tag.a('#%s' % ticket['id'],
                  class_=ticket['status'],
                  href=envhref.ticket(int(ticket['id'])),
                  title=shorten_line(ticket['summary']))
Пример #46
0
 def _pydoc_formatter(self, formatter, ns, object, label):
     object = urllib.unquote(object)
     label = urllib.unquote(label)
     if not object or object == 'index':
         return html.a(label, class_='wiki', href=formatter.href.pydoc())
     else:
         try:
             _, target = PyDoc(self.env).load_object(object)
             doc = pydoc.getdoc(target)
             if doc: doc = doc.strip().splitlines()[0]
             return html.a(label,
                           class_='wiki',
                           title=shorten_line(doc),
                           href=formatter.href.pydoc(object))
         except ImportError:
             return html.a(label,
                           class_='missing wiki',
                           href=formatter.href.pydoc(object))
Пример #47
0
 def _format_link(self, formatter, ns, target, label, fullmatch=None):
     intertrac = formatter.shorthand_intertrac_helper(ns, target, label,
                                                      fullmatch)
     if intertrac:
         return intertrac
     try:
         cursor = formatter.db.cursor()
         cursor.execute("SELECT summary,status FROM ticket WHERE id=%s",
                        (str(int(target)),))
         row = cursor.fetchone()
         if row:
             return html.A(label, class_='%s ticket' % row[1],
                           title=shorten_line(row[0]) + ' (%s)' % row[1],
                           href=formatter.href.ticket(target))
     except ValueError:
         pass
     return html.A(label, class_='missing ticket', rel='nofollow',
                   href=formatter.href.ticket(target))
Пример #48
0
 def _format_link(self, formatter, ns, target, label, fullmatch=None):
     intertrac = formatter.shorthand_intertrac_helper(ns, target, label, fullmatch)
     if intertrac:
         return intertrac
     try:
         cursor = formatter.db.cursor()
         cursor.execute("SELECT summary,status FROM ticket WHERE id=%s", (str(int(target)),))
         row = cursor.fetchone()
         if row:
             return html.A(
                 label,
                 class_="%s ticket" % row[1],
                 title=shorten_line(row[0]) + " (%s)" % row[1],
                 href=formatter.href.ticket(target),
             )
     except ValueError:
         pass
     return html.A(label, class_="missing ticket", rel="nofollow", href=formatter.href.ticket(target))
 def _index_wiki_page(self, page):
     history = list(page.get_history())
     so = FullTextSearchObject(
         self.project,
         page.resource,
         title=u"%s: %s" % (page.name, shorten_line(page.text)),
         author=page.author,
         changed=page.time,
         created=history[-1][1],  # .time of oldest version
         tags=self._page_tags(page.resource.realm, page.name),
         involved=list(set(r[2] for r in history)),
         popularity=0,  # FIXME
         oneline=shorten_result(page.text),
         body=page.text,
         comments=[r[3] for r in history],
     )
     self.backend.create(so, quiet=True)
     self.log.debug("WikiPage created for indexing: %s", page.name)
    def _index_changeset(self, repos, changeset):
        # Index the commit message
        so = FullTextSearchObject(
            self.project,
            changeset.resource,
            title=u"[%s]: %s" % (changeset.rev, shorten_line(changeset.message)),
            oneline=shorten_result(changeset.message),
            body=changeset.message,
            author=changeset.author,
            created=changeset.date,
            changed=changeset.date,
        )
        success = self.backend.create(so, quiet=True)

        if not self.fulltext_index_svn_nodes:
            return

        def _changes(repos, changeset):
            for path, kind, change, base_path, base_rev in changeset.get_changes():
                if change == Changeset.MOVE:
                    yield FullTextSearchObject(self.project, "source", base_path, repos.resource, action="DELETE")
                elif change == Changeset.DELETE:
                    yield FullTextSearchObject(self.project, "source", path, repos.resource, action="DELETE")
                if change in (Changeset.ADD, Changeset.EDIT, Changeset.COPY, Changeset.MOVE):
                    node = repos.get_node(path, changeset.rev)
                    so = FullTextSearchObject(
                        self.project,
                        node.resource,
                        title=node.path,
                        oneline=u"[%s]: %s" % (changeset.rev, shorten_result(changeset.message)),
                        comments=[changeset.message],
                        changed=node.get_last_modified(),
                        author=changeset.author,
                        created=changeset.date,
                    )
                    if node.content_length <= self.max_size:
                        stream = node.get_content()
                        if stream:
                            so.body = stream.read()
                            so.extract = True
                    yield so

        for so in _changes(repos, changeset):
            self.backend.create(so, quiet=True)
Пример #51
0
    def get_search_results(self, req, terms, filters):
        if not 'wiki' in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = search_to_sql(db,
                                        ['w1.name', 'w1.author', 'w1.text'],
                                        terms)
        cursor = db.cursor()
        cursor.execute(
            "SELECT w1.name,w1.time,w1.author,w1.text "
            "FROM wiki w1,"
            "(SELECT name,max(version) AS ver "
            "FROM wiki GROUP BY name) w2 "
            "WHERE w1.version = w2.ver AND w1.name = w2.name "
            "AND " + sql_query, args)

        for name, date, author, text in cursor:
            yield (req.href.wiki(name), '%s: %s' % (name, shorten_line(text)),
                   date, author, shorten_result(text, terms))
Пример #52
0
 def _format_link(self, formatter, ns, rev, label):
     repos = self.env.get_repository()
     if ns == 'branch':
         for b, head in repos.get_branches():
             if b == rev:
                 rev = head
                 break
     try:
         chgset = repos.get_changeset(rev)
         return html.a(label,
                       class_="changeset",
                       title=shorten_line(chgset.message),
                       href=formatter.href.changeset(rev))
     except NoSuchChangeset, e:
         return html.a(label,
                       class_="missing changeset",
                       title=to_unicode(e),
                       rel="nofollow",
                       href=formatter.href.changeset(rev))
Пример #53
0
    def format(self, text, out, shorten=False):
        if not text:
            return
        self.out = out
        self._open_tags = []

        # Simplify code blocks
        in_code_block = 0
        processor = None
        buf = StringIO()
        for line in text.strip().splitlines():
            if line.strip() == WikiParser.STARTBLOCK:
                in_code_block += 1
            elif line.strip() == WikiParser.ENDBLOCK:
                if in_code_block:
                    in_code_block -= 1
                    if in_code_block == 0:
                        if processor != 'comment':
                            buf.write(' ![...]' + os.linesep)
                        processor = None
            elif in_code_block:
                if not processor:
                    if line.startswith('#!'):
                        processor = line[2:].strip()
            else:
                buf.write(line + os.linesep)
        result = buf.getvalue()[:-1]

        if shorten:
            result = shorten_line(result)

        result = re.sub(self.my_rules, self.replace, result)

        result = result.replace('[...]', '[&hellip;]')
        if result.endswith('...'):
            result = result[:-3] + '&hellip;'

        # Close all open 'one line'-tags
        result += self.close_tag(None)
        # Flush unterminated code blocks
        if in_code_block > 0:
            result += '[&hellip;]'
        out.write(result)
Пример #54
0
 def wiki_page_added(self, page):
     history = list(page.get_history())
     so = FullTextSearchObject(
         self.project,
         page.resource,
         title=u'%s: %s' % (page.name, shorten_line(page.text)),
         author=page.author,
         changed=page.time,
         created=history[-1][1],  # .time of oldest version
         tags=self._page_tags(page.resource.realm, page.name),
         involved=list(set(r[2] for r in history)),
         popularity=0,  #FIXME
         oneline=shorten_result(page.text),
         body=page.text,
         comments=[r[3] for r in history],
     )
     self.backend.create(so, quiet=True)
     self._update_wiki(page)
     self.log.debug("WikiPage created for indexing: %s", page.name)
Пример #55
0
    def _format_changeset_link(self, formatter, ns, match):
        self.env.log.debug("format changeset link")
        if int(self.enable_revmap) == 0:
            self.env.log.debug("revmap disabled, skipping thingy")
            return match.group(0)
        self.env.log.debug("revmap enabled: formatting links")
        commit_data = self._get_commit_data(match.group(0))
        if len(commit_data) == 1:
            self.env.log.debug(commit_data)
            if int(self.long_tooltips):
                title = commit_data[0]['msg']
            else:
                title = shorten_line(commit_data[0]['msg'])
            return tag.a(match.group(0), href="%s/%s" % (formatter.href.changeset(), commit_data[0]['id']),
                    title=title, class_="changeset")
        elif len(commit_data) > 1:
            #try to figure out something better when an id is ambiguous
            return match.group(0)

        return match.group(0)
Пример #56
0
 def _format_changeset_link(self, formatter, ns, chgset, label,
                            fullmatch=None):
     intertrac = formatter.shorthand_intertrac_helper(ns, chgset, label,
                                                      fullmatch)
     if intertrac:
         return intertrac
     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 html.A(label, class_="changeset",
                       title=shorten_line(changeset.message),
                       href=formatter.href.changeset(rev, path))
     except NoSuchChangeset:
         return html.A(label, class_="missing changeset",
                       href=formatter.href.changeset(rev, path),
                       rel="nofollow")
Пример #57
0
    def annotate(self, row, lineno):
        if lineno > len(self.annotations):
            row.append(tag.th())
            return
        rev = self.annotations[lineno - 1]
        chgset = self.changesets[lineno - 1]
        path = self.paths.get(rev, None)
        # Note: path will be None if copy/rename is not supported
        # by get_history

        # -- compute anchor and style once per revision
        if rev not in self.chgset_data:
            chgset_href = \
                self.context.href.changeset(rev, self.repos.reponame or None,
                                            path)
            short_author = chgset.author.split(' ', 1)[0]
            title = shorten_line('%s: %s' % (short_author, chgset.message))
            anchor = tag.a(
                '[%s]' % self.repos.short_rev(rev),  # shortname
                title=title,
                href=chgset_href)
            color = self.colorize_age(self.timerange.relative(chgset.date))
            style = 'background-color: rgb(%d, %d, %d);' % color
            self.chgset_data[rev] = (anchor, style)
        else:
            anchor, style = self.chgset_data[rev]

        if self.prev_chgset != chgset:
            self.prev_style = style
        # optimize away the path if there's no copy/rename info
        if not path or path == self.path:
            path = ''
        # -- produce blame column, eventually with an anchor
        style = self.prev_style
        if lineno < len(self.changesets) and self.changesets[lineno] == chgset:
            style += ' border-bottom: none;'
        blame_col = tag.th(style=style, class_='blame r%s' % rev)
        if self.prev_chgset != chgset:
            blame_col.append(anchor)
            self.prev_chgset = chgset
        row.append(blame_col)
Пример #58
0
 def get_search_results(self, req, terms, filters):
     if not 'ticket' in filters:
         return
     db = self.env.get_db_cnx()
     sql, args = search_to_sql(db, ['b.newvalue'], terms)
     sql2, args2 = search_to_sql(db, ['summary', 'keywords', 'description',
                                      'reporter', 'cc'], terms)
     cursor = db.cursor()
     cursor.execute("SELECT DISTINCT a.summary,a.description,a.reporter, "
                    "a.keywords,a.id,a.time,a.status FROM ticket a "
                    "LEFT JOIN ticket_change b ON a.id = b.ticket "
                    "WHERE (b.field='comment' AND %s ) OR %s" % (sql, sql2),
                    args + args2)
     for summary, desc, author, keywords, tid, date, status in cursor:
         ticket = '#%d: ' % tid
         if status == 'closed':
             ticket = Markup('<span style="text-decoration: line-through">'
                             '#%s</span>: ', tid)
         yield (req.href.ticket(tid),
                ticket + shorten_line(summary),
                date, author, shorten_result(desc, terms))