Commits

Chris Wesseling committed 5c4ad0c

Adds skipping of broken urls.

Serves a small error message when *all* urls in a show are broken.

  • Participants
  • Parent commits 137bfb0

Comments (0)

Files changed (4)

File narrowcaster/fixtures/broken.json

+[
+  {
+    "pk": 1, 
+    "model": "narrowcaster.url", 
+    "fields": {
+      "url": "http://www.example.com/", 
+      "title": "Forwarded to iana", 
+      "order": 0, 
+      "timeout": 2, 
+      "show": "default"
+    }
+  },
+  {
+    "pk": 2, 
+    "model": "narrowcaster.url", 
+    "fields": {
+      "url": "http://homepages.cwi.nl/~ccw/reallydoesnotexist.html", 
+      "title": "404", 
+      "order": 1, 
+      "timeout": 2, 
+      "show": "default"
+    }
+  },
+  {
+    "pk": 3, 
+    "model": "narrowcaster.url", 
+    "fields": {
+      "url": "http://homepages.cwi.nl/~ccw/reallydoesnotexist.html", 
+      "title": "404", 
+      "order": 1, 
+      "timeout": 2, 
+      "show": "fail"
+    }
+  },
+  {
+    "pk": 4, 
+    "model": "narrowcaster.url", 
+    "fields": {
+      "url": "http://homepages.cwi.nl/~ccw/reallydoesnotexist.html", 
+      "title": "404", 
+      "order": 1, 
+      "timeout": 2, 
+      "show": "fail"
+    }
+  }
+]

File narrowcaster/tests.py

-"""
-This file demonstrates two different styles of tests (one doctest and one
-unittest). These will both pass when you run "manage.py test".
-
-Replace these with more appropriate tests for your application.
-"""
-
 from django.test import TestCase
 
-class SimpleTest(TestCase):
-    def test_basic_addition(self):
-        """
-        Tests that 1 + 1 always equals 2.
-        """
-        self.failUnlessEqual(1 + 1, 2)
 
-__test__ = {"doctest": """
-Another way to test that 1 + 1 is equal to 2.
+class NarrowcasterTest(TestCase):
+    urls = 'narrowcaster.urls'
+    fixtures = ['broken.json']
 
->>> 1 + 1 == 2
-True
-"""}
+    def test_redirect(self):
+        "Test missing trailing slash"
+        response = self.client.get('/default')
+        self.assertEqual(response.status_code, 301)
+        self.assertEqual(response['Location'], 'http://testserver/default/')
 
+    def test_brokenurl(self):
+        "Test that broken urls are skipped."
+        response = self.client.get('/default/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response['Refresh'], '2; /default/2')
+        response = self.client.get('/default/2')
+        # This is a broken url, so next is not the first, but the second again.
+        self.assertEqual(response.status_code, 200)
+        self.assertNotEqual(response['Refresh'], '2; /default/1')
+        #self.assertEqual(response['Refresh'], '2; /default/2')
+
+    def test_unknownshow(self):
+        response = self.client.get('/noshow/')
+        self.assertEqual(response.status_code, 404)
+
+    def test_brokenshow(self):
+        response = self.client.get('/fail/')
+        self.assertEqual(response.status_code, 200)
+        self.assert_('Oops' in response.content)
+        self.assert_('fail' in response.content)
+        self.assertEqual(response['Refresh'], '2; /fail/4')

File narrowcaster/urls.py

 
 urlpatterns = patterns('',
     url(r'^$', views.show, name='show'),
-    url(r'^(?P<show>[^/]+)/(?P<id>\d+)$', views.show, name='show'),
+    url(r'^(?P<show>[^/]+)/(?P<id>\d+)?$', views.show, name='show'),
 )

File narrowcaster/views.py

 from models import URL
 from django.core.urlresolvers import reverse
-from django.http import HttpResponse
-from urllib2 import Request, urlopen
+from django.http import HttpResponse, Http404
+from urllib2 import Request, urlopen, HTTPError
 from lxml import html
 
+
+def make_request(url):
+    "Contruct a `urllib2.Request` for a `URL`."
+    r = Request(url=url.url)
+    r.add_header('User-Agent', 'django-narrowcaster')
+    return r
+
+
 def show(request, id=None, show='default'):
     if not id:
-        url = URL.objects.filter(show=show)[0]
+        try:
+            url = URL.objects.filter(show=show)[0]
+        except IndexError:
+            raise Http404
     else:
         url = URL.objects.get(pk=id)
 
-    r = Request(url=url.url)
-    r.add_header('User-Agent', 'django-narrowcaster')
+    response = HttpResponse()
+    doc = None
+    errors = []
+    while not doc:
+        r = make_request(url)
+        try:
+            doc = urlopen(r)
+        except HTTPError, e:
+            if url.id in errors:
+                response.write(u"""<html><head><title></head>
+                <body><p>Oops all pages in %s are unavailable!</p></body>
+                </html>""" % show)
+                break
+            errors.append(url.id)
+            url = url.next
+        else:
+            #fix the base href.
+            page = html.parse(doc).getroot()
+            page.head.insert(0, page.head.makeelement('base',
+                href=page.head.base_url))
+            response.write(html.tostring(page, method='xml'))
 
-    response = HttpResponse()
     #come back for next
     response['Refresh'] = '%i; %s' % (url.timeout,
             reverse('show', kwargs={'id': url.next.id, 'show': show}))
 
-    #fix the base href.
-    page = html.parse(urlopen(r)).getroot()
-    page.head.insert(0, page.head.makeelement('base', href=page.head.base_url))
-
-    response.write(html.tostring(page, method='xml'))
     return response