Repository: carpentries/amy

Issue:
"Import from URL" does not seem to set country
Imported two workshops this morning via their URLs (which were http://huguesfontenelle.github.io/2015-12-02-Oslo/ and http://karinlag.github.io/2015-11-20-NVI/). In both cases we got address and lat/long, but _not_ country (which should be "Norway").



Discussion:
It does work in `develop`, but there's a bug with converting `None` to `int` in `parse_tags_from_event_website` (`TypeError` is not caught).

Additionally with fallback to the old method of getting tags, a slug should be calculated from event's URL. That's a TODO.


Resolving patch:
diff --git a/workshops/util.py b/workshops/util.py
--- a/workshops/util.py
+++ b/workshops/util.py
@@ -373,7 +373,7 @@ def generate_url_to_event_index(website_url):
     results = regex.match(website_url)
     if results:
         return template.format(**results.groupdict())
-    return None
+    raise ValueError('URL does not match Event.WEBSITE_REGEX.')
 
 ALLOWED_TAG_NAMES = [
     'slug', 'startdate', 'enddate', 'country', 'venue', 'address',
@@ -431,18 +431,24 @@ def parse_tags_from_event_website(tags):
     try:
         latitude, _ = tags.get('latlng', '').split(',')
         latitude = float(latitude.strip())
-    except ValueError:
+    except (ValueError, AttributeError):
+        # value error: can't convert string to float
+        # attribute error: object doesn't have "split" or "strip" methods
         latitude = None
     try:
         _, longitude = tags.get('latlng', '').split(',')
         longitude = float(longitude.strip())
-    except ValueError:
+    except (ValueError, AttributeError):
+        # value error: can't convert string to float
+        # attribute error: object doesn't have "split" or "strip" methods
         longitude = None
 
     try:
         reg_key = tags.get('eventbrite', '')
         reg_key = int(reg_key)
-    except ValueError:
+    except (ValueError, TypeError):
+        # value error: can't convert string to int
+        # type error: can't convert None to int
         reg_key = None
 
     try:
diff --git a/workshops/views.py b/workshops/views.py
--- a/workshops/views.py
+++ b/workshops/views.py
@@ -4,6 +4,7 @@
 import io
 import re
 import requests
+from urllib.parse import urlparse
 
 from django.contrib import messages
 from django.contrib.messages.views import SuccessMessageMixin
@@ -1061,16 +1062,27 @@ def event_import(request):
 
         if 'slug' not in tags:
             # there are no HTML tags, so let's try the old method
-            url = generate_url_to_event_index(url)
+            index_url = generate_url_to_event_index(url)
 
             # fetch page
-            response = requests.get(url)
+            response = requests.get(index_url)
 
             if response.status_code == 200:
                 # don't throw errors for pages we fall back to
                 content = response.text
                 tags = find_tags_on_event_index(content)
 
+                if 'slug' not in tags:
+                    # `url` should match WEBSITE_REGEX because of the check
+                    # performed in `generate_url_to_event_website`,
+                    # but, just in case someone removes that code, let's
+                    # throw ValueError here too
+                    try:
+                        tags['slug'] = Event.WEBSITE_REGEX.match(url) \
+                                                          .group('repo')
+                    except AttributeError:
+                        raise ValueError()
+
         # normalize (parse) them
         tags = parse_tags_from_event_website(tags)
 
@@ -1086,6 +1098,11 @@ def event_import(request):
             requests.exceptions.Timeout):
         raise SuspiciousOperation('Network connection error.')
 
+    except ValueError:
+        # probably matching url with Event.WEBSITE_REGEX (either here or in
+        # `generate_url_to_event_index`) failed
+        raise SuspiciousOperation('Event\'s url is in wrong format.')
+
     except KeyError:
         raise SuspiciousOperation('Missing or wrong "url" POST parameter.')
 


Test patch:
diff --git a/workshops/test/test_util.py b/workshops/test/test_util.py
--- a/workshops/test/test_util.py
+++ b/workshops/test/test_util.py
@@ -616,6 +616,7 @@ def test_parsing_tricky_latitude_longitude(self):
             ('XYZ, ', (None, None)),
             (',-123', (None, -123.0)),
             (',', (None, None)),
+            (None, (None, None)),
         ]
         expected = {
             'slug': '',
@@ -639,6 +640,33 @@ def test_parsing_tricky_latitude_longitude(self):
                 expected['longitude'] = longitude
                 self.assertEqual(expected, parse_tags_from_event_website(tags))
 
+    def test_parsing_tricky_eventbrite_id(self):
+        tests = [
+            ('', None),
+            ('string', None),
+            (None, None),
+        ]
+        expected = {
+            'slug': '',
+            'language': '',
+            'start': None,
+            'end': None,
+            'country': '',
+            'venue': '',
+            'address': '',
+            'latitude': None,
+            'longitude': None,
+            'reg_key': None,
+            'instructors': [],
+            'helpers': [],
+            'contact': '',
+        }
+        for eventbrite_id, reg_key in tests:
+            with self.subTest(eventbrite_id=eventbrite_id):
+                tags = dict(eventbrite=eventbrite_id)
+                expected['reg_key'] = reg_key
+                self.assertEqual(expected, parse_tags_from_event_website(tags))
+
     def test_validating_invalid_tags(self):
         tags = {
             'slug': 'WRONG FORMAT',