Beispiel #1
0
    def log_receiver (self, changed_paths, rev, author, date, log, pool):
        if not changed_paths: return

        # Store the copyfrom-information so we can follow the file/dir
        # through tags/banches/copy/renames.
        for newpath in changed_paths.keys():
            change = changed_paths[newpath]
            if change.copyfrom_path:
                self.branch_info.setdefault(rev, []).append((change.copyfrom_path, newpath))

        shortlog = util.shorten_line(util.wiki_escape_newline(log))
        t = svn.core.svn_time_from_cstring(date, pool) / 1000000
        gmt = time.gmtime(t)
        item = {
            'rev'      : rev,
            'author'   : author and util.escape(author) or 'None',
            'date'     : util.svn_date_to_string (date, pool),
            'gmt'      : time.strftime('%a, %d %b %Y %H:%M:%S GMT', gmt),
            'log.raw'  : util.escape(log),
            'log'      : wiki_to_oneliner(util.shorten_line(util.wiki_escape_newline(log)), self.req.hdf, self.env,self.db),
            'shortlog' : util.escape(shortlog),
            'file_href': self.env.href.browser(self.path, rev),
            'changeset_href': self.env.href.changeset(rev)
            }
        self.log_info.insert (0, item)
 def _changesethref_formatter(self, match, fullmatch):
     number = int(match[1:-1])
     cursor = self.db.cursor ()
     cursor.execute('SELECT message FROM revision WHERE rev=%d', number)
     row = cursor.fetchone ()
     if not row:
         return '[<a class="missing" href="%s">%d</a>]' % (self._href.changeset(number), number)
     else:
         return '[<a title="%s" href="%s">%d</a>]' % ( util.escape(util.shorten_line(row[0])),self._href.changeset(number), number)
 def _expand_module_link(self, text):
     sep = text.find(':')
     if sep == -1:
         return None, None
     module = text[:sep]
     args = text[sep+1:]
     if module in ['bug', 'ticket']:
         cursor = self.db.cursor ()
         cursor.execute('SELECT summary,status FROM ticket WHERE id=%s', args)
         row = cursor.fetchone ()
         if row:
             summary = util.escape(util.shorten_line(row[0]))
             if row[1] == 'new':
                 return self._href.ticket(args), '%s:%s*' % (module, args), 0, 'NEW: ' +  summary
             elif row[1] == 'closed':
                 return self._href.ticket(args), '<del>%s:%s</del>' % (module, args), 0, 'CLOSED: ' + summary
             else:
                 return self._href.ticket(args), '%s:%s' % (module, args), 0, summary
         else:
             return self._href.ticket(args), '%s:%s' % (module, args), 1, ''
     elif module == 'wiki':
         if not self.env._wiki_pages.has_key(args):
             return self._href.wiki(args), '%s:%s' % (module, args), 1, None
         else:
             return self._href.wiki(args), '%s:%s' % (module, args), 0, None
     elif module == 'report':
         return self._href.report(args), '%s:%s' % (module, args), 0, None
     elif module == 'changeset':
         cursor = self.db.cursor ()
         cursor.execute('SELECT message FROM revision WHERE rev=%s', args)
         row = cursor.fetchone ()
         if row:
             return self._href.changeset(args), '%s:%s' % (module,args), 0, util.escape(util.shorten_line(row[0]))
         else:
             return self._href.changeset(args), '%s:%s' % (module,args), 1, ''
     elif module == 'milestone':
         return self._href.milestone(args), '%s:%s' % (module, args), 0, None
     elif module == 'search':
         return self._href.search(args), '%s:%s' % (module, args), 0, None
     elif module in ['source', 'repos', 'browser']:
         rev = None
         match = re.search('([^#]+)#(.+)', args)
         if match:
             args = match.group(1)
             rev = match.group(2)
         if rev:
             return self._href.browser(args, rev), \
                    '%s:%s#%s' % (module, args, rev), 0, None
         else:
             return self._href.browser(args), '%s:%s' % (module, args), 0, None
     else:
         return None, None, 0, None
 def _tickethref_formatter(self, match, fullmatch):
     number = int(match[1:])
     cursor = self.db.cursor ()
     cursor.execute('SELECT summary,status FROM ticket WHERE id=%s', number)
     row = cursor.fetchone ()
     if not row:
         return '<a class="missing" href="%s">#%d</a>' % (self._href.ticket(number), number)
     else:
         summary =  util.escape(util.shorten_line(row[0]))
         if row[1] == 'new':
             return '<a href="%s" title="NEW : %s">#%d*</a>' % (self._href.ticket(number), summary, number)
         elif row[1] == 'closed':
             return '<a href="%s" title="CLOSED : %s"><del>#%d</del></a>' % (self._href.ticket(number), summary, number)
         else:
             return '<a href="%s" title="%s">#%d</a>' % (self._href.ticket(number), summary, number)
Beispiel #5
0
    def get_info(self, path, revision, rev_specified):
        """
        Extracts information for a given path and revision
        """
        # We need to really make sure it's an ordinary string. The FieldStorage
        # class provided by modpython might give us some strange string-like object
        # that svn doesn't like.
        path = str(path)
        try:
            root = svn.fs.revision_root(self.fs_ptr, revision, self.pool)
        except svn.core.SubversionException:
            raise util.TracError('Invalid revision number: %d' % revision)

        node_type = svn.fs.check_path(root, path, self.pool)
        if not node_type in [svn.core.svn_node_dir, svn.core.svn_node_file]:
            raise util.TracError('"%s": no such file or directory in revision %d' \
                            % (path, revision), 'No such file or directory')

        # Redirect to the file module if the requested path happens
        # to point to a regular file
        if svn.fs.is_file(root, path, self.pool):
            if rev_specified:
                self.req.redirect(self.env.href.file(path, revision))
            else:
                self.req.redirect(self.env.href.log(path))

        entries = svn.fs.dir_entries(root, path, self.pool)
        info = []
        for item in entries.keys():
            fullpath = posixpath.join(path, item)

            is_dir = svn.fs.is_dir(root, fullpath, self.pool)
            if is_dir:
                name = item + '/'
                fullpath = fullpath + '/'
            else:
                name = item

            created_rev = svn.fs.node_created_rev(root, fullpath, self.pool)
            date = svn.fs.revision_prop(self.fs_ptr, created_rev,
                                    svn.core.SVN_PROP_REVISION_DATE,
                                    self.pool)
            if date:
                date_seconds = svn.core.svn_time_from_cstring(date,
                                                              self.pool) / 1000000
                date = time.strftime('%x %X', time.localtime(date_seconds))
            else:
                date_seconds = 0
                date = ''
            author = svn.fs.revision_prop(self.fs_ptr, created_rev,
                                          svn.core.SVN_PROP_REVISION_AUTHOR,
                                          self.pool)
            change = svn.fs.revision_prop(self.fs_ptr, created_rev,
                                          svn.core.SVN_PROP_REVISION_LOG,
                                          self.pool)
            item = {
                'name'         : name,
                'fullpath'     : fullpath,
                'created_rev'  : created_rev,
                'date'         : date,
                'date_seconds' : date_seconds,
                'age'          : util.pretty_age(date_seconds),
                'is_dir'       : is_dir,
                'author'       : author,
                'change'       : wiki_to_oneliner(util.shorten_line(util.wiki_escape_newline(change)),
                                                  self.req.hdf, self.env,self.db),
		'permission'   : self.authzperm.has_permission(fullpath)
                }
            if rev_specified:
                item['log_href'] = self.env.href.log(fullpath, revision)
                if is_dir:
                    item['browser_href'] = self.env.href.browser(fullpath,
                                                                 revision)
                else:
                    item['browser_href'] = self.env.href.file(fullpath, revision)
            else:
                item['log_href'] = self.env.href.log(fullpath)
                if is_dir:
                    item['browser_href'] = self.env.href.browser(fullpath)
                else:
                    item['browser_href'] = self.env.href.file(fullpath)

            info.append(item)
        return info
Beispiel #6
0
    def get_info (self, start, stop, maxrows, tickets,
                  changeset, wiki, milestone):
        cursor = self.db.cursor ()

        tickets = tickets and self.perm.has_permission(perm.TICKET_VIEW)
        changeset = changeset and self.perm.has_permission(perm.CHANGESET_VIEW)
        wiki = wiki and self.perm.has_permission(perm.WIKI_VIEW)
        milestone = milestone and self.perm.has_permission(perm.MILESTONE_VIEW)

        if tickets == changeset == wiki == milestone == 0:
            return []

        CHANGESET = 1
        NEW_TICKET = 2
        CLOSED_TICKET = 3
        REOPENED_TICKET = 4
        WIKI = 5
        MILESTONE = 6

        q = []
        if changeset:
            q.append("SELECT time, rev AS idata, '' AS tdata, 1 AS type, "
                     " message, author "
                     "FROM revision WHERE time>=%s AND time<=%s" %
                     (start, stop))
        if tickets:
            q.append("SELECT time, id AS idata, '' AS tdata, 2 AS type, "
                     "summary AS message, reporter AS author "
                     "FROM ticket WHERE time>=%s AND time<=%s" %
                     (start, stop))
            q.append("SELECT time, ticket AS idata, '' AS tdata, 4 AS type, "
                     "'' AS message, author "
                     "FROM ticket_change WHERE field='status' "
                     "AND newvalue='reopened' AND time>=%s AND time<=%s" %
                     (start, stop))
            q.append("SELECT t1.time AS time, t1.ticket AS idata,"
                     "       t2.newvalue AS tdata, 3 AS type,"
                     "       t3.newvalue AS message, t1.author AS author"
                     " FROM ticket_change t1"
                     "   INNER JOIN ticket_change t2 ON t1.ticket = t2.ticket"
                     "     AND t1.time = t2.time"
                     "   LEFT OUTER JOIN ticket_change t3 ON t1.time = t3.time"
                     "     AND t1.ticket = t3.ticket AND t3.field = 'comment'"
                     " WHERE t1.field = 'status' AND t1.newvalue = 'closed'"
                     "   AND t2.field = 'resolution'"
                     "   AND t1.time >= %s AND t1.time <= %s" % (start,stop))
        if wiki:
            q.append("SELECT time, -1 AS idata, name AS tdata, 5 AS type, "
                     "comment AS message, author "
                        "FROM wiki WHERE time>=%s AND time<=%s" %
                     (start, stop))
        if milestone:
            q.append("SELECT time, -1 AS idata, '' AS tdata, 6 AS type, "
                     "name AS message, '' AS author " 
                     "FROM milestone WHERE time>=%s AND time<=%s" %
                     (start, stop))

        q_str = string.join(q, ' UNION ALL ')
        q_str += ' ORDER BY time DESC'
        if maxrows:
            q_str += ' LIMIT %d' % maxrows

        cursor.execute(q_str)

        # Make the data more HDF-friendly
        info = []
        while 1:
            row = cursor.fetchone()
            if not row:
                break
            t = time.localtime(int(row['time']))
            gmt = time.gmtime(int(row['time']))
            item = {'time': time.strftime('%H:%M', t),
                    'date': time.strftime('%x', t),
                    'datetime': time.strftime('%a, %d %b %Y %H:%M:%S GMT', gmt),
                    'idata': int(row['idata']),
                    'tdata': row['tdata'],
                    'type': int(row['type']),
                    'message': row['message'] or '',
                    'author': util.escape(row['author'] or 'anonymous')
                    }

            if item['type'] == CHANGESET:
                item['href'] = self.env.href.changeset(item['idata'])
                msg = item['message']
                item['shortmsg'] = util.escape(util.shorten_line(msg))
                item['msg_nowiki'] = util.escape(msg)
                item['msg_escwiki'] = util.escape(wiki_to_html(msg,
                                                               self.req.hdf,
                                                               self.env,
                                                               self.db,
                                                               absurls=1))
                item['message'] = wiki_to_oneliner(msg, self.req.hdf,
                                                   self.env, self.db,absurls=1)
                try:
                    max_node = int(self.env.get_config('timeline', 'changeset_show_files', 0))
                except ValueError, e:
                    self.env.log.warning("Invalid 'changeset_show_files' value, "
                                         "please edit trac.ini : %s" % e)
                    max_node = 0
                    
                if max_node != 0:
                    cursor_node = self.db.cursor ()
                    cursor_node.execute("SELECT name, change "
                                        "FROM node_change WHERE rev=%d" % item['idata'])
                    node_list = ''
                    node_data = ''
                    node_count = 0;
                    while 1:
                        row_node = cursor_node.fetchone()
                        if not row_node:
                            break
                        if node_count != 0:
                            node_list += ', '
                        if (max_node != -1) and (node_count >= max_node):
                            node_list += '...'
                            break
                        if row_node['change'] == 'A':
                            node_data = '<span class="diff-add">' + row_node['name'] + "</span>"
                        elif row_node['change'] == 'M':
                            node_data = '<span class="diff-mod">' + row_node['name'] + "</span>"
                        elif row_node['change'] == 'D':
                            node_data = '<span class="diff-rem">' + row_node['name'] + "</span>"
                        node_list += node_data
                        node_count += 1
                    item['node_list'] = node_list + ': '

            elif item['type'] == WIKI:
                item['href'] = self.env.href.wiki(row['tdata'])
                item['message'] = wiki_to_oneliner(util.shorten_line(item['message']),
                                                   self.req.hdf, self.env, self.db, absurls=1)
Beispiel #7
0
                            node_data = '<span class="diff-rem">' + row_node['name'] + "</span>"
                        node_list += node_data
                        node_count += 1
                    item['node_list'] = node_list + ': '

            elif item['type'] == WIKI:
                item['href'] = self.env.href.wiki(row['tdata'])
                item['message'] = wiki_to_oneliner(util.shorten_line(item['message']),
                                                   self.req.hdf, self.env, self.db, absurls=1)
            elif item['type'] == MILESTONE:
                item['href'] = self.env.href.milestone(item['message'])
                item['message'] = util.escape(item['message'])
            else:               # TICKET
                item['href'] = self.env.href.ticket(item['idata'])
                msg = item['message']
                item['shortmsg'] = util.escape(util.shorten_line(msg))
                item['message'] = wiki_to_oneliner(
                    util.shorten_line(item['message']),
                    self.req.hdf, self.env, self.db, absurls=1)
                item['msg_escwiki'] = util.escape(wiki_to_html(msg,
                                                               self.req.hdf,
                                                               self.env,
                                                               self.db,
                                                               absurls=1))
            # Kludges for RSS
            item['author.rss'] = item['author']
            if item['author.rss'].find('@') == -1:
                item['author.rss'] = ''
            item['message.rss'] = util.escape(item['message'] or '')

            info.append(item)
Beispiel #8
0
 elif item['type'] == WIKI:
     item['href'] = util.escape(self.env.href.wiki(row['tdata']))
     item['message'] = wiki_to_oneliner(util.shorten_line(
         item['message']),
                                        self.req.hdf,
                                        self.env,
                                        self.db,
                                        absurls=1)
 elif item['type'] == MILESTONE:
     item['href'] = util.escape(
         self.env.href.milestone(item['message']))
     item['message'] = util.escape(item['message'])
 else:  # TICKET
     item['href'] = util.escape(self.env.href.ticket(item['idata']))
     msg = item['message']
     item['shortmsg'] = util.escape(util.shorten_line(msg))
     item['message'] = wiki_to_oneliner(util.shorten_line(
         item['message']),
                                        self.req.hdf,
                                        self.env,
                                        self.db,
                                        absurls=1)
     item['msg_escwiki'] = util.escape(
         wiki_to_html(msg,
                      self.req.hdf,
                      self.env,
                      self.db,
                      absurls=1))
 # Kludges for RSS
 item['author.rss'] = item['author']
 if item['author.rss'].find('@') == -1:
Beispiel #9
0
    def perform_query (self, query, changeset, tickets, wiki, page=0):
        if not query:
            return ([], 0)
        keywords = query.split(' ')

        if changeset:
            changeset = self.perm.has_permission(perm.CHANGESET_VIEW)
        if tickets:
            tickets = self.perm.has_permission(perm.TICKET_VIEW)
        if wiki:
            wiki = self.perm.has_permission(perm.WIKI_VIEW)

        if changeset == tickets == wiki == 0:
            return ([], 0)

        if len(keywords) == 1:
            kwd = keywords[0]
            redir = None
            # Prepending a '!' disables quickjump feature
            if kwd[0] == '!':
                keywords[0] = kwd[1:]
                query = query[1:]
                self.req.hdf.setValue('search.q', query)
            # Ticket quickjump
            elif kwd[0] == '#' and kwd[1:].isdigit():
                redir = self.env.href.ticket(kwd[1:])
            # Changeset quickjump
            elif kwd[0] == '[' and kwd[-1] == ']' and kwd[1:-1].isdigit():
                redir = self.env.href.changeset(kwd[1:-1])
            # Report quickjump
            elif kwd[0] == '{' and kwd[-1] == '}' and kwd[1:-1].isdigit():
                redir = self.env.href.report(kwd[1:-1])
            elif kwd[0].isupper() and kwd[1].islower():
                r = "((^|(?<=[^A-Za-z]))[!]?[A-Z][a-z/]+(?:[A-Z][a-z/]+)+)"
                if re.match (r, kwd):
                    redir = self.env.href.wiki(kwd)
            if redir:
                self.req.hdf.setValue('search.q', '')
                self.req.redirect(redir)
            elif len(query) < 3:
                raise TracError('Search query too short. '
                                'Query must be at least 3 characters long.',
                                'Search Error')

        cursor = self.db.cursor ()

        q = []
        if changeset:
            q.append('SELECT 1 as type, message AS title, message, author, '
                     ' \'\' AS keywords, rev AS data, time,0 AS ver'
                     ' FROM revision WHERE %s OR %s' % 
                     (self.query_to_sql(query, 'message'),
                      self.query_to_sql(query, 'author')))
        if tickets:
            q.append('SELECT DISTINCT 2 as type, a.summary AS title, '
                     ' a.description AS message, a.reporter AS author, '
                     ' a.keywords as keywords, a.id AS data, a.time as time, 0 AS ver'
                     ' FROM ticket a LEFT JOIN ticket_change b ON a.id = b.ticket'
                     ' WHERE (b.field=\'comment\' AND %s ) OR'
                     ' %s OR %s OR %s OR %s OR %s' %
                      (self.query_to_sql(query, 'b.newvalue'),
                       self.query_to_sql(query, 'summary'),
                       self.query_to_sql(query, 'keywords'),
                       self.query_to_sql(query, 'description'),
                       self.query_to_sql(query, 'reporter'),
                       self.query_to_sql(query, 'cc')))
        if wiki:
            q.append('SELECT 3 as type, text AS title, text AS message,'
                     ' author, \'\' AS keywords, w1.name AS data, time,'
                     ' w1.version as ver'
                     ' 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'
                     ' (%s OR %s OR %s) ' %
                     (self.query_to_sql(query, 'w1.name'),
                      self.query_to_sql(query, 'w1.author'),
                      self.query_to_sql(query, 'w1.text')))

        if not q: return []

        q_str = string.join(q, ' UNION ALL ')
        q_str += ' ORDER BY 7 DESC LIMIT %d OFFSET %d' % \
                 (self.RESULTS_PER_PAGE + 1, self.RESULTS_PER_PAGE * page)

        self.log.debug("SQL Query: %s" % q_str)
        cursor.execute(q_str)

        # Make the data more HDF-friendly
        info = []
        more = 0
        while 1:
            row = cursor.fetchone()
            if not row:
                break
            if len(info) == self.RESULTS_PER_PAGE:
                more = 1
                break
            msg = row['message']
            t = time.localtime(int(row['time']))
            item = {'type': int(row['type']),
                    'keywords': row['keywords'] or '',
                    'data': row['data'],
                    'title': escape(row['title'] or ''),
                    'datetime' : time.strftime('%c', t),
                    'author': escape(row['author'])}
            if item['type'] == 1:
                item['changeset_href'] = self.env.href.changeset(int(row['data']))
            elif item['type'] == 2:
                item['ticket_href'] = self.env.href.ticket(int(row['data']))
            elif item['type'] == 3:
                item['wiki_href'] = self.env.href.wiki(row['data'])

            item['shortmsg'] = escape(shorten_line(msg))
            item['message'] = escape(self.shorten_result(msg, keywords))
            info.append(item)
        return info, more