Repository: oduwsdl/MementoEmbed

Issue:
Exception while searching for favicon
MementoEmbed throws an exception for the following URI-M:
* http://wayback.archive-it.org/4887/20141104211213/http://time.com/3502740/ebola-virus-1976/

Here is the log entry:
```
[2018-09-06 14:07:36,093 -0600 ] - ERROR - [ /services/product/socialcard/http://wayback.archive-it.org/4887/20141104211213/http://time.com/3502740/ebola-virus-1976/ ]: mementoembed.services.errors - An unforeseen error has occurred
Traceback (most recent call last):
  File "/Volumes/nerfherder External/Unsynced-Projects/MementoEmbed/mementoembed/services/errors.py", line 27, in handle_errors
    return function_name(urim, preferences)
  File "/Volumes/nerfherder External/Unsynced-Projects/MementoEmbed/mementoembed/services/product.py", line 77, in generate_socialcard_response
    original_favicon_uri = s.original_favicon
  File "/Volumes/nerfherder External/Unsynced-Projects/MementoEmbed/mementoembed/mementosurrogate.py", line 71, in original_favicon
    return self.originalresource.favicon
  File "/Volumes/nerfherder External/Unsynced-Projects/MementoEmbed/mementoembed/originalresource.py", line 49, in favicon
    candidate_favicon = get_favicon_from_html(self.content)
  File "/Volumes/nerfherder External/Unsynced-Projects/MementoEmbed/mementoembed/favicon.py", line 55, in get_favicon_from_html
    if 'icon' in link['rel']:
  File "/Users/smj/.virtualenvs/MementoEmbed-gkunwTeo/lib/python3.7/site-packages/bs4/element.py", line 1071, in __getitem__
    return self.attrs[key]
KeyError: 'rel'
```

The problem is that the code assumes that all `link` tags in html have a `rel` attribute.

Discussion:

Patch:
diff --git a/docs/source/conf.py b/docs/source/conf.py
index c7c0614..9892732 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -26,7 +26,7 @@ author = 'Shawn M. Jones'
 # The short X.Y version
 version = ''
 # The full version, including alpha/beta/rc tags
-release = '0.2018.09.05.234815'
+release = '0.2018.09.06.202242'
 
 
 # -- General configuration ---------------------------------------------------
diff --git a/mementoembed/favicon.py b/mementoembed/favicon.py
index 60203f0..2d53036 100644
--- a/mementoembed/favicon.py
+++ b/mementoembed/favicon.py
@@ -52,18 +52,27 @@ def get_favicon_from_html(content):
 
     for link in links:
 
-        if 'icon' in link['rel']:
-            favicon_uri = link['href']
-            break
+        try:
+            if 'icon' in link['rel']:
+                favicon_uri = link['href']
+                break
+        except KeyError:
+            module_logger.exception("there was no 'rel' attribute in this link tag: {}".format(link))
+            favicon_uri == None
 
     # if that fails, try the older, nonstandard relation 'shortcut'
     if favicon_uri == None:
 
         for link in links:
 
-            if 'shortcut' in link['rel']:
-                favicon_uri = link['href']
-                break
+            try:
+                if 'shortcut' in link['rel']:
+                    favicon_uri = link['href']
+                    break
+            except KeyError:
+                module_logger.exception("there was no 'rel' attribute in this link tag: {}".format(link))
+                favicon_uri == None
+
 
     return favicon_uri
 
diff --git a/mementoembed/version.py b/mementoembed/version.py
index 72f9069..d1f031b 100644
--- a/mementoembed/version.py
+++ b/mementoembed/version.py
@@ -1,3 +1,3 @@
 __appname__ = "MementoEmbed"
-__appversion__ = '0.2018.09.05.234815'
+__appversion__ = '0.2018.09.06.202242'
 __useragent__ = "{}/{}".format(__appname__, __appversion__)


Test patch:
diff --git a/tests/test_archiveresource.py b/tests/test_archiveresource.py
index 0be51a5..8c33160 100644
--- a/tests/test_archiveresource.py
+++ b/tests/test_archiveresource.py
@@ -279,3 +279,52 @@ class TestArchiveResource(unittest.TestCase):
         x = ArchiveResource(urim, httpcache)
 
         self.assertEqual(x.favicon, expected_favicon)
+
+    def test_link_tag_no_rel(self):
+
+        expected_favicon = None
+
+        cachedict = {
+            "http://myarchive.org":
+                mock_response(
+                    headers={},
+                    content="""<html>
+                    <head>
+                        <title>Is this a good title?</title>
+                        <link title="a good title" href="content/favicon.ico">
+                    </head>
+                    <body>Is this all there is to content?</body>
+                    </html>""",
+                    status=200,
+                    url = "testing-url://notused"
+                ),
+            expected_favicon:
+                mock_response(
+                    headers = { 'content-type': 'image/x-testing'},
+                    content = "a",
+                    status=200,
+                    url = "testing-url://notused"
+                ),
+            "http://myarchive.org/favicon.ico":
+                mock_response(
+                    headers={},
+                    content="not found",
+                    status=404,
+                    url="testing-url://notused"
+                ),
+            "https://www.google.com/s2/favicons?domain=myarchive.org":
+                mock_response(
+                    headers={},
+                    content="not found",
+                    status=404,
+                    url="testing-url://notused"
+                )
+        }
+
+        httpcache = mock_httpcache(cachedict)
+
+        urim = "http://myarchive.org/20160518000858/http://example.com/somecontent"
+
+        x = ArchiveResource(urim, httpcache)
+
+        self.assertEqual(x.favicon, expected_favicon)