Browse Source

Get basic working bookmarklet and refactor API into core

tags/v1.0.0
Isaac Bythewood 11 years ago
parent
commit
fa7e8c3b83
13 changed files with 175 additions and 223 deletions
  1. +0
    -0
      pinry/api/__init__.py
  2. +0
    -0
      pinry/api/models.py
  3. +0
    -126
      pinry/api/tests.py
  4. +0
    -17
      pinry/api/urls.py
  5. +0
    -0
      pinry/core/api.py
  6. +110
    -67
      pinry/core/tests.py
  7. +20
    -2
      pinry/core/urls.py
  8. +4
    -2
      pinry/pins/urls.py
  9. +0
    -1
      pinry/settings/__init__.py
  10. +21
    -7
      pinry/static/js/bookmarklet.js
  11. +13
    -0
      pinry/static/js/pin-form.js
  12. +7
    -0
      pinry/templates/core/pin_form.html
  13. +0
    -1
      pinry/urls.py

+ 0
- 0
pinry/api/__init__.py View File


+ 0
- 0
pinry/api/models.py View File


+ 0
- 126
pinry/api/tests.py View File

@@ -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'],
})

+ 0
- 17
pinry/api/urls.py View File

@@ -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)),
)

pinry/api/api.py → pinry/core/api.py View File


+ 110
- 67
pinry/core/tests.py View File

@@ -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

class HomeTest(unittest.TestCase):
def setUp(self):
self.client = Client()
self.url = reverse('core:home')
from ..pins.models import User, Pin, Image

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)
def filter_generator_for(size):
def wrapped_func(obj):
return Thumbnail.objects.get_or_create_at_size(obj.pk, size)
return wrapped_func


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 ImageResourceTest(ResourceTestCase):
fixtures = ['test_resources.json']
pass


class LoginTest(unittest.TestCase):
def setUp(self):
super(ImageResourceTest, self).setUp()
self.client = Client()
self.url = reverse('core:login')

def test_url(self):
self.assertEqual(self.url, '/login/')
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_status_code(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)

class PinResourceTest(ResourceTestCase):
fixtures = ['test_resources.json']

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_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'
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)

+ 20
- 2
pinry/core/urls.py View File

@@ -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'),
)

+ 4
- 2
pinry/pins/urls.py View File

@@ -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<tag>(\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'),
)

+ 0
- 1
pinry/settings/__init__.py View File

@@ -86,7 +86,6 @@ INSTALLED_APPS = (
'django_images',
'pinry.core',
'pinry.pins',
'pinry.api',
)

IMAGE_SIZES = {


+ 21
- 7
pinry/static/js/bookmarklet.js View File

@@ -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;


+ 13
- 0
pinry/static/js/pin-form.js View File

@@ -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();
});


+ 7
- 0
pinry/templates/core/pin_form.html View File

@@ -0,0 +1,7 @@
{% extends "base.html" %}

{% block title %}Pin Form{% endblock %}

{% block yield %}
<div id="display-pin-form"></div>
{% endblock %}

+ 0
- 1
pinry/urls.py View File

@@ -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)

Loading…
Cancel
Save