From cc2e5fdac4b72075d62bab71d5ae67eb3fc215a2 Mon Sep 17 00:00:00 2001
From: Johann Jacobsohn <j.jacobsohn@satzmedia.de>
Date: Mon, 3 Aug 2020 20:59:06 +0200
Subject: [PATCH] add doi link

---
 papersurfer.py | 67 +++++++++++++++++++++++++++++++++++---------------
 1 file changed, 47 insertions(+), 20 deletions(-)

diff --git a/papersurfer.py b/papersurfer.py
index 77a6228..691fda4 100644
--- a/papersurfer.py
+++ b/papersurfer.py
@@ -11,6 +11,7 @@ UI:
 """
 import subprocess
 from dataclasses import dataclass
+import re
 from functools import partial
 from mattermostdriver import Driver
 import urwid
@@ -26,6 +27,22 @@ class PostDTO:
     id: str
     message: str
     reporter: str
+    doi: str
+
+
+class Doi:
+    """Interface w/ the doi.org api"""
+    def get_doi_link(self, doi):
+        return f"http://doi.org/$doi"
+
+    def extract_doi(self, hay):
+        """Parse doi from string, or None if not found.
+
+        >>> Doi().extract_doi("https://doi.org/10.1093/petrology/egaa077")
+        '10.1093/petrology/egaa077'
+        """
+        matches = re.compile(r'\b10\.\d{4,9}/[-._;()/:A-Z0-9]+', re.I).search(hay)
+        return matches.group() if matches else None
 
 
 class Mattermost:
@@ -53,6 +70,7 @@ class Mattermost:
                     id=m['id'],
                     message=m['message'],
                     reporter=self.get_reporter(m['user_id']),
+                    doi=Doi().extract_doi(m['message']),
                 )
                 for m in posts['posts'].values()]
 
@@ -87,13 +105,10 @@ class Papersurfer:
         div = urwid.Divider(u'-')
 
         self.mtm = Mattermost(username, password)
-        papers = self.mtm.retrieve()
-        body = []
-        for paper in papers:
-            button = self.highlight(paper)
-            body.append(urwid.AttrMap(button, None, focus_map='reversed'))
 
+        body = [self.listItem(paper) for paper in self.mtm.retrieve()]
         self.listcontent = urwid.SimpleFocusListWalker(body)
+
         paperlist = urwid.BoxAdapter(urwid.ListBox(self.listcontent),
                                      self.size[1] - 5)
         pile = urwid.Pile([ask, div, paperlist, div, exitbutton])
@@ -104,10 +119,9 @@ class Papersurfer:
 
         urwid.MainLoop(top, palette).run()
 
-    def highlight(self, paper, needle=""):
+    def listItem(self, paper, needle=""):
         """Create highlighted text entry."""
         text_items = []
-        import re
         needle = needle or "ßß"
         msg = f"{paper.message} ({paper.reporter})"
         needles = re.findall(needle, msg, flags=re.IGNORECASE)
@@ -117,32 +131,45 @@ class Papersurfer:
             if i < len(needles):
                 text_items.append(('needle', needles[i]))
 
-        button = urwid.Button(text_items)
-        urwid.connect_signal(button, 'click',
-                             partial(self.handle_paper, paper))
+        title = urwid.Text(text_items)
+        discuss_button = urwid.Button("Open Discussion")
+        doi_button = urwid.Button("Open DOI")
+        button_bar = urwid.Columns([discuss_button, doi_button])
+        urwid.connect_signal(discuss_button, 'click',
+                             partial(self.h_open_discussion, paper))
 
-        return button
+        urwid.connect_signal(doi_button, 'click',
+                             partial(self.h_open_doi, paper))
+        pile = urwid.Pile([title, button_bar, urwid.Divider()])
+        return pile
 
-    def onchange(self, _, new_edit_text):
+    def onchange(self, _, needle):
         """Handle filter change."""
-        papers = self.mtm.get_filtered(new_edit_text)
         self.listcontent.clear()
-        for paper in papers:
-            button = self.highlight(paper, new_edit_text)
-            self.listcontent.append(urwid.AttrMap(button, None,
-                                                  focus_map='reversed'))
+        self.listcontent.extend([self.listItem(paper, needle)
+                                 for paper in self.mtm.get_filtered(needle)])
 
     def on_exit_clicked(self, button):
         """Handle exitbutton click and exit."""
         raise urwid.ExitMainLoop()
 
-    def handle_paper(self, post, _):
-        self.open_post(post)
+    def h_open_discussion(self, post, _):
+        """Handle click/enter on discussion button."""
+        self.open_discussion(post)
+
+    def h_open_doi(self, post, _):
+        """Handle click/enter on doi button."""
+        self.open_doi(post)
 
-    def open_post(self, post):
+    def open_discussion(self, post):
+        """Open Mattermost post in browser."""
         link = f"https://mattermost.cen.uni-hamburg.de/ifg/pl/{post.id}"
         subprocess.call(["xdg-open", link])
 
+    def open_doi(self, post):
+        """Open paper page in browser."""
+        subprocess.call(["xdg-open", Doi().get_doi_link(post.doi)])
+
 
 def parse_args():
     """Parse command line arguments and config file."""
-- 
GitLab