Skip to content

Commit

Permalink
A Django generic view that returns encrypted urls. Mostly used to get…
Browse files Browse the repository at this point in the history
… encrypted urls to be used by javascript
  • Loading branch information
rafaelcaricio committed Apr 14, 2011
1 parent 5c2f334 commit cd2a604
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@
.DS_Store
dist
libthumbor.egg-info
*.db
Empty file added libthumbor/django/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions libthumbor/django/urls.py
@@ -0,0 +1,5 @@
from django.conf.urls.defaults import *

urlpatterns = patterns('libthumbor.django.views',
url("^$", 'generate_url', name="generate_thumbor_url"),
)
42 changes: 42 additions & 0 deletions libthumbor/django/views.py
@@ -0,0 +1,42 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# libthumbor - python extension to thumbor
# http://github.com/heynemann/libthumbor

# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license
# Copyright (c) 2011 Bernardo Heynemann heynemann@gmail.com

'''Generic view for create thumbor encrypted urls.'''
import logging

from django.http import Http404, HttpResponse
from django.conf import settings

from libthumbor.crypto import CryptoURL

THUMBOR_SECURITY_KEY = getattr(settings, 'THUMBOR_SECURITY_KEY', 'my-security-key')

def generate_url(request):
crypto = CryptoURL(THUMBOR_SECURITY_KEY)
try:
args = request.GET if request.method == 'GET' else request.POST

# convert Django QueryDict to a python dict
args = dict(zip(map(str, args.keys()), args.values()))

if 'width' in args:
args['width'] = int(args['width'])

if 'height' in args:
args['height'] = int(args['height'])

if 'crop_top' in args or 'crop_left' in args or 'crop_right' in args or 'crop_bottom' in args:
args['crop'] = ((int(args['crop_left']), int(args['crop_top'])),
(int(args['crop_right']), int(args['crop_bottom'])))

return HttpResponse(crypto.generate(**args), mimetype="text/plain")
except (RuntimeError, ValueError, KeyError), e:
logging.warning(str(e))
raise Http404
104 changes: 104 additions & 0 deletions tests/test_generic_views.py
@@ -0,0 +1,104 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# libthumbor - python extension to thumbor
# http://github.com/heynemann/libthumbor

# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license
# Copyright (c) 2011 Bernardo Heynemann heynemann@gmail.com

'''libthumbor generic views tests'''
import os

from libthumbor.crypto import CryptoURL

os.environ["DJANGO_SETTINGS_MODULE"] = 'testproj.settings'

try:
from django.conf import settings
from django.test import TestCase
DJANGO_PRESENT = True
except ImportError:
DJANGO_PRESENT = False

if DJANGO_PRESENT:

class GenericViewsTestCase(TestCase):

def test_without_url_param(self):
response = self.client.get('/gen_url/')
assert 404 == response.status_code, "Got %d" % response.status_code

def test_generate_url_with_params_via_post(self):
image_args = {'image_url': 'globo.com/media/img/my_image.jpg'}
crypto = CryptoURL(settings.THUMBOR_SECURITY_KEY)

response = self.client.post('/gen_url/', image_args)

assert 200 == response.status_code, "Got %d" % response.status_code
assert response.content == crypto.generate(**image_args)

def test_generate_url_with_params_via_get(self):
image_args = {'image_url': 'globo.com/media/img/my_image.jpg'}
crypto = CryptoURL(settings.THUMBOR_SECURITY_KEY)

response = self.client.get('/gen_url/?image_url=' + image_args['image_url'])

assert 200 == response.status_code, "Got %d" % response.status_code
assert response.content == crypto.generate(**image_args)

def test_passing_invalid_aligns(self):
image_args = {'image_url': 'globo.com/media/img/my_image.jpg', 'halign': 'sss'}

response = self.client.post('/gen_url/', image_args)

assert 404 == response.status_code, "Got %d" % response.status_code

def test_passing_only_one_crop_value(self):
image_args = {
'image_url': 'globo.com/media/img/my_image.jpg',
'crop_left': 100,
}

response = self.client.post('/gen_url/', image_args)

assert 404 == response.status_code, "Got %d" % response.status_code

def test_passing_only_one_crop_with_invalid_value(self):
image_args = {
'image_url': 'globo.com/media/img/my_image.jpg',
'crop_top': 'bla',
}

response = self.client.post('/gen_url/', image_args)

assert 404 == response.status_code, "Got %d" % response.status_code

def test_passing_all_params(self):
image_args = {
'image_url': 'globo.com/media/img/my_image.jpg',
'halign': 'left',
'valign': 'middle',
'meta': True,
'smart': True,
'width': 400,
'height': 400,
'flip': True,
'flop': True
}
image_params = dict(image_args)
image_params.update({
'crop_top': 100,
'crop_left': 100,
'crop_bottom': 200,
'crop_right': 200
})
image_args['crop'] = ((100,100),(200,200))

crypto = CryptoURL(settings.THUMBOR_SECURITY_KEY)

response = self.client.post('/gen_url/', image_params)

assert 200 == response.status_code, "Got %d" % response.status_code
assert response.content == crypto.generate(**image_args)
Empty file added tests/testproj/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions tests/testproj/manage.py
@@ -0,0 +1,11 @@
#!/usr/bin/env python
from django.core.management import execute_manager
try:
import settings # Assumed to be in the same directory.
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
sys.exit(1)

if __name__ == "__main__":
execute_manager(settings)
86 changes: 86 additions & 0 deletions tests/testproj/settings.py
@@ -0,0 +1,86 @@
# Django settings for testproj project.
import logging

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
# ('Your Name', 'your_email@domain.com'),
)

MANAGERS = ADMINS

DATABASE_SUPPORTS_TRANSACTIONS = True

DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = 'test.db' # Or path to database file if using sqlite3.
DATABASE_USER = '' # Not used with sqlite3.
DATABASE_PASSWORD = '' # Not used with sqlite3.
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'America/Chicago'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'

# Make this unique, and don't share it with anybody.
SECRET_KEY = 'r2+#7pwvtvou#d_d6*ftt+pud^%s6vl-+2duag37x@xxy@$yu^'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
# 'django.template.loaders.eggs.load_template_source',
)

MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)

ROOT_URLCONF = 'testproj.urls'

TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
)

logging.basicConfig(level=logging.DEBUG)

THUMBOR_SECURITY_KEY = 'my-security-key'
5 changes: 5 additions & 0 deletions tests/testproj/urls.py
@@ -0,0 +1,5 @@
from django.conf.urls.defaults import *

urlpatterns = patterns('',
(r"^gen_url/", include('libthumbor.django.urls')),
)

0 comments on commit cd2a604

Please sign in to comment.