Commits

David Wolever  committed 577cbca

Adding a pop function.

  • Participants
  • Parent commits 5042886

Comments (0)

Files changed (6)

File queue/models.py

 
     @classmethod
     def next_in(cls, queue_name):
-        """ Get the next URL for a particular queue. """
-        return cls.objects_in_queue(queue_name)[0]
+        """ Get the next URL for a particular queue, or None if the
+            queue is empty. """
+        url = cls.objects_in_queue(queue_name)[:1]
+        if len(url) > 0:
+            return url[0]
+        return None
 
     @classmethod
     def objects_in_queue(cls, queue_name):

File queue/templates/queue/queue_empty.html

+Sorry, the queue <tt>{{ queue_name}}</tt> is empty.

File queue/tests.py

-from django.test import TestCase
+from django.test import TestCase, Client
 
 from nose.tools import assert_equal
 from datetime import datetime
 
 from models import QueuedUrl
 
+def new_queued_url(queue_name="default", url="http://url/",
+                   title="", enqueued=100, dequeued=None):
+    u = QueuedUrl()
+    u.queue_name = queue_name
+    u.url = url
+    u.title = title
+    u.enqueued = enqueued and datetime.fromtimestamp(enqueued)
+    u.dequeued = dequeued and datetime.fromtimestamp(dequeued)
+    u.save()
+    return u
+
+def setup_default_data():
+    new_queued_url(enqueued=100, dequeued=100, title="not shown 0")
+    new_queued_url(enqueued=110, title="first", url="http://first")
+    new_queued_url(enqueued=120, title="second", url="http://second")
+    new_queued_url(enqueued=130, dequeued=130, title="not shown 1")
+
 class TestQueuedUrl(TestCase):
 
-    def new_queued_url(self, queue_name="default", url="http://url/",
-                       title="", enqueued=100, dequeued=None):
-        u = QueuedUrl()
-        u.queue_name = queue_name
-        u.url = url
-        u.title = title
-        u.enqueued = enqueued and datetime.fromtimestamp(enqueued)
-        u.dequeued = dequeued and datetime.fromtimestamp(dequeued)
-        u.save()
-        return u
-
-    def setup_default_data(self):
-        self.new_queued_url(enqueued=100, dequeued=100, title="not shown 0")
-        self.new_queued_url(enqueued=110, title="first")
-        self.new_queued_url(enqueued=120, title="second")
-        self.new_queued_url(enqueued=130, dequeued=130, title="not shown 1")
-
     def test_in_queue(self):
-        self.setup_default_data()
+        setup_default_data()
 
         urls = QueuedUrl.objects_in_queue("default").all()
 
         assert_equal(urls[1].title, "second")
 
     def test_next_in_and_dequeue(self):
-        self.setup_default_data()
+        setup_default_data()
 
         url = QueuedUrl.next_in("default")
         assert_equal(url.title, "first")
 
         url = QueuedUrl.next_in("default")
         assert_equal(url.title, "second")
+
+    def test_in_queue_empty_queue(self):
+        url = QueuedUrl.next_in("empty_queue")
+        assert_equal(url, None)
+
+
+class TestViews(TestCase):
+    
+    def test_pop_with_get(self):
+        c = Client()
+        resp = c.get('/queue/some_queue/pop')
+        assert_equal(resp.status_code, 405)
+
+    def test_pop_empty(self):
+        c = Client()
+        resp = c.post('/queue/empty_queue/pop')
+        self.assertTemplateUsed(resp, 'queue/queue_empty.html')
+
+    def test_pop_full(self):
+        setup_default_data()
+        c = Client()
+
+        # Redirects should be a 302, temporary
+        resp = c.post('/queue/default/pop')
+        assert_equal(resp.status_code, 302)
+        assert_equal(resp['Location'], 'http://first')
+
+        resp = c.post('/queue/default/pop')
+        assert_equal(resp.status_code, 302)
+        assert_equal(resp['Location'], 'http://second')

File queue/urls.py

 from django.conf.urls.defaults import *
 
-from views import show_queue
+from views import show_queue, pop_queue
 
 matchers = {
     'queue_name': '[^/]+',
 
 urlpatterns = patterns('',
     url(r'^(%(queue_name)s)/$' % matchers, show_queue),
+    url(r'^(%(queue_name)s)/pop$' % matchers, pop_queue),
 )

File queue/views.py

-from django.shortcuts import render_to_response
+from django.shortcuts import render_to_response, redirect
+from django.http import HttpResponseNotAllowed
+
+from functools import partial
 
 from models import QueuedUrl
 
+def assert_method(expected_method):
+    def assert_method_helper(decorated, request, *args, **kwargs):
+        if request.method != expected_method:
+            return HttpResponseNotAllowed('%r expected, %r got' %
+                                          ( expected_method,
+                                            request.method ))
+        return decorated(request, *args, **kwargs)
+
+    def decorate(function):
+        return partial(assert_method_helper, function)
+    return decorate
+
+@assert_method("GET")
 def show_queue(request, queue_name):
     data = {
         'urls': QueuedUrl.objects_in_queue(queue_name),
     }
 
     return render_to_response('queue/show_queue.html', data)
+
+@assert_method("POST")
+def pop_queue(request, queue_name):
+    next_url = QueuedUrl.next_in(queue_name)
+
+    if next_url is None:
+        data = { 'queue_name': queue_name }
+        return render_to_response('queue/queue_empty.html', data)
+
+    next_url.dequeue()
+    next_url.save()
+
+    return redirect(next_url.url)

File templates/404.html

+Sorry, not found :(