Repository: carpentries/amy

Issue:
URL normalization bug (?)
The Event page displays a website URL and a repository URL. Normally, it seems that when the repository URL is edited, the website URL is automatically updated - more specifically, if the repository URL is `https://github.com/site/yyyy-mm-dd-site`, the website URL becomes `http://site.github.io/yyyy-mm-dd-site`. However, this is not happening with https://amy.software-carpentry.org/workshops/event/2015-08-26-uw-madison (as of 2015-08-18).



Discussion:

Resolving patch:
diff --git a/workshops/models.py b/workshops/models.py
--- a/workshops/models.py
+++ b/workshops/models.py
@@ -317,6 +317,13 @@ class Event(models.Model):
     latitude = models.FloatField(null=True, blank=True)
     longitude = models.FloatField(null=True, blank=True)
 
+    REPO_REGEX = re.compile(r'https?://github\.com/(?P<name>[^/]+)/'
+                            r'(?P<repo>[^/]+)/?')
+    REPO_FORMAT = 'https://github.com/{name}/{repo}'
+    WEBSITE_REGEX = re.compile(r'https?://(?P<name>[^.]+)\.github\.'
+                               r'(io|com)/(?P<repo>[^/]+)/?')
+    WEBSITE_FORMAT = 'https://{name}.github.io/{repo}'
+
     class Meta:
         ordering = ('-start', )
 
@@ -329,6 +336,38 @@ def __str__(self):
     def get_absolute_url(self):
         return reverse('event_details', args=[self.get_ident()])
 
+    def get_repository_url(self):
+        """Return self.url formatted as it was repository URL.
+
+        Repository URL is as specified in REPO_FORMAT.
+        If it doesn't match, the original URL is returned."""
+        try:
+            mo = self.WEBSITE_REGEX.match(self.url)
+            if not mo:
+                return self.url
+
+            return self.REPO_FORMAT.format(**mo.groupdict())
+        except (TypeError, KeyError):
+            # TypeError: self.url is None
+            # KeyError: mo.groupdict doesn't supply required names to format
+            return self.url
+
+    def get_website_url(self):
+        """Return self.url formatted as it was website URL.
+
+        Website URL is as specified in WEBSITE_FORMAT.
+        If it doesn't match, the original URL is returned."""
+        try:
+            mo = self.REPO_REGEX.match(self.url)
+            if not mo:
+                return self.url
+
+            return self.WEBSITE_FORMAT.format(**mo.groupdict())
+        except (TypeError, KeyError):
+            # TypeError: self.url is None
+            # KeyError: mo.groupdict doesn't supply required names to format
+            return self.url
+
     def get_ident(self):
         if self.slug:
             return str(self.slug)
diff --git a/workshops/templatetags/links.py b/workshops/templatetags/links.py
deleted file mode 100644
--- a/workshops/templatetags/links.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import re
-
-from django import template
-
-register = template.Library()
-
-REPO_REGEXP = re.compile(r'https://github\.com/(?P<name>\w+)/(?P<repo>\S+)/?')
-REPO_SCHEMA = 'https://github.com/{name}/{repo}/'
-WEBSITE_REGEXP = re.compile(
-    r'http://(?P<name>\w+)\.github\.(io|com)/(?P<repo>\S+)/?'
-)
-WEBSITE_SCHEMA = 'http://{name}.github.io/{repo}/'
-
-
-@register.assignment_tag
-def format_link_to_repository(link):
-    """
-    Use: {% format_link_to_repository event.url as repo_link %}
-    Then: {{ repo_link|urlize|default_if_none:"—" }}
-    """
-    if not link:
-        return link
-    elif REPO_REGEXP.match(link):
-        return link
-    else:
-        try:
-            repository = WEBSITE_REGEXP.findall(link)[0]
-            return REPO_SCHEMA.format(name=repository[0], repo=repository[-1])
-        except IndexError:
-            return link
-
-
-@register.assignment_tag
-def format_link_to_website(link):
-    """
-    Use: {% format_link_to_website event.url as website_link %}
-    Then: {{ website_link|urlize|default_if_none:"—" }}
-    """
-    if not link:
-        return link
-    elif WEBSITE_REGEXP.match(link):
-        return link
-    else:
-        try:
-            site = REPO_REGEXP.findall(link)[0]
-            return WEBSITE_SCHEMA.format(name=site[0], repo=site[-1])
-        except IndexError:
-            return link
diff --git a/workshops/views.py b/workshops/views.py
--- a/workshops/views.py
+++ b/workshops/views.py
@@ -718,7 +718,7 @@ def validate_event(request, event_ident):
     event = Event.get_by_ident(event_ident)
     github_url = request.GET.get('url', None)  # for manual override
     if github_url is None:
-        github_url = event.url
+        github_url = event.get_repository_url()
 
     try:
         page_url, _ = normalize_event_index_url(github_url)


Test patch:
diff --git a/workshops/test/test_event.py b/workshops/test/test_event.py
--- a/workshops/test/test_event.py
+++ b/workshops/test/test_event.py
@@ -158,6 +158,55 @@ def test_delete_event_with_tasks_and_awards(self):
         Task.objects.get(pk=task.pk)
         Award.objects.get(pk=award.pk)
 
+    def test_repository_url(self):
+        test_host = Host.objects.all()[0]
+        links = [
+            'http://user-name.github.com/repo-name',
+            'http://user-name.github.io/repo-name',
+            'https://user-name.github.com/repo-name',
+            'https://user-name.github.io/repo-name',
+            'http://user-name.github.com/repo-name/',
+            'http://user-name.github.io/repo-name/',
+            'https://user-name.github.com/repo-name/',
+            'https://user-name.github.io/repo-name/',
+        ]
+        REPO = 'https://github.com/user-name/repo-name'
+        for index, link in enumerate(links):
+            event = Event.objects.create(
+                slug='e{}'.format(index),
+                host=test_host,
+                url=link
+            )
+            assert event.get_repository_url() == REPO
+
+    def test_website_url(self):
+        test_host = Host.objects.all()[0]
+        links = [
+            'http://github.com/user-name/repo-name',
+            'http://github.com/user-name/repo-name/',
+            'https://github.com/user-name/repo-name',
+            'https://github.com/user-name/repo-name/',
+        ]
+        WEBSITE = 'https://user-name.github.io/repo-name'
+        for index, link in enumerate(links):
+            event = Event.objects.create(
+                slug='e{}'.format(index),
+                host=test_host,
+                url=link
+            )
+            assert event.get_website_url() == WEBSITE
+
+    def test_wrong_repository_website_urls(self):
+        test_host = Host.objects.all()[0]
+        link = 'http://en.wikipedia.org/'
+        event = Event.objects.create(
+            slug='test-event',
+            host=test_host,
+            url=link
+        )
+        assert event.get_repository_url() == link
+        assert event.get_website_url() == link
+
 
 class TestEventViews(TestBase):
     "Tests for the event views"