Commits

Tetsuya Morimoto committed 910e840

changed to pick up ticket id in description/comment

Comments (0)

Files changed (3)

 from trac.util.translation import domain_functions
 
 from model import CUSTOM_FIELDS, TICKETREF, TicketLinks
+from utils import cnv_sorted_refs, get_refs_in_comment
 
 _, add_domain = domain_functions("ticketref", ("_", "add_domain"))
 
 
     # ITicketChangeListener methods
     def ticket_created(self, ticket):
+        links = None
+        desc_refs = get_refs_in_comment(ticket["description"])
+        if desc_refs:
+            ticket[TICKETREF] = cnv_sorted_refs(ticket[TICKETREF], desc_refs)
+            links = TicketLinks(self.env, ticket)
+            links.add_reference(desc_refs)
+
         if self.has_ticket_refs(ticket):
             self.log.debug("TracTicketReference: ticket are creating")
-            links = TicketLinks(self.env, ticket)
+            if not links:
+                links = TicketLinks(self.env, ticket)
             links.create()
 
     def ticket_changed(self, ticket, comment, author, old_values):
-        if TICKETREF in old_values:
+        links = None
+        need_change = TICKETREF in old_values
+
+        com_refs = get_refs_in_comment(comment)
+        if com_refs:
+            links = TicketLinks(self.env, ticket)
+            links.add_reference(com_refs)
+            need_change = True
+
+        if need_change:
             self.log.debug("TracTicketReference: ticket are changing")
-            links = TicketLinks(self.env, ticket)
-            links.change(author, old_values[TICKETREF])
+            if not links:
+                links = TicketLinks(self.env, ticket)
+            links.change(author, old_values.get(TICKETREF))
 
     def ticket_deleted(self, ticket):
         if self.has_ticket_refs(ticket):

ticketref/model.py

 from trac.ticket.model import Ticket
 from trac.util.datefmt import utc, to_utimestamp
 
-from utils import cnv_text2list, cnv_list2text
+from utils import cnv_list2text, cnv_sorted_refs, cnv_text2list
 
 CUSTOM_FIELDS = [
     {"name": "ticketref",
         self.ticket = ticket
         self.time_stamp = to_utimestamp(datetime.now(utc))
 
+    def add_reference(self, refs):
+        c = self.cursor
+        for ref_id in refs:
+            c.execute(SELECT_TICKETREF % self.ticket.id)
+            row = c.fetchone()
+            if row:
+                target_refs = cnv_text2list(row[0])
+                if not ref_id in target_refs:
+                    target_refs.add(ref_id)
+                    new_text = cnv_list2text(target_refs)
+                    c.execute(UPDATE_TICKETREF % (new_text, self.ticket.id))
+                    self.ticket[TICKETREF] = cnv_sorted_refs(
+                                        self.ticket[TICKETREF], set([ref_id]))
+            else:
+                c.execute(INSERT_TICKETREF % (self.ticket.id, ref_id))
+                self.ticket[TICKETREF] = u"%s" % ref_id
+
     def remove_cross_reference(self, refs, author):
         c = self.cursor
         for ref_id in refs:
             row = c.fetchone()
             if row:
                 target_refs = cnv_text2list(row[0])
-                target_refs.add(self.ticket.id)
-                new_text = cnv_list2text(target_refs)
-                c.execute(UPDATE_TICKETREF % (new_text, ref_id))
+                if not self.ticket.id in target_refs:
+                    target_refs.add(self.ticket.id)
+                    new_text = cnv_list2text(target_refs)
+                    c.execute(UPDATE_TICKETREF % (new_text, ref_id))
+                    c.execute(INSERT_TICKETCHG % (
+                        ref_id, self.time_stamp, author, "", self.ticket.id))
             else:
                 c.execute(INSERT_TICKETREF % (ref_id, self.ticket.id))
-            c.execute(INSERT_TICKETCHG % (
-                ref_id, self.time_stamp, author, "", self.ticket.id))
+                c.execute(INSERT_TICKETCHG % (
+                    ref_id, self.time_stamp, author, "", self.ticket.id))
 
     def create(self):
         refs = cnv_text2list(self.ticket[TICKETREF])

ticketref/utils.py

 # -*- coding: utf-8 -*-
 
+import re
+
+_RE_REFS_WITH_IDS = re.compile(r"""
+    ^.*?(?P<ref_text>(ref.*?)\s+(\#\d+[,|\s]*){1,})
+""", re.U | re.X)
+
+def get_refs_in_comment(comment):
+    """ pick out reference text and convert text to ids
+    >>> get_refs_in_comment(u"refs. #1")
+    set([1])
+    >>> get_refs_in_comment(u"refs. #1ab")
+    set([1])
+    >>> get_refs_in_comment(u"refs. a#1b")
+    set([])
+    >>> get_refs_in_comment(u"some refer #1, #3, some")
+    set([1, 3])
+    >>> get_refs_in_comment(u"some refer #1,#3,#5 # 7 some")
+    set([1, 3, 5])
+    >>> get_refs_in_comment(u"ref #1,#3  ref, #5 #7 refs")
+    set([1, 3])
+    >>> get_refs_in_comment(u"ref #1,#3  ref #5, #7")
+    set([1, 3])
+    >>> get_refs_in_comment(u"refs#1")
+    set([])
+    >>> get_refs_in_comment(u"reference#1 #3, #5")
+    set([1, 3, 5])
+    """
+    ref_ids = set([])
+    match = re.match(_RE_REFS_WITH_IDS, comment)
+    if match:
+        ref_text = match.groupdict().get("ref_text")
+        ref_ids = get_ref_ids_in_comment(ref_text)
+    return ref_ids
+
+_RE_TICKET_IDS = re.compile(r"(#\d+)", re.U)
+
+def get_ref_ids_in_comment(text):
+    """ return only id numbers with list
+    >>> get_ref_ids_in_comment("")
+    set([])
+    >>> get_ref_ids_in_comment("#1")
+    set([1])
+    >>> get_ref_ids_in_comment("refs #1")
+    set([1])
+    >>> get_ref_ids_in_comment("refs #1, ")
+    set([1])
+    >>> get_ref_ids_in_comment("refs #1, #2")
+    set([1, 2])
+    >>> get_ref_ids_in_comment("refs #1,#2,   #3 ids")
+    set([1, 2, 3])
+    """
+    ref_ids = re.findall(_RE_TICKET_IDS, text)
+    return set([int(id_.replace("#", "")) for id_ in ref_ids])
+
 def cnv_text2list(refs_text):
     """ convert text to list
     >>> cnv_text2list("")
     set([])
+    >>> cnv_text2list(", ")
+    set([])
     >>> cnv_text2list("1")
     set([1])
     >>> cnv_text2list("1, 3")
     set([1, 3])
     >>> cnv_text2list("  1,3,   5")
     set([1, 3, 5])
+    >>> cnv_text2list(",  1,3,")
+    set([1, 3])
     """
     refs = set([])
-    if refs_text and refs_text.strip():
+    if refs_text:
+        refs_text = refs_text.strip(" ,")
+    if refs_text:
         refs = set([int(id_.strip()) for id_ in refs_text.split(",")])
     return refs
 
     u'1, 3'
     """
     return u", ".join(str(i) for i in sorted(refs))
+
+def cnv_sorted_refs(orig_text, extra_refs):
+    """
+    >>> cnv_sorted_refs(u"", set([]))
+    u''
+    >>> cnv_sorted_refs(u"1", set([]))
+    u'1'
+    >>> cnv_sorted_refs(u"", set([3, 1]))
+    u'1, 3'
+    >>> cnv_sorted_refs(u"1, 5", set([3, 1]))
+    u'1, 3, 5'
+    >>> cnv_sorted_refs(u"2, 1, 5", set([3, 1, 2]))
+    u'1, 2, 3, 5'
+    """
+    refs = cnv_text2list(orig_text)
+    refs.update(extra_refs)
+    return cnv_list2text(refs)