Bubble [main]

Fixes for issue cross-references

d9819a1bf6ec13132b198e37b1c2ae918fa106e6
diff --git a/feeds.py b/feeds.py
index 0e164b9..61ee7ce 100644
--- a/feeds.py
+++ b/feeds.py
@@ -168,6 +168,23 @@ def make_post_page(session, post):
 
     page = session.render_post(post)
 
+    commits = []
+    incoming_xrefs = []
+    outgoing_xrefs = {}
+    if post.issueid:
+        repo = db.get_repository(subspace=session.context)
+        commits = db.get_commits(repo, issueid=post.issueid)
+        incoming_xrefs = db.get_issue_crossrefs(session.context,
+                                                incoming_to_issueid=post.issueid)
+        outgoing_xrefs = db.get_issue_crossrefs(session.context,
+                                                outgoing_from_issueid=post.issueid)
+
+        # Cross references outgoing from the main post itself.
+        if outgoing_xrefs and post.id in outgoing_xrefs:
+            page += '\n'
+            for xref in outgoing_xrefs[post.id]:
+                page += xref.outgoing_entry()
+
     # Poll.
     poll = session.render_poll(post, show_results=not session.user)
     if poll:
@@ -249,16 +266,7 @@ def make_post_page(session, post):
     display_order_desc = not session.user or \
         session.user.sort_cmt == User.SORT_COMMENT_NEWEST
     comments = db.get_posts(parent=post.id, draft=False, sort_descending=False, limit=None)
-    commits = []
-    incoming_xrefs = []
-    outgoing_xrefs = {}
-    if post.issueid:
-        repo = db.get_repository(subspace=session.context)
-        commits = db.get_commits(repo, issueid=post.issueid)
-        incoming_xrefs = db.get_issue_crossrefs(session.context,
-                                                incoming_to_issueid=post.issueid)
-        outgoing_xrefs = db.get_issue_crossrefs(session.context,
-                                                outgoing_from_issueid=post.issueid)
+
     n = len(comments)
     if n > 0 or commits or incoming_xrefs:
         if n > 1:
@@ -279,19 +287,12 @@ def make_post_page(session, post):
 
             # Commits are shown as links to the Git viewer.
             if isinstance(cmt, Commit):
-                rendered_comments.append(
-                    f'=> {repo.view_url}/{cmt.hash} Commit {cmt.hash[:8]} · {clean_title(cmt.msg)}\n' +
-                    ago_text(cmt.ts) + '\n'
-                )
+                rendered_comments.append(cmt.entry(repo.view_url))
                 continue
 
             # Cross-references incoming from other issues.
             if isinstance(cmt, Crossref):
-                x_url = f'/s/{cmt.sub_name}/{cmt.id}'
-                x_icon = '✔︎' if '✔︎' in cmt.tags else '🐞'
-                rendered_comments.append(
-                    f'=> {x_url} {x_icon} Mentioned in #{cmt.issueid}: {cmt.title}\n{ago_text(cmt.ts_created)}\n'
-                )
+                rendered_comments.append(cmt.incoming_entry())
                 continue
 
             src = f'=> /u/{cmt.poster_name} {cmt.poster_avatar} {cmt.poster_name}\n'
@@ -300,9 +301,7 @@ def make_post_page(session, post):
             # Cross-references to other issues.
             if outgoing_xrefs and cmt.id in outgoing_xrefs:
                 for xref in outgoing_xrefs[cmt.id]:
-                    x_url = f'/s/{xref.sub_name}/{xref.id}'
-                    x_icon = '✔︎' if '✔︎' in xref.tags else '🐞'
-                    src += f'=> {x_url} {x_icon} — #{xref.issueid}: {xref.title}\n'
+                    src += xref.outgoing_entry()
 
             # Hide the `age` if it's the same as the previous entry (in reading order).
             comment_age = cmt.age()
diff --git a/model.py b/model.py
index f475a14..e118b8b 100644
--- a/model.py
+++ b/model.py
@@ -229,6 +229,9 @@ class Commit:
         dt = datetime.datetime.fromtimestamp(self.ts, UTC)
         return dt.strftime('%Y-%m-%d')
 
+    def entry(self, view_url):
+        return f'=> {view_url}/{self.hash} Commit {self.hash[:8]} · {clean_title(self.msg)}\n' + ago_text(self.ts) + '\n'
+
 
 class Post:
     TAG_PINNED = 'pinned'
@@ -300,6 +303,16 @@ class Crossref (Post):
                          None, None, None, None, tags, ts_created,
                          None, None, sub_name)
 
+    def incoming_entry(self):
+        x_url = f'/s/{self.sub_name}/{self.id}'
+        x_icon = '✔︎' if '✔︎' in self.tags else '🐞'
+        return f'=> {x_url} {x_icon} Mentioned in #{self.issueid}: {self.title}\n{ago_text(self.ts_created)}\n'
+
+    def outgoing_entry(self):
+        x_url = f'/s/{self.sub_name}/{self.id}'
+        x_icon = '✔︎' if '✔︎' in self.tags else '🐞'
+        return f'=> {x_url} {x_icon} — #{self.issueid}: {self.title}\n'
+
 
 class File:
     def __init__(self, id, segment, user, name, mimetype, data,
@@ -1090,25 +1103,29 @@ class Database:
 
                 self.commit()
 
-            # Notify mentioned users.
             all_text = []
             for segment in self.get_segments(post):
                 if segment.type == Segment.TEXT:
                     all_text.append(segment.content)
+
+            # Notify mentioned users.
             self.notify_mentioned(post, ' '.join(all_text))
 
-        if self.get_subspace(post.subspace).flags & Subspace.ISSUE_TRACKER and \
-                post.issueid is None and \
-                post.parent == 0:
-            # Time to assign a new issue number.
-            cur.execute("""
-                UPDATE posts
-                SET issueid=(SELECT nextissueid FROM subspaces WHERE id=?)
-                WHERE id=?
-            """, (post.subspace, post.id))
-            cur.execute("UPDATE subspaces SET nextissueid=nextissueid+1 WHERE id=?",
-                (post.subspace,))
-            self.commit()
+        if self.get_subspace(post.subspace).flags & Subspace.ISSUE_TRACKER:
+            if post.issueid is None and post.parent == 0:
+                # Time to assign a new issue number.
+                cur.execute("""
+                    UPDATE posts
+                    SET issueid=(SELECT nextissueid FROM subspaces WHERE id=?)
+                    WHERE id=?
+                """, (post.subspace, post.id))
+                cur.execute("UPDATE subspaces SET nextissueid=nextissueid+1 WHERE id=?",
+                    (post.subspace,))
+                self.commit()
+
+            # Update all crossrefrences found in text segments (posts and comments).
+            for segment in self.get_segments(post):
+                self.update_segment_crossrefs(segment)
 
         self.update_user(post.user, active=True)
         self.update_subspace(post.subspace, active=True)
@@ -1162,6 +1179,7 @@ class Database:
         if content != None:
             set_stm.append('content=?')
             values.append(content)
+            segment.content = content
         if url != None:
             set_stm.append('url=?')
             values.append(url)
@@ -1175,8 +1193,8 @@ class Database:
         if not post.is_draft:
             self.update_post_summary(post)
         if content:
-            self.update_segment_crossrefs(segment) # from text segments
             if not post.is_draft:
+                self.update_segment_crossrefs(segment)
                 self.notify_mentioned(post, content)
 
     def get_segments(self, post, poll=None):
@@ -1213,6 +1231,7 @@ class Database:
             seg_post = self.get_post(id=segment.post)
             parent_post = self.get_post(id=seg_post.parent) if seg_post.parent else None
             issue_post = parent_post if parent_post else seg_post
+            print('xref', issue_post.issueid)
             if not issue_post.issueid:
                 return
 
@@ -1226,7 +1245,8 @@ class Database:
                     INSERT IGNORE INTO crossrefs
                         (subspace, post, segment, issueid, dst_post, dst_issueid, ts)
                     SELECT
-                        {issue_post.subspace}, {issue_post.id}, {segment.id}, {issue_post.issueid}, id, {dst_issueid}, ?
+                        {issue_post.subspace}, {issue_post.id}, {segment.id},
+                        {issue_post.issueid}, id, {dst_issueid}, ?
                     FROM posts
                     WHERE issueid=?
                 """, (datetime.datetime.fromtimestamp(seg_post.ts_created),