Beispiel #1
0
def render_tag_changes(old_tags, new_tags):
    old_tags = split_into_tags(old_tags or '')
    new_tags = split_into_tags(new_tags or '')
    added = sorted(new_tags - old_tags)
    added = added and \
            tagn_("%(tags)s added", "%(tags)s added",
                  len(added), tags=builder.em(', '.join(added)))
    removed = sorted(old_tags - new_tags)
    removed = removed and \
              tagn_("%(tags)s removed", "%(tags)s removed",
                    len(removed), tags=builder.em(', '.join(removed)))
    # TRANSLATOR: How to delimit added and removed tags.
    delim = added and removed and _("; ")
    return builder(builder.strong(_("Tags")), ' ', added, delim, removed)
Beispiel #2
0
def render_tag_changes(old_tags, new_tags):
        old_tags = split_into_tags(old_tags or '')
        new_tags = split_into_tags(new_tags or '')
        added = sorted(new_tags - old_tags)
        added = added and \
                tagn_("%(tags)s added", "%(tags)s added",
                      len(added), tags=builder.em(', '.join(added)))
        removed = sorted(old_tags - new_tags)
        removed = removed and \
                  tagn_("%(tags)s removed", "%(tags)s removed",
                        len(removed), tags=builder.em(', '.join(removed)))
        # TRANSLATOR: How to delimit added and removed tags.
        delim = added and removed and _("; ")
        return builder(builder.strong(_("Tags")), ' ', added,
                       delim, removed)
Beispiel #3
0
    def splitIntoTags(self, req, tag_str):
        """Returns a list of tags from a string.

        Comma, whitespace and combinations of these characters are recognized
        as delimiter, that get stripped from the output.
        """
        return split_into_tags(tag_str)
Beispiel #4
0
 def set_resource_tags(self,
                       req,
                       ticket_or_resource,
                       tags,
                       comment=u'',
                       when=None):
     try:
         resource = ticket_or_resource.resource
     except AttributeError:
         resource = ticket_or_resource
         assert resource.realm == self.realm
         if not self._check_permission(req, resource, 'modify'):
             raise PermissionError(resource=resource, env=self.env)
         tag_set = set(tags)
         # Processing a call from TracTags, try to alter the ticket.
         tkt = Ticket(self.env, resource.id)
         all = self._ticket_tags(tkt)
         # Avoid unnecessary ticket changes, considering comments below.
         if tag_set != all:
             # Will only alter tags in 'keywords' ticket field.
             keywords = split_into_tags(tkt['keywords'])
             # Assume, that duplication is depreciated and consolitation
             # wanted to primarily affect 'keywords' ticket field.
             # Consequently updating ticket tags and reducing (tag)
             # 'ticket_fields' afterwards may result in undesired tag loss.
             tag_set.difference_update(all.difference(keywords))
             tkt['keywords'] = u' '.join(sorted(map(to_unicode, tag_set)))
             tkt.save_changes(get_reporter_id(req), comment)
     else:
         # Processing a change listener event.
         tags = self._ticket_tags(ticket_or_resource)
         super(TicketTagProvider,
               self).set_resource_tags(req, resource, tags)
Beispiel #5
0
def resource_tags(env, resource, db=None, when=None):
    """Return all tags for a Trac resource by realm and ID."""
    db = _get_db(env, db)
    cursor = db.cursor()
    id = to_unicode(resource.id)
    if when is None:
        cursor.execute("""
            SELECT tag
              FROM tags
             WHERE tagspace=%s
               AND name=%s
        """, (resource.realm, id))
        for row in cursor:
            yield row[0]
    else:
        if isinstance(when, datetime):
            when = to_utimestamp(when)
        cursor.execute("SELECT newtags FROM tags_change "
                       "WHERE tagspace=%s AND name=%s AND time<=%s "
                       "ORDER BY time DESC LIMIT 1",
                       (resource.realm, id, when))
        row = cursor.fetchone()
        if row and row[0]:
            for tag in split_into_tags(row[0]):
                yield tag
Beispiel #6
0
 def set_resource_tags(self, req, ticket_or_resource, tags, comment=u'',
                       when=None):
     try:
         resource = ticket_or_resource.resource
     except AttributeError:
         resource = ticket_or_resource
         assert resource.realm == self.realm
         if not self._check_permission(req, resource, 'modify'):
             raise PermissionError(resource=resource, env=self.env)
         tag_set = set(tags)
         # Processing a call from TracTags, try to alter the ticket.
         tkt = Ticket(self.env, resource.id)
         all = self._ticket_tags(tkt)
         # Avoid unnecessary ticket changes, considering comments below.
         if tag_set != all:
             # Will only alter tags in 'keywords' ticket field.
             keywords = split_into_tags(tkt['keywords'])
             # Assume, that duplication is depreciated and consolitation
             # wanted to primarily affect 'keywords' ticket field.
             # Consequently updating ticket tags and reducing (tag)
             # 'ticket_fields' afterwards may result in undesired tag loss.
             tag_set.difference_update(all.difference(keywords))
             tkt['keywords'] = u' '.join(sorted(map(to_unicode, tag_set)))
             tkt.save_changes(get_reporter_id(req), comment)
     else:
         # Processing a change listener event.
         tags = self._ticket_tags(ticket_or_resource)
         super(TicketTagProvider,
               self).set_resource_tags(req, resource, tags)
Beispiel #7
0
def resource_tags(env, resource, db=None, when=None):
    """Return all tags for a Trac resource by realm and ID."""
    db = _get_db(env, db)
    cursor = db.cursor()
    id = to_unicode(resource.id)
    if when is None:
        cursor.execute(
            """
            SELECT tag
              FROM tags
             WHERE tagspace=%s
               AND name=%s
        """, (resource.realm, id))
        for row in cursor:
            yield row[0]
    else:
        if isinstance(when, datetime):
            when = to_utimestamp(when)
        cursor.execute(
            "SELECT newtags FROM tags_change "
            "WHERE tagspace=%s AND name=%s AND time<=%s "
            "ORDER BY time DESC LIMIT 1", (resource.realm, id, when))
        row = cursor.fetchone()
        if row and row[0]:
            for tag in split_into_tags(row[0]):
                yield tag
Beispiel #8
0
    def _update_tags(self, req, page, when=None):
        newtags = split_into_tags(req.args.get('tags', ''))
        oldtags = self.tag_system.get_tags(req, page.resource)

        if oldtags != newtags:
            self.tag_system.set_tags(req, page.resource, newtags, when=when)
            return True
        return False
Beispiel #9
0
    def _update_tags(self, req, page, when=None):
        newtags = split_into_tags(req.args.get('tags', ''))
        oldtags = self.tag_system.get_tags(req, page.resource)

        if oldtags != newtags:
            self.tag_system.set_tags(req, page.resource, newtags, when=when)
            return True
        return False
Beispiel #10
0
    def _post_process_request_history(self, req, data):
        history = []
        page_histories = data.get('history', [])
        resource = data['resource']
        tags_histories = tag_changes(self.env, resource)

        for page_history in page_histories:
            while tags_histories and \
                    tags_histories[0][0] >= page_history['date']:
                tags_history = tags_histories.pop(0)
                date = tags_history[0]
                author = tags_history[1]
                old_tags = split_into_tags(tags_history[2] or '')
                new_tags = split_into_tags(tags_history[3] or '')
                added = sorted(new_tags - old_tags)
                added = added and \
                        tagn_("%(tags)s added", "%(tags)s added",
                              len(added), tags=tag.em(', '.join(added)))
                removed = sorted(old_tags - new_tags)
                removed = removed and \
                          tagn_("%(tags)s removed", "%(tags)s removed",
                                len(removed), tags=tag.em(', '.join(removed)))
                # TRANSLATOR: How to delimit added and removed tags.
                delim = added and removed and _("; ")
                comment = tag(tag.strong(_("Tags")), ' ', added, delim,
                              removed)
                url = req.href(resource.realm, resource.id,
                               version=page_history['version'],
                               tags_version=to_utimestamp(date))
                history.append({'version': '*', 'url': url, 'date': date,
                                'author': author, 'comment': comment,
                                'ipnr': ''})
            history.append(page_history)

        data.update(dict(history=history,
                         wiki_to_oneliner=self._wiki_to_oneliner))
Beispiel #11
0
    def _fetch_tkt_tags(self, db):
        """Transfer all relevant ticket attributes to tags db table."""
        # Initial sync is done by forced, stupid one-way mirroring.
        # Data aquisition for this utilizes the known ticket tags query.
        fields = ["COALESCE(%s, '')" % f for f in self.fields]
        ignore = ''
        if self.ignore_closed_tickets:
            ignore = " AND status != 'closed'"
        sql = """
            SELECT *
              FROM (SELECT id, %s, %s AS std_fields
                      FROM ticket AS tkt
                     WHERE NOT EXISTS (SELECT * FROM tags
                                       WHERE tagspace=%%s AND name=%s)
                     %s) AS s
             WHERE std_fields != ''
             ORDER BY id
            """ % (','.join(self.fields), db.concat(*fields),
                   db.cast('tkt.id', 'text'), ignore)
        self.env.log.debug(sql)
        # Obtain cursors for reading tickets and altering tags db table.
        # DEVEL: Use appropriate cursor typs from Trac 1.0 db API.
        ro_cursor = db.cursor()
        rw_cursor = db.cursor()
        # Delete tags for non-existent ticket
        rw_cursor.execute(
            """
            DELETE FROM tags
             WHERE tagspace=%%s
               AND NOT EXISTS (SELECT * FROM ticket AS tkt
                               WHERE tkt.id=%s%s)
            """ % (db.cast('tags.name', 'int'), ignore), (self.realm, ))

        self.log.debug('ENTER_TAG_DB_CHECKOUT')
        ro_cursor.execute(sql, (self.realm, ))
        self.log.debug('EXIT_TAG_DB_CHECKOUT')
        self.log.debug('ENTER_TAG_SYNC')

        for row in ro_cursor:
            tkt_id, ttags = row[0], ' '.join([f for f in row[1:-1] if f])
            ticket_tags = split_into_tags(ttags)
            rw_cursor.executemany(
                """
                INSERT INTO tags
                       (tagspace, name, tag)
                VALUES (%s, %s, %s)
                """, [(self.realm, str(tkt_id), tag) for tag in ticket_tags])
        self.log.debug('EXIT_TAG_SYNC')
Beispiel #12
0
    def _fetch_tkt_tags(self, db):
        """Transfer all relevant ticket attributes to tags db table."""
        # Initial sync is done by forced, stupid one-way mirroring.
        # Data aquisition for this utilizes the known ticket tags query.
        fields = ["COALESCE(%s, '')" % f for f in self.fields]
        ignore = ''
        if self.ignore_closed_tickets:
            ignore = " AND status != 'closed'"
        sql = """
            SELECT *
              FROM (SELECT id, %s, %s AS std_fields
                      FROM ticket AS tkt
                     WHERE NOT EXISTS (SELECT * FROM tags
                                       WHERE tagspace=%%s AND name=%s)
                     %s) AS s
             WHERE std_fields != ''
             ORDER BY id
            """ % (','.join(self.fields), db.concat(*fields),
                   db.cast('tkt.id', 'text'), ignore)
        # Obtain cursors for reading tickets and altering tags db table.
        # DEVEL: Use appropriate cursor typs from Trac 1.0 db API.
        ro_cursor = db.cursor()
        rw_cursor = db.cursor()
        # Delete tags for non-existent ticket
        rw_cursor.execute("""
            DELETE FROM tags
             WHERE tagspace=%%s
               AND NOT EXISTS (SELECT * FROM ticket AS tkt
                               WHERE tkt.id=%s%s)
            """ % (db.cast('tags.name', 'int'), ignore),
            (self.realm,))

        self.log.debug('ENTER_TAG_DB_CHECKOUT')
        ro_cursor.execute(sql, (self.realm,))
        self.log.debug('EXIT_TAG_DB_CHECKOUT')
        self.log.debug('ENTER_TAG_SYNC')

        for row in ro_cursor:
            tkt_id, ttags = row[0], ' '.join([f for f in row[1:-1] if f])
            ticket_tags = split_into_tags(ttags)
            rw_cursor.executemany("""
                INSERT INTO tags
                       (tagspace, name, tag)
                VALUES (%s, %s, %s)
                """, [(self.realm, str(tkt_id), tag) for tag in ticket_tags])
        self.log.debug('EXIT_TAG_SYNC')
Beispiel #13
0
def resource_tags(env, resource, when=None):
    """Return all tags for a Trac resource by realm and ID."""
    id = to_unicode(resource.id)
    if when is None:
        for tag, in env.db_query("""
                SELECT tag FROM tags
                WHERE tagspace=%s AND name=%s
                """, (resource.realm, id)):
            yield tag
    else:
        if isinstance(when, datetime):
            when = to_utimestamp(when)
        for newtags, in env.db_query("""
                SELECT newtags FROM tags_change
                WHERE tagspace=%s AND name=%s AND time<=%s
                ORDER BY time DESC LIMIT 1
                """, (resource.realm, id, when)):
            for tag in split_into_tags(newtags):
                yield tag
Beispiel #14
0
def resource_tags(env, resource, when=None):
    """Return all tags for a Trac resource by realm and ID."""
    id = to_unicode(resource.id)
    if when is None:
        for tag, in env.db_query("""
                SELECT tag FROM tags
                WHERE tagspace=%s AND name=%s
                """, (resource.realm, id)):
            yield tag
    else:
        if isinstance(when, datetime):
            when = to_utimestamp(when)
        for newtags, in env.db_query("""
                SELECT newtags FROM tags_change
                WHERE tagspace=%s AND name=%s AND time<=%s
                ORDER BY time DESC LIMIT 1
                """, (resource.realm, id, when)):
            for tag in split_into_tags(newtags):
                yield tag
Beispiel #15
0
 def _ticket_tags(self, ticket):
     return split_into_tags(' '.join(
         filter(None, [ticket[f] for f in self.fields])))
Beispiel #16
0
 def _ticket_tags(self, ticket):
     return split_into_tags(
         ' '.join(filter(None, [ticket[f] for f in self.fields])))