Repository: internetarchive/openlibrary

Issue:
Display author date(s) with name for librarians
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
Author disambiguation is difficult and even more difficult when the author names all look the same for different identities. To see precisely which author is associated with a work, one must either click the author to view the profile or go into edit mode and use the author selection box.

### Describe the problem that you'd like solved
<!-- A clear and concise description of what you want to happen. -->
Authors should display their associated years to make this task less cumbersome. 

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

<!-- Which suggestions or requirements should be considered for how feature needs to appear or be implemented? -->
Only the year is necessary, any other date information does not need to be displayed.
This should be a librarian-feature only.

### Additional context
<!-- Add any other context or screenshots about the feature request here. -->

For example, these are two different Stephen Kings:
<img width="454" alt="Screenshot 2023-04-19 at 09 02 16" src="https://user-images.githubusercontent.com/17739465/232992930-9b99cdaf-2e84-491f-bea3-ec4457b18a32.png">
<img width="484" alt="Screenshot 2023-04-19 at 09 02 38" src="https://user-images.githubusercontent.com/17739465/232993031-8c846762-0dee-4d60-9c83-b10100d4be65.png">

A display like this would make disambiguation much easier and less time-consuming:
<img width="314" alt="Screenshot 2023-04-19 at 09 04 35" src="https://user-images.githubusercontent.com/17739465/232993643-55f2d88f-ff8f-487b-8931-aaa447f54acf.png">
<img width="466" alt="Screenshot 2023-04-19 at 09 04 47" src="https://user-images.githubusercontent.com/17739465/232993680-717724ab-907f-473c-9c4a-048575328ed1.png">

### Stakeholders
<!-- @ tag stakeholders of this bug -->





Discussion:
@seabelis 
Why librarian-feature only? Many of us mortals have struggled with this problem.
@LeadSongDog @mekarpeles indicated that this is preferred.
> @mekarpeles indicated that this is preferred.

Preferred by a representative sample of customers? I missed the fact that this was spec'd as librarian only and agree that it is generally useful. What is the down side to having more information available to everyone?
The logic is that this area of the page is already featuring a lot of information. The downside to having more information _visible_ (note the information is/was always _available_) is that it can make it difficult to realize what information to focus on, and potentially look cluttered. My guess would be that a very large chunk of the users accessing this page would not have their experience improved by having that extra information in one of the most prominent pieces of realestate on this page, and in fact it would defer their attention from information that might be more meaningful to them.
@cdrini 
"Available" only in the sense that the Lost Ark was available to Indiana Jones with sufficient motivation, persistence, and willingness to risk bending rules.  A library's task is to make correct information readily accessible.  Perhaps a compromise then: don’t show it on small screens, where errors are unlikely to be corrected anyhow. Otherwise we have no hope of ever prying apart all the John Smith misattributions.
Working on it

Resolving patch:
diff --git a/openlibrary/plugins/worksearch/code.py b/openlibrary/plugins/worksearch/code.py
--- a/openlibrary/plugins/worksearch/code.py
+++ b/openlibrary/plugins/worksearch/code.py
@@ -338,6 +338,8 @@ def get_doc(doc: SolrDocument):
                 key=key,
                 name=name,
                 url=f"/authors/{key}/{urlsafe(name or 'noname')}",
+                birth_date=doc.get('birth_date', None),
+                death_date=doc.get('death_date', None),
             )
             for key, name in zip(doc.get('author_key', []), doc.get('author_name', []))
         ],


Test patch:
diff --git a/openlibrary/plugins/worksearch/tests/test_worksearch.py b/openlibrary/plugins/worksearch/tests/test_worksearch.py
--- a/openlibrary/plugins/worksearch/tests/test_worksearch.py
+++ b/openlibrary/plugins/worksearch/tests/test_worksearch.py
@@ -47,6 +47,8 @@ def test_get_doc():
                         'key': 'OL218224A',
                         'name': 'Alan Freedman',
                         'url': '/authors/OL218224A/Alan_Freedman',
+                        'birth_date': None,
+                        'death_date': None,
                     }
                 )
             ],
diff --git a/tests/integration/test_author_name.py b/tests/integration/test_author_name.py
new file mode 100644
--- /dev/null
+++ b/tests/integration/test_author_name.py
@@ -0,0 +1,97 @@
+import pytest
+from splinter import Browser
+
+
+class TestAuthorName:
+    host = 'http://localhost:8080/works'
+
+    @pytest.fixture()
+    def browser(self):
+        browser = Browser('chrome')
+        yield browser
+        browser.quit()
+
+    def test_author_name_with_dates(self, browser):
+        url = self.host + '/OL118420W/Flatland'
+        browser.visit(url)
+        title = browser.find_by_css(".edition-byline")[0].text
+        begin_of_date = title.find('(')
+        if begin_of_date:
+            begin_of_date += 1
+        end_of_date = title.find(')')
+        date = title[begin_of_date:end_of_date]
+        assert date
+
+    def test_author_birth_and_death_year(self, browser):
+        url = self.host + '/OL118420W/Flatland'
+        browser.visit(url)
+        title = browser.find_by_css(".edition-byline")[0].text
+        begin_of_date = title.find('(')
+        if begin_of_date:
+            begin_of_date += 1
+        end_of_date = title.find(')')
+        date = title[begin_of_date:end_of_date]
+        len_if_author_alive = 7
+        len_if_author_dead = 11
+        assert len(date) == len_if_author_alive or len(date) == len_if_author_dead
+
+    def test_all_author_birth_and_death_year(self, browser):
+        url = self.host + '/OL5702375W/Three_cups_of_tea'
+        browser.visit(url)
+        title = browser.find_by_css(".edition-byline")[0].text
+        title_length = len(title)
+        author_dates = []
+        authors_quantity = title.count('(')
+        for i in range(0, authors_quantity):
+            if author_dates != []:
+                title = title[end_of_date + 1 : title_length]
+            begin_of_date = title.find('(')
+            if begin_of_date:
+                begin_of_date += 1
+            else:
+                break
+            end_of_date = title.find(')')
+            date = title[begin_of_date:end_of_date]
+            author_dates.append(date)
+        len_if_no_birth_data = 3
+        len_if_author_alive = 7
+        len_if_author_dead = 11
+        for date in author_dates:
+            assert (
+                len(date) == len_if_no_birth_data
+                or len(date) == len_if_author_alive
+                or len(date) == len_if_author_dead
+            )
+
+    def test_all_works_from_author(self, browser):
+        url = 'http://localhost:8080/authors/OL18319A/Mark_Twain'
+        browser.visit(url)
+        error = browser.find_by_css(".error")
+        if error:
+            raise Exception("Error in page")
+        titles = browser.find_by_css(".bookauthor")
+        for title_driver in titles:
+            title = title_driver.text
+            title_length = len(title)
+            author_dates = []
+            authors_quantity = title.count('(')
+            for i in range(0, authors_quantity):
+                if author_dates != []:
+                    title = title[end_of_date + 1 : title_length]
+                begin_of_date = title.find('(')
+                if begin_of_date:
+                    begin_of_date += 1
+                else:
+                    break
+                end_of_date = title.find(')')
+                date = title[begin_of_date:end_of_date]
+                author_dates.append(date)
+            len_if_no_birth_data = 3
+            len_if_author_alive = 7
+            len_if_author_dead = 11
+            for date in author_dates:
+                assert (
+                    len(date) == len_if_no_birth_data
+                    or len(date) == len_if_author_alive
+                    or len(date) == len_if_author_dead
+                )