From fa7e8c3b83a7aee71175fdbb2ea7379190be5612 Mon Sep 17 00:00:00 2001 From: Isaac Bythewood Date: Tue, 26 Feb 2013 23:20:50 +0000 Subject: [PATCH] Get basic working bookmarklet and refactor API into core --- pinry/api/__init__.py | 0 pinry/api/models.py | 0 pinry/api/tests.py | 126 ------------------- pinry/api/urls.py | 17 --- pinry/{api => core}/api.py | 0 pinry/core/tests.py | 189 ++++++++++++++++++----------- pinry/core/urls.py | 22 +++- pinry/pins/urls.py | 6 +- pinry/settings/__init__.py | 1 - pinry/static/js/bookmarklet.js | 28 +++-- pinry/static/js/pin-form.js | 13 ++ pinry/templates/core/pin_form.html | 7 ++ pinry/urls.py | 1 - 13 files changed, 181 insertions(+), 229 deletions(-) delete mode 100644 pinry/api/__init__.py delete mode 100644 pinry/api/models.py delete mode 100644 pinry/api/tests.py delete mode 100644 pinry/api/urls.py rename pinry/{api => core}/api.py (100%) create mode 100644 pinry/templates/core/pin_form.html diff --git a/pinry/api/__init__.py b/pinry/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pinry/api/models.py b/pinry/api/models.py deleted file mode 100644 index e69de29..0000000 diff --git a/pinry/api/tests.py b/pinry/api/tests.py deleted file mode 100644 index 89a5638..0000000 --- a/pinry/api/tests.py +++ /dev/null @@ -1,126 +0,0 @@ -# pylint: disable-msg=R0904 -# pylint: disable-msg=E1103 - -from django.test.client import Client -from django_images.models import Thumbnail - -from taggit.models import Tag -from tastypie.test import ResourceTestCase - -from ..pins.models import User, Pin, Image - - -def filter_generator_for(size): - def wrapped_func(obj): - return Thumbnail.objects.get_or_create_at_size(obj.pk, size) - return wrapped_func - - -class ImageResourceTest(ResourceTestCase): - fixtures = ['test_resources.json'] - pass - - def setUp(self): - super(ImageResourceTest, self).setUp() - self.client = Client() - - def test_list_detail(self): - image = Image.objects.get(pk=1) - thumbnail = filter_generator_for('thumbnail')(image) - standard = filter_generator_for('standard')(image) - response = self.api_client.get('/api/v1/image/', format='json') - self.assertDictEqual(self.deserialize(response)['objects'][0], { - u'image': image.image.url, - u'height': image.height, - u'width': image.width, - u'standard': { - u'image': unicode(standard.image.url), - u'width': standard.width, - u'height': standard.height, - }, - u'thumbnail': { - u'image': unicode(thumbnail.image.url), - u'width': thumbnail.width, - u'height': thumbnail.height, - } - }) - - -class PinResourceTest(ResourceTestCase): - fixtures = ['test_resources.json'] - - def setUp(self): - super(PinResourceTest, self).setUp() - - self.pin_1 = Pin.objects.get(pk=1) - self.image_url = 'http://technicallyphilly.com/wp-content/uploads/2013/02/url1.jpeg' - - self.user = User.objects.get(pk=1) - self.api_client.client.login(username=self.user.username, password='password') - - def test_post_create_url(self): - post_data = { - 'submitter': '/api/v1/user/1/', - 'url': self.image_url, - 'description': 'That\'s an Apple!' - } - response = self.api_client.post('/api/v1/pin/', data=post_data) - self.assertHttpCreated(response) - self.assertEqual(Pin.objects.count(), 3) - self.assertEqual(Image.objects.count(), 3) - - def test_post_create_obj(self): - user = User.objects.get(pk=1) - image = Image.objects.get(pk=1) - post_data = { - 'submitter': '/api/v1/user/{}/'.format(user.pk), - 'image': '/api/v1/image/{}/'.format(image.pk), - 'description': 'That\'s something else (probably a CC logo)!', - 'tags': ['random', 'tags'], - } - response = self.api_client.post('/api/v1/pin/', data=post_data) - self.assertEqual(self.deserialize(response)['id'], 3) - self.assertHttpCreated(response) - # A number of Image objects should stay the same as we are using an existing image - self.assertEqual(Image.objects.count(), 2) - self.assertEqual(Pin.objects.count(), 3) - self.assertEquals(Tag.objects.count(), 4) - - def test_get_list_json_ordered(self): - pin = Pin.objects.latest('id') - response = self.api_client.get('/api/v1/pin/', format='json', data={'order_by': '-id'}) - self.assertValidJSONResponse(response) - self.assertEqual(self.deserialize(response)['objects'][0]['id'], pin.id) - - def test_get_list_json(self): - user = User.objects.get(pk=1) - image = Image.objects.get(pk=1) - standard = filter_generator_for('standard')(image) - thumbnail = filter_generator_for('thumbnail')(image) - response = self.api_client.get('/api/v1/pin/', format='json') - self.assertValidJSONResponse(response) - self.assertDictEqual(self.deserialize(response)['objects'][0], { - u'id': self.pin_1.id, - u'submitter': { - u'username': user.username, - u'gravatar': user.gravatar - }, - u'image': { - u'image': unicode(image.image.url), - u'width': image.width, - u'height': image.height, - u'standard': { - u'image': unicode(standard.image.url), - u'width': standard.width, - u'height': standard.height, - }, - u'thumbnail': { - u'image': unicode(thumbnail.image.url), - u'width': thumbnail.width, - u'height': thumbnail.height, - } - }, - u'url': self.pin_1.url, - u'description': self.pin_1.description, - u'tags': [u'creative-commons'], - }) diff --git a/pinry/api/urls.py b/pinry/api/urls.py deleted file mode 100644 index 39d4bd9..0000000 --- a/pinry/api/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.conf.urls import patterns, include, url - -from tastypie.api import Api - -from .api import ImageResource, ThumbnailResource, PinResource, UserResource - - -v1_api = Api(api_name='v1') -v1_api.register(ImageResource()) -v1_api.register(ThumbnailResource()) -v1_api.register(PinResource()) -v1_api.register(UserResource()) - - -urlpatterns = patterns('', - url(r'^api/', include(v1_api.urls)), -) diff --git a/pinry/api/api.py b/pinry/core/api.py similarity index 100% rename from pinry/api/api.py rename to pinry/core/api.py diff --git a/pinry/core/tests.py b/pinry/core/tests.py index 5c63580..89a5638 100644 --- a/pinry/core/tests.py +++ b/pinry/core/tests.py @@ -1,83 +1,126 @@ -from django.utils import unittest +# pylint: disable-msg=R0904 +# pylint: disable-msg=E1103 + from django.test.client import Client -from django.core.urlresolvers import reverse +from django_images.models import Thumbnail + +from taggit.models import Tag +from tastypie.test import ResourceTestCase + +from ..pins.models import User, Pin, Image -class HomeTest(unittest.TestCase): +def filter_generator_for(size): + def wrapped_func(obj): + return Thumbnail.objects.get_or_create_at_size(obj.pk, size) + return wrapped_func + + +class ImageResourceTest(ResourceTestCase): + fixtures = ['test_resources.json'] + pass + def setUp(self): + super(ImageResourceTest, self).setUp() self.client = Client() - self.url = reverse('core:home') - def test_url(self): - self.assertEqual(self.url, '/') - - def test_status_code(self): - response = self.client.get(self.url) - self.assertEqual(response.status_code, 302) - - -class RegisterTest(unittest.TestCase): - def setUp(self): - self.client = Client() - self.url = reverse('core:register') - - def test_url(self): - self.assertEqual(self.url, '/register/') - - def test_status_code(self): - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - - @unittest.expectedFailure - def test_successful_registration(self): - # If 302 was success, if 200 same page registration failed. - response = self.client.post(self.url, { - 'username': 'test_registration_success', - 'password1': 'test_password', - 'password2': 'test_password', - }) - self.assertEqual(response.status_code, 302) - - def test_failed_registration(self): - # If 302 was success, if 200 same page registration failed. - response = self.client.post(self.url, { - 'username': 'test_registration_failed', - 'password1': 'test_password', - 'password2': 'test_wrong_password', - }) - self.assertEqual(response.status_code, 200) - - -class LoginTest(unittest.TestCase): - def setUp(self): - self.client = Client() - self.url = reverse('core:login') - - def test_url(self): - self.assertEqual(self.url, '/login/') - - def test_status_code(self): - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - - -class LogoutTest(unittest.TestCase): - def setUp(self): - self.client = Client() - self.url = reverse('core:logout') - self.client.post(self.url, { - 'username': 'test_user_logout', - 'password1': 'test_password', - 'password2': 'test_password', + def test_list_detail(self): + image = Image.objects.get(pk=1) + thumbnail = filter_generator_for('thumbnail')(image) + standard = filter_generator_for('standard')(image) + response = self.api_client.get('/api/v1/image/', format='json') + self.assertDictEqual(self.deserialize(response)['objects'][0], { + u'image': image.image.url, + u'height': image.height, + u'width': image.width, + u'standard': { + u'image': unicode(standard.image.url), + u'width': standard.width, + u'height': standard.height, + }, + u'thumbnail': { + u'image': unicode(thumbnail.image.url), + u'width': thumbnail.width, + u'height': thumbnail.height, + } }) - def test_url(self): - self.assertEqual(self.url, '/logout/') - def test_logout_with_logged_in_user(self): - self.client.post(self.url, { - 'username': 'test_user_logout', - 'password': 'test_password' +class PinResourceTest(ResourceTestCase): + fixtures = ['test_resources.json'] + + def setUp(self): + super(PinResourceTest, self).setUp() + + self.pin_1 = Pin.objects.get(pk=1) + self.image_url = 'http://technicallyphilly.com/wp-content/uploads/2013/02/url1.jpeg' + + self.user = User.objects.get(pk=1) + self.api_client.client.login(username=self.user.username, password='password') + + def test_post_create_url(self): + post_data = { + 'submitter': '/api/v1/user/1/', + 'url': self.image_url, + 'description': 'That\'s an Apple!' + } + response = self.api_client.post('/api/v1/pin/', data=post_data) + self.assertHttpCreated(response) + self.assertEqual(Pin.objects.count(), 3) + self.assertEqual(Image.objects.count(), 3) + + def test_post_create_obj(self): + user = User.objects.get(pk=1) + image = Image.objects.get(pk=1) + post_data = { + 'submitter': '/api/v1/user/{}/'.format(user.pk), + 'image': '/api/v1/image/{}/'.format(image.pk), + 'description': 'That\'s something else (probably a CC logo)!', + 'tags': ['random', 'tags'], + } + response = self.api_client.post('/api/v1/pin/', data=post_data) + self.assertEqual(self.deserialize(response)['id'], 3) + self.assertHttpCreated(response) + # A number of Image objects should stay the same as we are using an existing image + self.assertEqual(Image.objects.count(), 2) + self.assertEqual(Pin.objects.count(), 3) + self.assertEquals(Tag.objects.count(), 4) + + def test_get_list_json_ordered(self): + pin = Pin.objects.latest('id') + response = self.api_client.get('/api/v1/pin/', format='json', data={'order_by': '-id'}) + self.assertValidJSONResponse(response) + self.assertEqual(self.deserialize(response)['objects'][0]['id'], pin.id) + + def test_get_list_json(self): + user = User.objects.get(pk=1) + image = Image.objects.get(pk=1) + standard = filter_generator_for('standard')(image) + thumbnail = filter_generator_for('thumbnail')(image) + response = self.api_client.get('/api/v1/pin/', format='json') + self.assertValidJSONResponse(response) + self.assertDictEqual(self.deserialize(response)['objects'][0], { + u'id': self.pin_1.id, + u'submitter': { + u'username': user.username, + u'gravatar': user.gravatar + }, + u'image': { + u'image': unicode(image.image.url), + u'width': image.width, + u'height': image.height, + u'standard': { + u'image': unicode(standard.image.url), + u'width': standard.width, + u'height': standard.height, + }, + u'thumbnail': { + u'image': unicode(thumbnail.image.url), + u'width': thumbnail.width, + u'height': thumbnail.height, + } + }, + u'url': self.pin_1.url, + u'description': self.pin_1.description, + u'tags': [u'creative-commons'], }) - response = self.client.get(self.url) - self.assertEqual(response.status_code, 302) diff --git a/pinry/core/urls.py b/pinry/core/urls.py index e9ed1aa..613bbc5 100644 --- a/pinry/core/urls.py +++ b/pinry/core/urls.py @@ -1,11 +1,29 @@ -from django.conf.urls import patterns, url +from django.conf.urls import patterns, include, url + +from tastypie.api import Api + +from .api import ImageResource, ThumbnailResource, PinResource, UserResource + + +v1_api = Api(api_name='v1') +v1_api.register(ImageResource()) +v1_api.register(ThumbnailResource()) +v1_api.register(PinResource()) +v1_api.register(UserResource()) urlpatterns = patterns('', +) + + +urlpatterns = patterns('', + url(r'^api/', include(v1_api.urls, namespace='api')), + url(r'^$', 'pinry.core.views.home', name='home'), + url(r'^private/$', 'pinry.core.views.private', name='private'), url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'user/login.html'}, name='login'), - url(r'^register/$', 'pinry.core.views.register', name='register'), url(r'^logout/$', 'pinry.core.views.logout_user', name='logout'), + url(r'^register/$', 'pinry.core.views.register', name='register'), ) diff --git a/pinry/pins/urls.py b/pinry/pins/urls.py index e548b39..a3e6c06 100644 --- a/pinry/pins/urls.py +++ b/pinry/pins/urls.py @@ -5,9 +5,11 @@ from .views import CreateImage urlpatterns = patterns('pinry.pins.views', + url(r'^pin-form/$', TemplateView.as_view(template_name='core/pin_form.html'), + name='pin-form'), url(r'^upload-pin/$', CreateImage.as_view(), name='new-pin'), - url(r'^$', TemplateView.as_view(template_name='core/pins.html'), - name='recent-pins'), url(r'^tag/(?P(\w|-)+)/$', TemplateView.as_view(template_name='core/pins.html'), name='tag-pins'), + url(r'^$', TemplateView.as_view(template_name='core/pins.html'), + name='recent-pins'), ) diff --git a/pinry/settings/__init__.py b/pinry/settings/__init__.py index c4b3ed8..c3e29f6 100644 --- a/pinry/settings/__init__.py +++ b/pinry/settings/__init__.py @@ -86,7 +86,6 @@ INSTALLED_APPS = ( 'django_images', 'pinry.core', 'pinry.pins', - 'pinry.api', ) IMAGE_SIZES = { diff --git a/pinry/static/js/bookmarklet.js b/pinry/static/js/bookmarklet.js index fadece9..b74232c 100644 --- a/pinry/static/js/bookmarklet.js +++ b/pinry/static/js/bookmarklet.js @@ -6,6 +6,21 @@ if (!jQuery) { } $(document).ready(function() { + var scriptUri; + + function curScriptUrl(callback) { + var scripts = document.getElementsByTagName("script"); + var scriptURI = scripts[scripts.length-1].src; + + if(scriptURI != "") { + callback(scriptURI); + } else if($ != undefined) { + $(document).ajaxSuccess(function(e, xhr, s) { + callback(s.url); + }); + } + } + function createPage() { var documentHeight = $(document).height(); @@ -37,14 +52,13 @@ $(document).ready(function() { 'cursor': 'pointer' }); wrapper.click(function() { - $.ajax({ - type: "post", - url: "http://nebula.bythewood.me/api/v1/pin/", - contentType: 'application/json', - data: JSON.stringify({ - url: imageUrl - }) + var apiUrl = 'http://'; + curScriptUrl(function(x) { + scriptUri = x; + apiUrl = apiUrl +scriptUri.split('/')[2]; }); + apiUrl = apiUrl + '/pins/pin-form/?pin-image-url='+imageUrl; + window.open(apiUrl, '1361920530821', 'width=579,height=475,toolbar=0,menubar=0,location=0,status=1,scrollbars=1,resizable=1,left=0,top=0'); $('.pinry-images').remove(); }); return wrapper; diff --git a/pinry/static/js/pin-form.js b/pinry/static/js/pin-form.js index 6e98a06..61f41d5 100644 --- a/pinry/static/js/pin-form.js +++ b/pinry/static/js/pin-form.js @@ -51,6 +51,17 @@ $(window).load(function() { $('#pin-form-tags').bind('propertychange keyup input paste', function() { createPreview(); }); + + function getURLParameter(name) { + return decodeURI( + (RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1] + ); + } + if (getURLParameter('pin-image-url') != 'null') { + $('#pin-form-image-url').val(getURLParameter('pin-image-url')); + createPreview(); + } + $('#pin-form-submit').click(function(e) { var tags = cleanTags(); $.ajax({ @@ -85,6 +96,8 @@ $(window).load(function() { }); } + if ($('#display-pin-form').length >= 1) createPinForm(); + $('#call-pin-form').click(function() { createPinForm(); }); diff --git a/pinry/templates/core/pin_form.html b/pinry/templates/core/pin_form.html new file mode 100644 index 0000000..b4af1e5 --- /dev/null +++ b/pinry/templates/core/pin_form.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block title %}Pin Form{% endblock %} + +{% block yield %} +
+{% endblock %} diff --git a/pinry/urls.py b/pinry/urls.py index 68fea12..26b644d 100644 --- a/pinry/urls.py +++ b/pinry/urls.py @@ -5,6 +5,5 @@ from django.conf import settings urlpatterns = patterns('', url(r'^pins/', include('pinry.pins.urls', namespace='pins')), - url(r'', include('pinry.api.urls')), url(r'', include('pinry.core.urls', namespace='core')), ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)