Пример #1
0
    def get_timeline_events(self, req, start, stop, filters):
        if ('sensitive_activity' in filters and
            'SENSITIVE_ACTIVITY_VIEW' in req.perm and
            'SENSITIVE_VIEW' not in req.perm):
            ts_start = to_utimestamp(start)
            ts_stop = to_utimestamp(stop)

            db = self.env.get_db_cnx()
            cursor = db.cursor()

            if 'ticket_details' in filters:
                # only show sensitive ticket changes (edits, closure) if the 'ticket_details' filter is on:
                cursor.execute("""
                    SELECT DISTINCT t.id,tc.time,tc.oldvalue
                    FROM ticket_change tc 
                        INNER JOIN ticket t ON t.id = tc.ticket 
                            AND tc.time >= %s AND tc.time <= %s  AND tc.field = %s
                        INNER JOIN ticket_custom td ON t.id = td.ticket
                            AND td.name = %s AND td.value = %s
                    ORDER BY tc.time
                    """, (ts_start, ts_stop, 'comment', 'sensitive', '1'))
                for tid,t,cid in cursor:
                    yield ('sensitive_activity', from_utimestamp(t), 'redacted', (tid, cid))
            # always show new sensitive tickets:
            cursor.execute('''
               SELECT DISTINCT id, time FROM
                  ticket t INNER JOIN ticket_custom tc ON t.id = tc.ticket
                   AND t.time >= %s AND t.time <= %s
                   AND tc.name = %s AND tc.value = %s
               ORDER BY time
               ''', (ts_start, ts_stop, 'sensitive', '1'))
            for tid,t in cursor:
                yield ('sensitive_activity', from_utimestamp(t), 'redacted', (tid, None))
Пример #2
0
    def get_comment_history(self, cnum, db=None):
        """Retrieve the edit history of comment `cnum`.

        :since 0.13: the `db` parameter is no longer needed and will be removed
        in version 0.14
        """
        row = self._find_change(cnum)
        if row:
            ts0, author0, last_comment = row
            with self.env.db_query as db:
                # Get all fields of the form "_comment%d"
                rows = db("""SELECT field, author, oldvalue, newvalue 
                             FROM ticket_change 
                             WHERE ticket=%%s AND time=%%s AND field %s
                             """ % db.like(),
                             (self.id, ts0, db.like_escape('_comment') + '%'))
                rows = sorted((int(field[8:]), author, old, new)
                              for field, author, old, new in rows)
                history = []
                for rev, author, comment, ts in rows:
                    history.append((rev, from_utimestamp(long(ts0)), author0,
                                    comment))
                    ts0, author0 = ts, author
                history.sort()
                rev = history[-1][0] + 1 if history else 0
                history.append((rev, from_utimestamp(long(ts0)), author0,
                                last_comment))
                return history
Пример #3
0
    def get_search_results(self, req, terms, filters):
        if not 'milestone' in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = search_to_sql(db, ['name', 'description'], terms)
        cursor = db.cursor()
        cursor.execute(
            "SELECT name,due,completed,description "
            "FROM milestone "
            "WHERE " + sql_query, args)

        milestone_realm = Resource('milestone')
        for name, due, completed, description in cursor:
            milestone = milestone_realm(id=name)
            if 'MILESTONE_VIEW' in req.perm(milestone):
                dt = (completed and from_utimestamp(completed)
                      or due and from_utimestamp(due) or datetime.now(utc))
                yield (get_resource_url(self.env, milestone, req.href),
                       get_resource_name(self.env, milestone), dt, '',
                       shorten_result(description, terms))

        # Attachments
        for result in AttachmentModule(self.env).get_search_results(
                req, milestone_realm, terms):
            yield result
Пример #4
0
 def _from_database(self, row):
     name, due, completed, description = row
     self.name = name
     self.due = from_utimestamp(due) if due else None
     self.completed = from_utimestamp(completed) if completed else None
     self.description = description or ''
     self._to_old()
Пример #5
0
    def select(cls, env, tkt_ids):
        if not tkt_ids:
            return {}

        db = _get_db(env)
        fields = TicketSystem(env).get_ticket_fields()
        std_fields = [f['name'] for f in fields if not f.get('custom')]
        time_fields = [f['name'] for f in fields if f['type'] == 'time']
        custom_fields = set(f['name'] for f in fields if f.get('custom'))
        cursor = db.cursor()
        tickets = {}

        cursor.execute(
            'SELECT %s,id FROM ticket WHERE %s' %
            (','.join(std_fields), _tkt_id_conditions('id', tkt_ids)))
        for row in cursor:
            id = row[-1]
            values = {}
            for idx, field in enumerate(std_fields):
                value = row[idx]
                if field in time_fields:
                    value = from_utimestamp(value)
                elif value is None:
                    value = empty
                values[field] = value
            tickets[id] = (values, [])  # values, changelog

        cursor.execute('SELECT ticket,name,value FROM ticket_custom '
                       'WHERE %s ORDER BY ticket' %
                       _tkt_id_conditions('ticket', tkt_ids))
        for id, rows in groupby(cursor, lambda row: row[0]):
            if id not in tickets:
                continue
            values = {}
            for id, name, value in rows:
                if name in custom_fields:
                    if value is None:
                        value = empty
                    values[name] = value
            tickets[id][0].update(values)

        cursor.execute('SELECT ticket,time,author,field,oldvalue,newvalue '
                       'FROM ticket_change WHERE %s ORDER BY ticket,time' %
                       _tkt_id_conditions('ticket', tkt_ids))
        for id, rows in groupby(cursor, lambda row: row[0]):
            if id not in tickets:
                continue
            tickets[id][1].extend(
                (from_utimestamp(t), author, field, oldvalue or '',
                 newvalue or '', 1)
                for id, t, author, field, oldvalue, newvalue in rows)

        return dict((id,
                     cls(env,
                         id,
                         values=values,
                         changelog=changelog,
                         fields=fields,
                         time_fields=time_fields))
                    for id, (values, changelog) in tickets.iteritems())
Пример #6
0
 def _fetch_ticket(self):
     rts = RemoteTicketSystem(self.env)
     db = self.env.get_read_db()
     cursor = db.cursor()
     
     # Try to retrieve remote ticket from cache
     cursor.execute('''SELECT %s FROM remote_tickets 
                    WHERE remote_name=%%s and id=%%s
                    ''' % (', '.join(self.table_fields)),
                    (self.remote_name, self.id))
     row = cursor.fetchone()
     
     # Remote ticket not in cache
     if not row:
         self._refresh_ticket()
     
     self._cachetime = from_utimestamp(row[self.cachetime_pos])
     ttl = timedelta(seconds=int(rts.cache_ttl) // 1000, 
                     microseconds=int(rts.cache_ttl) % 1000 * 1000)
     
     # Cached remote ticket is too old
     if self._cachetime < datetime.now(utc) - ttl:
         self._refresh_ticket()
     
     # Cached ticket is valid, populate instance
     for name, value in zip(self.remote_fields, row):
         if name in self.time_fields:
             self.values[name] = from_utimestamp(value)
         elif value is None:
             self.values[name] = empty
         else:
             self.values[name] = value
Пример #7
0
    def _fetch_ticket(self):
        rts = RemoteTicketSystem(self.env)
        db = self.env.get_read_db()
        cursor = db.cursor()

        # Try to retrieve remote ticket from cache
        cursor.execute(
            '''SELECT %s FROM remote_tickets 
                       WHERE remote_name=%%s and id=%%s
                       ''' % (', '.join(self.table_fields)),
            (self.remote_name, self.id))
        row = cursor.fetchone()

        # Remote ticket not in cache
        if not row:
            self._refresh_ticket()

        self._cachetime = from_utimestamp(row[self.cachetime_pos])
        ttl = timedelta(seconds=int(rts.cache_ttl) // 1000,
                        microseconds=int(rts.cache_ttl) % 1000 * 1000)

        # Cached remote ticket is too old
        if self._cachetime < datetime.now(utc) - ttl:
            self._refresh_ticket()

        # Cached ticket is valid, populate instance
        for name, value in zip(self.remote_fields, row):
            if name in self.time_fields:
                self.values[name] = from_utimestamp(value)
            elif value is None:
                self.values[name] = empty
            else:
                self.values[name] = value
Пример #8
0
 def _from_database(self, row):
     name, due, completed, description = row
     self.name = name
     self.due = from_utimestamp(due) if due else None
     self.completed = from_utimestamp(completed) if completed else None
     self.description = description or ''
     self._to_old()
Пример #9
0
 def _from_database(self, row):
     name, due, completed, description = row
     self.name = name
     self.due = due and from_utimestamp(due) or None
     self.completed = completed and from_utimestamp(completed) or None
     self.description = description or ''
     self._to_old()
Пример #10
0
 def get_comment_history(self, cnum, db=None):
     db = self._get_db(db)
     history = []
     cursor = db.cursor()
     row = self._find_change(cnum, db)
     if row:
         ts0, author0, last_comment = row
         # Get all fields of the form "_comment%d"
         cursor.execute("""
             SELECT field,author,oldvalue,newvalue 
             FROM ticket_change 
             WHERE ticket=%%s AND time=%%s AND field %s
             """ % db.like(), (self.id, ts0,
                               db.like_escape('_comment') + '%'))
         rows = sorted((int(field[8:]), author, old, new)
                       for field, author, old, new in cursor)
         for rev, author, comment, ts in rows:
             history.append((rev, from_utimestamp(long(ts0)), author0,
                             comment))
             ts0, author0 = ts, author
         history.sort()
         rev = history and (history[-1][0] + 1) or 0
         history.append((rev, from_utimestamp(long(ts0)), author0,
                         last_comment))
     return history
Пример #11
0
    def get_data(self, limit=100, offset=0):
        cursor = self.env.get_db_cnx().cursor()
        cursor2 = self.env.get_db_cnx().cursor()

        cursor.execute(
            "SELECT buildqueue.id, owner, replace(replace(browseurl, '%OWNER%', buildqueue.owner), '%REVISION%', revision), revision, status, startdate, CASE WHEN enddate < startdate THEN startdate ELSE enddate END, description FROM buildqueue, portrepositories WHERE repository = portrepositories.id AND buildqueue.status >= 10 "
            + self._get_filter() +
            " ORDER BY buildqueue.id DESC LIMIT %s OFFSET %s", (limit, offset))

        for queueid, owner, repository, revision, status, startdate, enddate, description in cursor:
            build = Build(self.env)
            build.queueid = queueid
            build.owner = owner
            build.repository = repository
            build.revision = revision
            build.setStatus(status)
            build.runtime = pretty_timedelta(from_utimestamp(startdate),
                                             from_utimestamp(enddate))
            build.startdate = startdate
            build.enddate = enddate
            build.description = description

            cursor2.execute(
                "SELECT id, buildgroup, portname, pkgversion, status, buildstatus, buildreason, buildlog, wrkdir, startdate, CASE WHEN enddate < startdate THEN extract(epoch from now())*1000000 ELSE enddate END FROM builds WHERE queueid = %s ORDER BY id",
                (queueid, ))

            lastport = None
            for id, group, portname, pkgversion, status, buildstatus, buildreason, buildlog, wrkdir, startdate, enddate in cursor2:
                port = Port(self.env)
                port.id = id
                port.group = group
                port.portname = portname
                port.pkgversion = pkgversion
                port.buildstatus = buildstatus
                port.buildlog = buildlog
                port.wrkdir = wrkdir
                port.runtime = pretty_timedelta(from_utimestamp(startdate),
                                                from_utimestamp(enddate))
                port.startdate = startdate
                port.enddate = enddate
                port.directory = '/~%s/%s-%s' % (owner, queueid, id)

                if buildstatus:
                    port.buildstatus = buildstatus.lower()
                if buildstatus and not buildreason:
                    buildreason = buildstatus.lower()

                port.setStatus(status, buildreason)

                if self.uniqueports and lastport == portname:
                    continue

                if lastport != portname:
                    port.head = True
                    lastport = portname

                build.ports.append(port)

            yield build
Пример #12
0
 def formatter(self, col, cell_value):
     if col == 'time':
         return cell_value != '' and format_time(from_utimestamp(long(cell_value))) or '--'
     if col in ('date', 'created', 'modified'):
         return cell_value != '' and format_date(from_utimestamp(long(cell_value))) or '--'
     if col == 'datetime':
         return cell_value != '' and format_datetime(from_utimestamp(long(cell_value))) or '--'
     return cell_value
    def render_admin_panel(self, req, cat, page, path_info):
        req.perm.require('SVNVERIFY_REPORT')
        
        rm = RepositoryManager(self.env)
        all_repos = rm.get_all_repositories()
        db = self.env.get_read_db()
        cursor = db.cursor()
        
        if path_info:
            # detailed
            reponame = not is_default(path_info) and path_info or ''
            info = all_repos.get(reponame)
            if info is None:
                raise TracError(_("Repository '%(repo)s' not found",
                                  repo=path_info))

            cursor.execute("SELECT type, time, result, log "
                           "FROM svnverify_log WHERE repository_id = %s "
                           "ORDER BY time DESC LIMIT 1",
                           (info['id'],))
            row = cursor.fetchone()
            if row:
                info['check_type'] = row[0]
                info['time_checked'] = format_datetime(from_utimestamp(row[1]))
                info['pretty_status'] = int(row[2]) == 0 and "OK" or "Warning"
                info['status'] = row[2]
                info['log'] = row[3]
            info['prettydir'] = breakable_path(info['dir'])
            if info['name'] == '':
                info['name'] = "(default)"
            return 'svnverify.html', {"info": info}
        else:
            repositories = {}
            for reponame, info in all_repos.iteritems():
                if info.get('type',rm.repository_type) == "svn" or (rm.repository_type == 'svn' and info.get('type') == ''):
                    info['prettydir'] = breakable_path(info['dir'])
                    try:
                        r = RepositoryManager(self.env).get_repository(reponame)
                        info['rev'] = r.get_youngest_rev()
                        info['display_rev'] = r.display_rev(info['rev'])
                    except:
                        pass
                    cursor.execute("SELECT type, time, result "
                                   "FROM svnverify_log "
                                   "WHERE repository_id = %s "
                                   "ORDER BY time DESC LIMIT 1",
                                   (info['id'],))
                    row = cursor.fetchone()
                    if row:
                        info['check_type'] = row[0]
                        info['time_checked'] = format_datetime(from_utimestamp(row[1]))
                        info['pretty_status'] = int(row[2]) == 0 and "OK" or "Warning"
                        info['status'] = row[2]

                    repositories[reponame] = info

            add_stylesheet(req, 'svnverify/css/svnverify.css')
            return 'svnverifylist.html', {"repositories": repositories}
Пример #14
0
    def get_comment_history(self, cnum=None, cdate=None, db=None):
        """Retrieve the edit history of a comment identified by its number or
        date.

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            ts0, author0, last_comment = row
        else:
            ts0, author0, last_comment = to_utimestamp(cdate), None, None
        with self.env.db_query as db:
            # Get last comment and author if not available
            if last_comment is None:
                last_comment = ""
                for author0, last_comment in db(
                    """
                        SELECT author, newvalue FROM ticket_change
                        WHERE ticket=%s AND time=%s AND field='comment'
                        """,
                    (self.id, ts0),
                ):
                    break
            if author0 is None:
                for author0, last_comment in db(
                    """
                        SELECT author, newvalue FROM ticket_change
                        WHERE ticket=%%s AND time=%%s AND NOT field %s LIMIT 1
                        """
                    % db.like(),
                    (self.id, ts0, db.like_escape("_") + "%"),
                ):
                    break
                else:
                    return

            # Get all fields of the form "_comment%d"
            rows = db(
                """SELECT field, author, oldvalue, newvalue
                         FROM ticket_change
                         WHERE ticket=%%s AND time=%%s AND field %s
                         """
                % db.like(),
                (self.id, ts0, db.like_escape("_comment") + "%"),
            )
            rows = sorted((int(field[8:]), author, old, new) for field, author, old, new in rows)
            history = []
            for rev, author, comment, ts in rows:
                history.append((rev, from_utimestamp(long(ts0)), author0, comment))
                ts0, author0 = ts, author
            history.sort()
            rev = history[-1][0] + 1 if history else 0
            history.append((rev, from_utimestamp(long(ts0)), author0, last_comment))
            return history
Пример #15
0
    def process_request(self, req):
        id = req.args.getint('id')
        req.perm('ticket', id).require('TICKET_ADMIN')
        ticket = Ticket(self.env, id)
        action = req.args['action']
        cnum = req.args.get('cnum')
        if req.method == 'POST':
            if 'cancel' in req.args:
                href = req.href.ticket(id)
                if action == 'delete-comment':
                    href += '#comment:%s' % cnum
                req.redirect(href)

            if action == 'delete':
                ticket.delete()
                add_notice(
                    req,
                    _("Ticket #%(num)s and all associated data "
                      "removed.",
                      num=ticket.id))
                req.redirect(req.href())

            elif action == 'delete-comment':
                cdate = from_utimestamp(long(req.args.get('cdate')))
                ticket.delete_change(cdate=cdate)
                add_notice(
                    req,
                    _(
                        "The ticket comment %(num)s on ticket "
                        "#%(id)s has been deleted.",
                        num=cnum,
                        id=ticket.id))
                req.redirect(req.href.ticket(id))

        tm = TicketModule(self.env)
        data = tm._prepare_data(req, ticket)
        tm._insert_ticket_data(req, ticket, data,
                               get_reporter_id(req, 'author'), {})
        data.update(action=action, cdate=None)

        if action == 'delete-comment':
            data['cdate'] = req.args.get('cdate')
            cdate = from_utimestamp(long(data['cdate']))
            for change in data['changes']:
                if change.get('date') == cdate:
                    data['change'] = change
                    data['cnum'] = change.get('cnum')
                    break
            else:
                raise TracError(_("Comment %(num)s not found", num=cnum))
        elif action == 'delete':
            attachments = Attachment.select(self.env, ticket.realm, ticket.id)
            data.update(attachments=list(attachments))

        add_stylesheet(req, 'common/css/ticket.css')
        return 'ticket_delete.html', data
Пример #16
0
    def get_comment_history(self, cnum=None, cdate=None, db=None):
        """Retrieve the edit history of a comment identified by its number or
        date.

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            ts0, author0, last_comment = row
        else:
            ts0, author0, last_comment = to_utimestamp(cdate), None, None
        with self.env.db_query as db:
            # Get last comment and author if not available
            if last_comment is None:
                last_comment = ''
                for author0, last_comment in db(
                        """
                        SELECT author, newvalue FROM ticket_change
                        WHERE ticket=%s AND time=%s AND field='comment'
                        """, (self.id, ts0)):
                    break
            if author0 is None:
                for author0, last_comment in db(
                        """
                        SELECT author, newvalue FROM ticket_change
                        WHERE ticket=%%s AND time=%%s AND NOT field %s LIMIT 1
                        """ % db.like(),
                    (self.id, ts0, db.like_escape('_') + '%')):
                    break
                else:
                    return

            # Get all fields of the form "_comment%d"
            rows = db(
                """SELECT field, author, oldvalue, newvalue
                         FROM ticket_change
                         WHERE ticket=%%s AND time=%%s AND field %s
                         """ % db.like(),
                (self.id, ts0, db.like_escape('_comment') + '%'))
            rows = sorted((int(field[8:]), author, old, new)
                          for field, author, old, new in rows)
            history = []
            for rev, author, comment, ts in rows:
                history.append(
                    (rev, from_utimestamp(long(ts0)), author0, comment))
                ts0, author0 = ts, author
            history.sort()
            rev = history[-1][0] + 1 if history else 0
            history.append(
                (rev, from_utimestamp(long(ts0)), author0, last_comment))
            return history
Пример #17
0
 def formatter(self, col, cell_value):
     if col == 'time':
         return cell_value != '' and format_time(
             from_utimestamp(long(cell_value))) or '--'
     if col in ('date', 'created', 'modified'):
         return cell_value != '' and format_date(
             from_utimestamp(long(cell_value))) or '--'
     if col == 'datetime':
         return cell_value != '' and format_datetime(
             from_utimestamp(long(cell_value))) or '--'
     return cell_value
Пример #18
0
def parse_options(env, content, options):
    """Parses the parameters, makes some sanity checks, and creates default values
    for missing parameters.
    """
    _, parsed_options = parse_args(content, strict=False)

    options.update(parsed_options)
    today = datetime.now().date()

    startdatearg = options.get('startdate')
    if startdatearg:
        options['startdate'] = \
            datetime(*strptime(startdatearg, "%Y-%m-%d")[0:5]).date()

    enddatearg = options.get('enddate')
    options['enddate'] = None
    if enddatearg:
        options['enddate'] = \
            datetime(*strptime(enddatearg, "%Y-%m-%d")[0:5]).date()

    if not options['enddate'] and options.get('milestone'):
        # use first milestone
        milestone = options['milestone'].split('|')[0]
        # try to get end date from db
        for completed, due in env.db_query(
                """
                SELECT completed, due FROM milestone WHERE name = %s
                """, (milestone, )):
            if completed:
                options['enddate'] = from_utimestamp(completed).date()
            elif due:
                due = from_utimestamp(due).date()
                if due >= today:
                    options['enddate'] = due
            break
        else:
            raise TracError("Couldn't find milestone %s" % milestone)

    options['enddate'] = options['enddate'] or today
    options['today'] = options.get('today') or today

    if options.get('weekends'):
        options['weekends'] = parse_bool(options['weekends'])

    if options.get('spent'):
        options['spent'] = parse_bool(options['spent'])

    # all arguments that are no key should be treated as part of the query
    query_args = {}
    for key in options.keys():
        if key not in AVAILABLE_OPTIONS:
            query_args[key] = options[key]
    return options, query_args
Пример #19
0
def parse_options(env, content, options):
    """Parses the parameters, makes some sanity checks, and creates default values
    for missing parameters.
    """
    _, parsed_options = parse_args(content, strict=False)

    options.update(parsed_options)
    today = datetime.now().date()

    startdatearg = options.get('startdate')
    if startdatearg:
        options['startdate'] = \
            datetime(*strptime(startdatearg, "%Y-%m-%d")[0:5]).date()

    enddatearg = options.get('enddate')
    options['enddate'] = None
    if enddatearg:
        options['enddate'] = \
            datetime(*strptime(enddatearg, "%Y-%m-%d")[0:5]).date()

    if not options['enddate'] and options.get('milestone'):
        # use first milestone
        milestone = options['milestone'].split('|')[0]
        # try to get end date from db
        for completed, due in env.db_query("""
                SELECT completed, due FROM milestone WHERE name = %s
                """, (milestone,)):
            if completed:
                options['enddate'] = from_utimestamp(completed).date()
            elif due:
                due = from_utimestamp(due).date()
                if due >= today:
                    options['enddate'] = due
            break
        else:
            raise TracError("Couldn't find milestone %s" % milestone)

    options['enddate'] = options['enddate'] or today
    options['today'] = options.get('today') or today

    if options.get('weekends'):
        options['weekends'] = parse_bool(options['weekends'])

    if options.get('spent'):
        options['spent'] = parse_bool(options['spent'] )

    # all arguments that are no key should be treated as part of the query
    query_args = {}
    for key in options.keys():
        if key not in AVAILABLE_OPTIONS:
            query_args[key] = options[key]
    return options, query_args
Пример #20
0
    def process_request(self, req):
        id = int(req.args.get('id'))
        req.perm('ticket', id).require('TICKET_ADMIN')
        ticket = Ticket(self.env, id)
        action = req.args['action']
        cnum = req.args.get('cnum')
        if req.method == 'POST':
            if 'cancel' in req.args:
                href = req.href.ticket(id)
                if action == 'delete-comment':
                    href += '#comment:%s' % cnum
                req.redirect(href)

            if action == 'delete':
                ticket.delete()
                add_notice(req, _('The ticket #%(id)s has been deleted.',
                                  id=ticket.id))
                req.redirect(req.href())

            elif action == 'delete-comment':
                cdate = from_utimestamp(long(req.args.get('cdate')))
                ticket.delete_change(cdate=cdate)
                add_notice(req, _('The ticket comment %(num)s on ticket '
                                  '#%(id)s has been deleted.',
                                  num=cnum, id=ticket.id))
                req.redirect(req.href.ticket(id))

        tm = TicketModule(self.env)
        data = tm._prepare_data(req, ticket)
        tm._insert_ticket_data(req, ticket, data,
                               get_reporter_id(req, 'author'), {})
        data.update(action=action, cdate=None)

        if action == 'delete-comment':
            data['cdate'] = req.args.get('cdate')
            cdate = from_utimestamp(long(data['cdate']))
            for change in data['changes']:
                if change.get('date') == cdate:
                    data['change'] = change
                    data['cnum'] = change.get('cnum')
                    break
            else:
                raise TracError(_('Comment %(num)s not found', num=cnum))
        elif action == 'delete':
            attachments = Attachment.select(self.env, ticket.realm, ticket.id)
            data.update(attachments=list(attachments))

        add_stylesheet(req, 'common/css/ticket.css')
        return 'ticket_delete.html', data, None
Пример #21
0
    def milestones(self):
        """Dictionary containing milestone data, indexed by name.

        Milestone data consist of a tuple containing the name, the
        datetime objects for due and completed dates and the
        description.
        """
        milestones = {}
        for name, due, completed, description in self.env.db_query("""
                SELECT name, due, completed, description FROM milestone
                """):
            milestones[name] = (name, from_utimestamp(due) if due else None,
                                from_utimestamp(completed)
                                if completed else None, description or '')
        return milestones
Пример #22
0
    def get_comment_history(self, cnum=None, cdate=None):
        """Retrieve the edit history of a comment identified by its number or
        date.
        """
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            ts0, author0, last_comment = row
        else:
            ts0, author0, last_comment = to_utimestamp(cdate), None, None
        with self.env.db_query as db:
            # Get last comment and author if not available
            if last_comment is None:
                last_comment = ''
                for author0, last_comment in db("""
                        SELECT author, newvalue FROM ticket_change
                        WHERE ticket=%s AND time=%s AND field='comment'
                        """, (self.id, ts0)):
                    break
            if author0 is None:
                for author0, last_comment in db("""
                        SELECT author, newvalue FROM ticket_change
                        WHERE ticket=%%s AND time=%%s AND NOT field %s LIMIT 1
                        """ % db.prefix_match(),
                        (self.id, ts0, db.prefix_match_value('_'))):
                    break
                else:
                    return

            # Get all fields of the form "_comment%d"
            rows = db("""SELECT field, author, oldvalue, newvalue
                         FROM ticket_change
                         WHERE ticket=%%s AND time=%%s AND field %s
                         """ % db.prefix_match(),
                         (self.id, ts0, db.prefix_match_value('_comment')))
            rows = sorted((int(field[8:]), author, old, new)
                          for field, author, old, new in rows)
            history = []
            for rev, author, comment, ts in rows:
                history.append((rev, from_utimestamp(long(ts0)), author0,
                                comment))
                ts0, author0 = ts, author
            history.sort()
            rev = history[-1][0] + 1 if history else 0
            history.append((rev, from_utimestamp(long(ts0)), author0,
                            last_comment))
            return history
Пример #23
0
    def get_change(self, cnum=None, cdate=None, db=None):
        """Return a ticket change by its number or date.

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            cdate = from_utimestamp(row[0])
        ts = to_utimestamp(cdate)
        fields = {}
        change = {'date': cdate, 'fields': fields}
        for field, author, old, new in self.env.db_query("""
                SELECT field, author, oldvalue, newvalue
                FROM ticket_change WHERE ticket=%s AND time=%s
                """, (self.id, ts)):
            fields[field] = {'author': author, 'old': old, 'new': new}
            if field == 'comment':
                change['author'] = author
            elif not field.startswith('_'):
                change.setdefault('author', author)
        if fields:
            return change
Пример #24
0
    def _fetch_ticket(self, tkt_id):
        row = None
        if self.id_is_valid(tkt_id):
            # Fetch the standard ticket fields
            for row in self.env.db_query("SELECT %s FROM ticket WHERE id=%%s" %
                                         ','.join(self.std_fields), (tkt_id,)):
                break
        if not row:
            raise ResourceNotFound(_("Ticket %(id)s does not exist.",
                                     id=tkt_id), _("Invalid ticket number"))

        self.id = tkt_id
        for i, field in enumerate(self.std_fields):
            value = row[i]
            if field in self.time_fields:
                self.values[field] = from_utimestamp(value)
            elif value is None:
                self.values[field] = empty
            else:
                self.values[field] = value

        # Fetch custom fields if available
        for name, value in self.env.db_query("""
                SELECT name, value FROM ticket_custom WHERE ticket=%s
                """, (tkt_id,)):
            if name in self.custom_fields:
                if name in self.time_fields:
                    self.values[name] = _db_str_to_datetime(value)
                elif value is None:
                    self.values[name] = empty
                else:
                    self.values[name] = value
Пример #25
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
Пример #26
0
 def _from_database(self, filename, description, size, time, author, ipnr):
     self.filename = filename
     self.description = description
     self.size = int(size) if size else 0
     self.date = from_utimestamp(time or 0)
     self.author = author
     self.ipnr = ipnr
    def _fetch_message(self, name):
        """
        Retrieves data representing an individual project message from the 
        database, and unpacks this into a values dictionary.

        If the name provided does not match a row in the project_message 
        table, we raise a ResourceNotFound exception."""

        db = self.env.get_read_db()
        cursor = db.cursor()
        cursor.execute("""SELECT name, message, button, mode, groups,
                                 start, "end", author, created_at
                          FROM project_message
                          WHERE name=%s""", (name,))
        row = cursor.fetchone()
        if row:
            for field, value in izip(self.message_keys, row):
                if field == 'groups':
                    self.values[field] = json.loads(value)
                if field in ['start', 'date']:
                    self.values[field] = from_utimestamp(value)
                else:
                    self.values[field] = value
        else:
            raise ResourceNotFound("Project message '%s' does not exist.", (name))
Пример #28
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)),
                       from_utimestamp(ts), author,
                       shorten_result(text, terms))
        
        # Attachments
        for result in AttachmentModule(self.env).get_search_results(
            req, wiki_realm, terms):
            yield result
Пример #29
0
    def get_change(self, cnum=None, cdate=None, db=None):
        """Return a ticket change by its number or date.

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            cdate = from_utimestamp(row[0])
        ts = to_utimestamp(cdate)
        fields = {}
        change = {"date": cdate, "fields": fields}
        for field, author, old, new in self.env.db_query(
            """
                SELECT field, author, oldvalue, newvalue
                FROM ticket_change WHERE ticket=%s AND time=%s
                """,
            (self.id, ts),
        ):
            fields[field] = {"author": author, "old": old, "new": new}
            if field == "comment":
                change["author"] = author
            elif not field.startswith("_"):
                change.setdefault("author", author)
        if fields:
            return change
Пример #30
0
 def _fetch(self, name, version=None, db=None):
     if not db:
         db = self.env.get_db_cnx()
     cursor = db.cursor()
     if version is not None:
         cursor.execute("SELECT version,time,author,text,comment,readonly "
                        "FROM wiki "
                        "WHERE name=%s AND version=%s",
                        (name, int(version)))
     else:
         cursor.execute("SELECT version,time,author,text,comment,readonly "
                        "FROM wiki "
                        "WHERE name=%s ORDER BY version DESC LIMIT 1",
                        (name,))
     row = cursor.fetchone()
     if row:
         version, time, author, text, comment, readonly = row
         self.version = int(version)
         self.author = author
         self.time = from_utimestamp(time)
         self.text = text
         self.comment = comment
         self.readonly = readonly and int(readonly) or 0
     else:
         self.version = 0
         self.text = self.comment = self.author = ''
         self.time = None
         self.readonly = 0
Пример #31
0
    def milestones(self):
        """Dictionary containing milestone data, indexed by name.

        Milestone data consist of a tuple containing the name, the
        datetime objects for due and completed dates and the
        description.
        """
        milestones = {}
        for name, due, completed, description in self.env.db_query("""
                SELECT name, due, completed, description FROM milestone
                """):
            milestones[name] = (name,
                    from_utimestamp(due) if due else None,
                    from_utimestamp(completed) if completed else None,
                    description or '')
        return milestones
Пример #32
0
    def _fetch_ticket(self, tkt_id):
        row = None
        if self.id_is_valid(tkt_id):
            # Fetch the standard ticket fields
            for row in self.env.db_query(
                    "SELECT %s FROM ticket WHERE id=%%s" %
                    ','.join(self.std_fields), (tkt_id, )):
                break
        if not row:
            raise ResourceNotFound(
                _("Ticket %(id)s does not exist.", id=tkt_id),
                _("Invalid ticket number"))

        self.id = tkt_id
        for i, field in enumerate(self.std_fields):
            value = row[i]
            if field in self.time_fields:
                self.values[field] = from_utimestamp(value)
            elif value is None:
                self.values[field] = empty
            else:
                self.values[field] = value

        # Fetch custom fields if available
        for name, value in self.env.db_query(
                """
                SELECT name, value FROM ticket_custom WHERE ticket=%s
                """, (tkt_id, )):
            if name in self.custom_fields:
                if name in self.time_fields:
                    self.values[name] = _db_str_to_datetime(value)
                elif value is None:
                    self.values[name] = empty
                else:
                    self.values[name] = value
Пример #33
0
    def get_change(self, cnum=None, cdate=None, db=None):
        """Return a ticket change by its number or date.

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            cdate = from_utimestamp(row[0])
        ts = to_utimestamp(cdate)
        fields = {}
        change = {'date': cdate, 'fields': fields}
        for field, author, old, new in self.env.db_query(
                """
                SELECT field, author, oldvalue, newvalue
                FROM ticket_change WHERE ticket=%s AND time=%s
                """, (self.id, ts)):
            fields[field] = {'author': author, 'old': old, 'new': new}
            if field == 'comment':
                change['author'] = author
            elif not field.startswith('_'):
                change.setdefault('author', author)
        if fields:
            return change
Пример #34
0
 def _fetch(self, name, version=None, db=None):
     if not db:
         db = self.env.get_db_cnx()
     cursor = db.cursor()
     if version is not None:
         cursor.execute(
             "SELECT version,time,author,text,comment,readonly "
             "FROM wiki "
             "WHERE name=%s AND version=%s", (name, int(version)))
     else:
         cursor.execute(
             "SELECT version,time,author,text,comment,readonly "
             "FROM wiki "
             "WHERE name=%s ORDER BY version DESC LIMIT 1", (name, ))
     row = cursor.fetchone()
     if row:
         version, time, author, text, comment, readonly = row
         self.version = int(version)
         self.author = author
         self.time = from_utimestamp(time)
         self.text = text
         self.comment = comment
         self.readonly = readonly and int(readonly) or 0
     else:
         self.version = 0
         self.text = self.comment = self.author = ''
         self.time = None
         self.readonly = 0
Пример #35
0
    def get_history(self, item, db=None):
        if not item in self.pool.get_items():
            raise Exception("Item not in pool")

        if item.is_new():
            return

        if db is None:
            db = self.env.get_db_cnx()

        cursor = db.cursor()
        query = """
                SELECT v.id, v.time, v.author, v.ipnr, v.comment
                FROM asa_version v"""
        if isinstance(item, Entity): # it's a spec
            query += """
                    INNER JOIN asa_spec s ON s.version_id=v.id
                    WHERE s.name='%s'
                    """ % (item.get_name())
        else: # it's an artifact
            query += """
                    INNER JOIN asa_artifact a ON a.version_id=v.id
                    WHERE a.id=%d""" % (item.get_id())

        if not self.version is None:
            query += ' AND v.id <= %s' % (self.version,)
        query += ' ORDER BY v.id DESC'
        cursor.execute(query)
        for version, ts, author, ipnr, comment in cursor:
            yield version, from_utimestamp(ts), author, ipnr, comment
    def get_history(self, item, db=None):
        if not item in self.pool.get_items():
            raise Exception("Item not in pool")

        if item.is_new():
            return

        if db is None:
            db = self.env.get_db_cnx()

        cursor = db.cursor()
        query = """
                SELECT v.id, v.time, v.author, v.ipnr, v.comment
                FROM asa_version v"""
        if isinstance(item, Entity):  # it's a spec
            query += """
                    INNER JOIN asa_spec s ON s.version_id=v.id
                    WHERE s.name='%s'
                    """ % (
                item.get_name()
            )
        else:  # it's an artifact
            query += """
                    INNER JOIN asa_artifact a ON a.version_id=v.id
                    WHERE a.id=%d""" % (
                item.get_id()
            )

        if not self.version is None:
            query += " AND v.id <= %s" % (self.version,)
        query += " ORDER BY v.id DESC"
        cursor.execute(query)
        for version, ts, author, ipnr, comment in cursor:
            yield version, from_utimestamp(ts), author, ipnr, comment
Пример #37
0
    def delete_change(self, cnum=None, cdate=None):
        """Delete a ticket change identified by its number or date."""
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            cdate = from_utimestamp(row[0])
        ts = to_utimestamp(cdate)
        with self.env.db_transaction as db:
            # Find modified fields and their previous value
            fields = [(field, old, new) for field, old, new in db(
                """
                        SELECT field, oldvalue, newvalue FROM ticket_change
                        WHERE ticket=%s AND time=%s
                        """, (self.id, ts))
                      if field != 'comment' and not field.startswith('_')]
            for field, oldvalue, newvalue in fields:
                # Find the next change
                for next_ts, in db(
                        """SELECT time FROM ticket_change
                                      WHERE ticket=%s AND time>%s AND field=%s
                                      LIMIT 1
                                      """, (self.id, ts, field)):
                    # Modify the old value of the next change if it is equal
                    # to the new value of the deleted change
                    db(
                        """UPDATE ticket_change SET oldvalue=%s
                          WHERE ticket=%s AND time=%s AND field=%s
                          AND oldvalue=%s
                          """, (oldvalue, self.id, next_ts, field, newvalue))
                    break
                else:
                    # No next change, edit ticket field
                    if field in self.custom_fields:
                        db(
                            """UPDATE ticket_custom SET value=%s
                              WHERE ticket=%s AND name=%s
                              """, (oldvalue, self.id, field))
                    else:
                        db("UPDATE ticket SET %s=%%s WHERE id=%%s" % field,
                           (oldvalue, self.id))

            # Delete the change
            db("DELETE FROM ticket_change WHERE ticket=%s AND time=%s",
               (self.id, ts))

            # Fix the last modification time
            # Work around MySQL ERROR 1093 with the same table for the update
            # target and the subquery FROM clause
            db(
                """UPDATE ticket SET changetime=(
                  SELECT time FROM ticket_change WHERE ticket=%s
                  UNION
                  SELECT time FROM (
                      SELECT time FROM ticket WHERE id=%s LIMIT 1) AS t
                  ORDER BY time DESC LIMIT 1)
                  WHERE id=%s
                  """, (self.id, self.id, self.id))
        self._fetch_ticket(self.id)
Пример #38
0
Файл: model.py Проект: t2y/trac
 def get_history(self):
     """Retrieve the edit history of a wiki page.
     """
     for version, ts, author, comment, ipnr in self.env.db_query("""
             SELECT version, time, author, comment, ipnr FROM wiki
             WHERE name=%s AND version<=%s ORDER BY version DESC
             """, (self.name, self.version)):
         yield version, from_utimestamp(ts), author, comment, ipnr
Пример #39
0
def GlobalBuildqueueIterator(env, req):
    cursor = env.get_db_cnx().cursor()

    if req.args.get('group'):
        group = req.args.get('group')
    else:
        group = ''

    cursor.execute(
        "SELECT builds.id, builds.buildgroup, builds.portname, builds.pkgversion, builds.status, builds.buildstatus, builds.buildreason, builds.buildlog, builds.wrkdir, builds.startdate, CASE WHEN builds.enddate < builds.startdate THEN extract(epoch from now())*1000000 ELSE builds.enddate END, buildqueue.id, buildqueue.priority, buildqueue.owner FROM builds, buildqueue WHERE buildqueue.id = builds.queueid AND builds.status < 90 AND (builds.buildgroup = %s OR %s = '') ORDER BY builds.status DESC, buildqueue.priority, builds.id DESC LIMIT 50",
        (group, group))

    lastport = None
    for id, group, portname, pkgversion, status, buildstatus, buildreason, buildlog, wrkdir, startdate, enddate, queueid, priority, owner in cursor:
        port = Port(env)
        port.id = id
        port.group = group
        port.portname = portname
        port.pkgversion = pkgversion
        port.buildstatus = buildstatus
        port.buildlog = buildlog
        port.wrkdir = wrkdir
        port.runtime = pretty_timedelta(from_utimestamp(startdate),
                                        from_utimestamp(enddate))
        port.startdate = startdate
        port.enddate = enddate
        port.directory = '/~%s/%s-%s' % (owner, queueid, id)
        port.queueid = queueid
        port.owner = owner
        port.setPriority(priority)

        if buildstatus:
            port.buildstatus = buildstatus.lower()
        if buildstatus and not buildreason:
            buildreason = buildstatus.lower()

        if owner == req.authname or status != 20:
            port.highlight = True

        port.setStatus(status, buildreason)

        if lastport != portname:
            port.head = True
            lastport = portname

        yield port
Пример #40
0
 def get_timeline_events(self, req, start, stop, filters):
     if 'project changes' in filters:
         cnx=self.env.get_db_cnx()
         cur=cnx.cursor()
         cur.execute("select who,change,time from project_change where time>=%s AND time<=%s"%\
                      (to_utimestamp(start), to_utimestamp(stop)));
         for who,change,ts in cur:
             yield('project',from_utimestamp(ts),who,change)
    def _populate_from_database(self, row):
        """
        Takes a row returned from a cursor and populates instance 
        attributes based on these values."""

        (name, message, button, mode, 
        groups, start, end, author, created_at) = row

        self['name'] = name
        self['message'] = message
        self['button'] = button
        self['mode'] = mode
        self['groups'] = json.loads(groups) if groups else None
        self['start'] = from_utimestamp(start)
        self['end'] = from_utimestamp(end)
        self['author'] = author
        self['created_at'] = from_utimestamp(created_at)
 def test_get_all_records(self):
     record = self._create_new_record()
     record.insert()
     all_records = ProjectMessageRecord.get_all_records(self.env)
     self.assertEqual(1, len(all_records))
     self.assertEqual(1, all_records[0]['record_id'])
     self.assertEqual("Test Case", all_records[0]['message_name'])
     self.assertEqual("milsomd", all_records[0]['agreed_by'])
     self.assertEqual(from_utimestamp(1396975221114382), all_records[0]['agreed_at'])
     record2 = self._create_new_record_two()
     record2.insert()
     all_records = ProjectMessageRecord.get_all_records(self.env)
     self.assertEqual(2, len(all_records))
     self.assertEqual(2, all_records[1]['record_id'])
     self.assertEqual("Another Test Case", all_records[1]['message_name'])
     self.assertEqual("goldinge", all_records[1]['agreed_by'])
     self.assertEqual(from_utimestamp(1396975221114388), all_records[1]['agreed_at'])
Пример #43
0
 def _do_list(self):
     print_table(
         [(title, int(edits), format_datetime(from_utimestamp(modified),
                                              console_datetime_format))
          for title, edits, modified in self.env.db_query("""
                 SELECT name, max(version), max(time)
                 FROM wiki GROUP BY name ORDER BY name""")
          ], [_("Title"), _("Edits"), _("Modified")])
Пример #44
0
 def _do_list(self):
     print_table(
         [(title, int(edits), format_datetime(from_utimestamp(modified),
                                              console_datetime_format))
          for title, edits, modified in self.env.db_query("""
                 SELECT name, max(version), max(time)
                 FROM wiki GROUP BY name ORDER BY name""")
          ], [_("Title"), _("Edits"), _("Modified")])
Пример #45
0
    def delete_change(self, cnum=None, cdate=None, when=None):
        """Delete a ticket change identified by its number or date."""
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            cdate = from_utimestamp(row[0])
        ts = to_utimestamp(cdate)
        if when is None:
            when = datetime.now(utc)
        when_ts = to_utimestamp(when)

        with self.env.db_transaction as db:
            # Find modified fields and their previous value
            fields = [(field, old, new)
                      for field, old, new in db("""
                        SELECT field, oldvalue, newvalue FROM ticket_change
                        WHERE ticket=%s AND time=%s
                        """, (self.id, ts))
                      if field != 'comment' and not field.startswith('_')]
            for field, oldvalue, newvalue in fields:
                # Find the next change
                for next_ts, in db("""SELECT time FROM ticket_change
                                      WHERE ticket=%s AND time>%s AND field=%s
                                      LIMIT 1
                                      """, (self.id, ts, field)):
                    # Modify the old value of the next change if it is equal
                    # to the new value of the deleted change
                    db("""UPDATE ticket_change SET oldvalue=%s
                          WHERE ticket=%s AND time=%s AND field=%s
                          AND oldvalue=%s
                          """, (oldvalue, self.id, next_ts, field, newvalue))
                    break
                else:
                    # No next change, edit ticket field
                    if field in self.std_fields:
                        db("UPDATE ticket SET %s=%%s WHERE id=%%s"
                           % field, (oldvalue, self.id))
                    else:
                        db("""UPDATE ticket_custom SET value=%s
                              WHERE ticket=%s AND name=%s
                              """, (oldvalue, self.id, field))

            # Delete the change
            db("DELETE FROM ticket_change WHERE ticket=%s AND time=%s",
               (self.id, ts))

            # Update last changed time
            db("UPDATE ticket SET changetime=%s WHERE id=%s",
               (when_ts, self.id))

        self._fetch_ticket(self.id)

        changes = dict((field, (oldvalue, newvalue))
                       for field, oldvalue, newvalue in fields)
        for listener in TicketSystem(self.env).change_listeners:
            if hasattr(listener, 'ticket_change_deleted'):
                listener.ticket_change_deleted(self, cdate, changes)
Пример #46
0
def ticket_activity_user(project_id, username, start_date, end_date, groupsize, groupcnt, db, req):
    """
    Get query response for specified time interval and `username`:
    Data: <event>: <count events>.
    Events: 'created', 'closed'.
    """
    q = '''
        SELECT t.id, t.time, 'created' AS event
        FROM ticket t
        WHERE t.reporter=%s AND t.project_id=%s AND
              t.time >= %s AND t.time < %s
        UNION
        SELECT t.id, tc.time, 'closed' AS event
        FROM ticket t JOIN ticket_change tc ON t.id = tc.ticket
            AND tc.field='status' AND tc.newvalue='closed'
        WHERE t.owner=%s AND t.project_id=%s AND
              tc.time >= %s AND tc.time < %s
        ORDER BY event
    '''
    cursor = db.cursor()
    cursor.execute(q, (username, project_id, to_utimestamp(start_date), to_utimestamp(end_date))*2)
    etypes = (N_('created'), N_('closed'))
    events = [(r[2], from_utimestamp(r[1]), r[0]) for r in cursor]

    # TODO: count closed once, use global closed set
    def init_set(e):
        return set()
    def add_to_set(stor, idx, event_data):
        stor[idx].add(event_data[2])

    groups_list, groups_data = aggregate_events_by_periods(etypes, events,
                                              start_date, groupsize, groupcnt,
                                              add_to_set, init_set)

    for etype, groups in groups_data.iteritems():
        for idx, ids in enumerate(groups):
            groups[idx] = len(ids)

    query_response = QueryResponse("ticket_activity", req.href('/chrome'))
    query_response.set_title(_("Ticket activity from %(start_date)s to %(end_date)s",
                               start_date=format_date(start_date, tzinfo=req.tz),
                               end_date=format_date(end_date, tzinfo=req.tz)))

    groups_data = translate_keys(groups_data)
    columns, rows = adapt_to_table(groups_list, groups_data)
    query_response.set_columns(columns)
    query_response.set_results(rows)

    chart = query_response.chart_info
    chart.type = 'Line'
    chart.width = 600
    chart.x_legend = _('Time periods')
    chart.y_legend = _('Tickets')
    chart.x_labels = groups_list
    chart.data = restructure_data(groups_data)
    chart.tool_tip = "#key#<br>%s:#x_label#<br>%s:#val#" % (_('period'), _('tickets'))

    return query_response
Пример #47
0
 def get_history(self, db=None):
     if not db:
         db = self.env.get_db_cnx()
     cursor = db.cursor()
     cursor.execute("SELECT version,time,author,comment,ipnr FROM wiki "
                    "WHERE name=%s AND version<=%s "
                    "ORDER BY version DESC", (self.name, self.version))
     for version, ts, author, comment, ipnr in cursor:
         yield version, from_utimestamp(ts), author, comment, ipnr
 def test_get_term(self):
     record = self._create_new_record()
     record.insert()
     # retrieve data from db
     retrieved_record = ProjectMessageRecord(self.env, 1)
     self.assertEqual(1, retrieved_record['record_id'])
     self.assertEqual("Test Case", retrieved_record['message_name'])
     self.assertEqual("milsomd", retrieved_record['agreed_by'])
     self.assertEqual(from_utimestamp(1396975221114382), retrieved_record['agreed_at'])
Пример #49
0
    def get_last_modified(self):
        """Retrieve timestamp of last modification, in micro-seconds.

        (wraps ``fs.revision_prop``)
        """
        _date = fs.revision_prop(self.fs_ptr, self.created_rev,
                                 core.SVN_PROP_REVISION_DATE, self.pool())
        if not _date:
            return None
        return from_utimestamp(core.svn_time_from_cstring(_date, self.pool()))
Пример #50
0
 def _do_list(self):
     db = self.env.get_db_cnx()
     cursor = db.cursor()
     cursor.execute("SELECT name, max(version), max(time) "
                    "FROM wiki GROUP BY name ORDER BY name")
     print_table([(r[0], int(r[1]),
                   format_datetime(from_utimestamp(r[2]),
                                   console_datetime_format))
                  for r in cursor],
                 [_('Title'), _('Edits'), _('Modified')])
Пример #51
0
 def get_history(self, db=None):
     if not db:
         db = self.env.get_db_cnx()
     cursor = db.cursor()
     cursor.execute(
         "SELECT version,time,author,comment,ipnr FROM wiki "
         "WHERE name=%s AND version<=%s "
         "ORDER BY version DESC", (self.name, self.version))
     for version, ts, author, comment, ipnr in cursor:
         yield version, from_utimestamp(ts), author, comment, ipnr
Пример #52
0
Файл: svn_fs.py Проект: t2y/trac
    def get_last_modified(self):
        """Retrieve timestamp of last modification, in micro-seconds.

        (wraps ``fs.revision_prop``)
        """
        _date = fs.revision_prop(self.fs_ptr, self.created_rev,
                                 core.SVN_PROP_REVISION_DATE, self.pool())
        if not _date:
            return None
        return from_utimestamp(core.svn_time_from_cstring(_date, self.pool()))
Пример #53
0
    def delete_change(self, cnum=None, cdate=None, when=None):
        """Delete a ticket change identified by its number or date."""
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            cdate = from_utimestamp(row[0])
        ts = to_utimestamp(cdate)
        if when is None:
            when = datetime.now(utc)
        when_ts = to_utimestamp(when)

        with self.env.db_transaction as db:
            # Find modified fields and their previous value
            fields = [(field, old, new) for field, old, new in db(
                """
                        SELECT field, oldvalue, newvalue FROM ticket_change
                        WHERE ticket=%s AND time=%s
                        """, (self.id, ts))
                      if field != 'comment' and not field.startswith('_')]
            for field, oldvalue, newvalue in fields:
                # Find the next change
                for next_ts, in db(
                        """SELECT time FROM ticket_change
                                      WHERE ticket=%s AND time>%s AND field=%s
                                      LIMIT 1
                                      """, (self.id, ts, field)):
                    # Modify the old value of the next change if it is equal
                    # to the new value of the deleted change
                    db(
                        """UPDATE ticket_change SET oldvalue=%s
                          WHERE ticket=%s AND time=%s AND field=%s
                          AND oldvalue=%s
                          """, (oldvalue, self.id, next_ts, field, newvalue))
                    break
                else:
                    # No next change, edit ticket field
                    if field in self.std_fields:
                        db("UPDATE ticket SET %s=%%s WHERE id=%%s" % field,
                           (oldvalue, self.id))
                    else:
                        db(
                            """UPDATE ticket_custom SET value=%s
                              WHERE ticket=%s AND name=%s
                              """, (oldvalue, self.id, field))

            # Delete the change
            db("DELETE FROM ticket_change WHERE ticket=%s AND time=%s",
               (self.id, ts))

            # Update last changed time
            db("UPDATE ticket SET changetime=%s WHERE id=%s",
               (when_ts, self.id))

        self._fetch_ticket(self.id)
Пример #54
0
    def delete_change(self, cnum=None, cdate=None):
        """Delete a ticket change identified by its number or date."""
        if cdate is None:
            row = self._find_change(cnum)
            if not row:
                return
            cdate = from_utimestamp(row[0])
        ts = to_utimestamp(cdate)
        with self.env.db_transaction as db:
            # Find modified fields and their previous value
            fields = [(field, old, new)
                      for field, old, new in db("""
                        SELECT field, oldvalue, newvalue FROM ticket_change
                        WHERE ticket=%s AND time=%s
                        """, (self.id, ts))
                      if field != 'comment' and not field.startswith('_')]
            for field, oldvalue, newvalue in fields:
                # Find the next change
                for next_ts, in db("""SELECT time FROM ticket_change
                                      WHERE ticket=%s AND time>%s AND field=%s
                                      LIMIT 1
                                      """, (self.id, ts, field)):
                    # Modify the old value of the next change if it is equal
                    # to the new value of the deleted change
                    db("""UPDATE ticket_change SET oldvalue=%s
                          WHERE ticket=%s AND time=%s AND field=%s
                          AND oldvalue=%s
                          """, (oldvalue, self.id, next_ts, field, newvalue))
                    break
                else:
                    # No next change, edit ticket field
                    if field in self.custom_fields:
                        db("""UPDATE ticket_custom SET value=%s
                              WHERE ticket=%s AND name=%s
                              """, (oldvalue, self.id, field))
                    else:
                        db("UPDATE ticket SET %s=%%s WHERE id=%%s"
                           % field, (oldvalue, self.id))

            # Delete the change
            db("DELETE FROM ticket_change WHERE ticket=%s AND time=%s",
               (self.id, ts))

            # Fix the last modification time
            # Work around MySQL ERROR 1093 with the same table for the update
            # target and the subquery FROM clause
            db("""UPDATE ticket SET changetime=(
                  SELECT time FROM ticket_change WHERE ticket=%s
                  UNION
                  SELECT time FROM (
                      SELECT time FROM ticket WHERE id=%s LIMIT 1) AS t
                  ORDER BY time DESC LIMIT 1)
                  WHERE id=%s
                  """, (self.id, self.id, self.id))
        self._fetch_ticket(self.id)
Пример #55
0
    def get_history(self):
        """Retrieve the edit history of a wiki page.

        :return: a tuple containing the `version`, `datetime`, `author`
                 and `comment`.
        """
        for version, ts, author, comment in self.env.db_query("""
                SELECT version, time, author, comment FROM wiki
                WHERE name=%s AND version<=%s ORDER BY version DESC
                """, (self.name, self.version)):
            yield version, from_utimestamp(ts), author, comment
Пример #56
0
    def get_history(self, db=None):
        """Retrieve the edit history of a wiki page.

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        for version, ts, author, comment, ipnr in self.env.db_query("""
                SELECT version, time, author, comment, ipnr FROM wiki
                WHERE name=%s AND version<=%s ORDER BY version DESC
                """, (self.name, self.version)):
            yield version, from_utimestamp(ts), author, comment, ipnr
Пример #57
0
def _db_str_to_datetime(value):
    if value is None:
        return None
    try:
        return from_utimestamp(long(value))
    except ValueError:
        pass
    try:
        return parse_date(value.strip(), utc, 'datetime')
    except Exception:
        return None
Пример #58
0
 def __init__(self, repos, rev, env):
     self.env = env
     for _date, author, message in self.env.db_query("""
             SELECT time, author, message FROM revision
             WHERE repos=%s AND rev=%s
             """, (repos.id, repos.db_rev(rev))):
         date = from_utimestamp(_date)
         Changeset.__init__(self, repos, repos.rev_db(rev), message, author,
                            date)
         break
     else:
         raise NoSuchChangeset(rev)
Пример #59
0
    def get_changelog(self, when=None, db=None):
        """Return the changelog as a list of tuples of the form
        (time, author, field, oldvalue, newvalue, permanent).

        While the other tuple elements are quite self-explanatory,
        the `permanent` flag is used to distinguish collateral changes
        that are not yet immutable (like attachments, currently).

        :since 1.0: the `db` parameter is no longer needed and will be removed
        in version 1.1.1
        """
        sid = str(self.id)
        when_ts = to_utimestamp(when)
        if when_ts:
            sql = """
                SELECT time, author, field, oldvalue, newvalue, 1 AS permanent
                FROM ticket_change WHERE ticket=%s AND time=%s
                  UNION
                SELECT time, author, 'attachment', null, filename,
                  0 AS permanent
                FROM attachment WHERE type='ticket' AND id=%s AND time=%s
                  UNION
                SELECT time, author, 'comment', null, description,
                  0 AS permanent
                FROM attachment WHERE type='ticket' AND id=%s AND time=%s
                ORDER BY time,permanent,author
                """
            args = (self.id, when_ts, sid, when_ts, sid, when_ts)
        else:
            sql = """
                SELECT time, author, field, oldvalue, newvalue, 1 AS permanent
                FROM ticket_change WHERE ticket=%s
                  UNION
                SELECT time, author, 'attachment', null, filename,
                  0 AS permanent
                FROM attachment WHERE type='ticket' AND id=%s
                  UNION
                SELECT time, author, 'comment', null, description,
                  0 AS permanent
                FROM attachment WHERE type='ticket' AND id=%s
                ORDER BY time,permanent,author
                """
            args = (self.id, sid, sid)
        log = []
        for t, author, field, oldvalue, newvalue, permanent \
                in self.env.db_query(sql, args):
            if field in self.time_fields:
                oldvalue = _db_str_to_datetime(oldvalue)
                newvalue = _db_str_to_datetime(newvalue)
            log.append((from_utimestamp(t), author, field, oldvalue
                        or '', newvalue or '', permanent))
        return log