Merge branch 'master' of github.com:Gluejar/regluit
commit
f774d9d552
|
@ -0,0 +1,103 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.contrib import auth
|
||||||
|
from django.contrib.auth.models import User, AnonymousUser
|
||||||
|
from django.conf.urls.defaults import url
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from tastypie import fields
|
||||||
|
from tastypie.constants import ALL, ALL_WITH_RELATIONS
|
||||||
|
from tastypie.resources import ModelResource, Resource, Bundle
|
||||||
|
from tastypie.utils import trailing_slash
|
||||||
|
from tastypie.authentication import ApiKeyAuthentication
|
||||||
|
|
||||||
|
from regluit.core import models
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class UserResource(ModelResource):
|
||||||
|
class Meta:
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
queryset = User.objects.all()
|
||||||
|
resource_name = 'user'
|
||||||
|
fields = ['username', 'first_name', 'last_name']
|
||||||
|
|
||||||
|
class EditionResource(ModelResource):
|
||||||
|
class Meta:
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
queryset = models.Edition.objects.all()
|
||||||
|
resource_name = 'edition'
|
||||||
|
filtering = {
|
||||||
|
"isbn_10": ALL,
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkResource(ModelResource):
|
||||||
|
editions = fields.ToManyField(EditionResource, 'editions')
|
||||||
|
class Meta:
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
queryset = models.Work.objects.all()
|
||||||
|
resource_name = 'work'
|
||||||
|
filtering = {'editions': ALL_WITH_RELATIONS, 'id': ALL}
|
||||||
|
|
||||||
|
class CampaignResource(ModelResource):
|
||||||
|
work = fields.ToOneField(WorkResource, 'work')
|
||||||
|
|
||||||
|
def alter_list_data_to_serialize(self, request, data):
|
||||||
|
"""
|
||||||
|
annotate the list of campaigns with information from the logged in
|
||||||
|
user. note: this isn't the user identified by the api username/api_key
|
||||||
|
it's the the user that client might be logged into unglue.it as.
|
||||||
|
"""
|
||||||
|
u = auth.get_user(request)
|
||||||
|
if isinstance(u, User):
|
||||||
|
data['meta']['logged_in_username'] = u.username
|
||||||
|
wishlist_work_ids = [w.id for w in u.wishlist.works.all()]
|
||||||
|
else:
|
||||||
|
data['meta']['logged_in_username'] = None
|
||||||
|
wishlist_work_ids = []
|
||||||
|
|
||||||
|
for o in data['objects']:
|
||||||
|
o.data['in_wishlist'] = o.obj.id in wishlist_work_ids
|
||||||
|
|
||||||
|
# TODO: add pledging information
|
||||||
|
return data
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
queryset = models.Campaign.objects.all()
|
||||||
|
resource_name = 'campaign'
|
||||||
|
excludes = ['amazon_receiver', 'paypal_receiver']
|
||||||
|
filtering = {
|
||||||
|
"work": ALL_WITH_RELATIONS,
|
||||||
|
}
|
||||||
|
|
||||||
|
class AuthorResource(ModelResource):
|
||||||
|
works = fields.ToManyField(WorkResource, 'works')
|
||||||
|
class Meta:
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
queryset = models.Author.objects.all()
|
||||||
|
resource_name = 'author'
|
||||||
|
|
||||||
|
class SubjectResource(ModelResource):
|
||||||
|
works = fields.ToManyField(WorkResource, 'works')
|
||||||
|
class Meta:
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
queryset = models.Subject.objects.all()
|
||||||
|
resource_name = 'subject'
|
||||||
|
|
||||||
|
class EditionCoverResource(ModelResource):
|
||||||
|
edition = fields.ToManyField(EditionResource, 'editions')
|
||||||
|
class Meta:
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
queryset = models.EditionCover.objects.all()
|
||||||
|
resource_name = 'editioncover'
|
||||||
|
|
||||||
|
class WishlistResource(ModelResource):
|
||||||
|
user = fields.ToOneField(UserResource, 'user')
|
||||||
|
works = fields.ToManyField(WorkResource, 'works')
|
||||||
|
class Meta:
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
queryset = models.Wishlist.objects.all()
|
||||||
|
resource_name = 'wishlist'
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>editions</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!--- editions --->
|
||||||
|
|
||||||
|
{% if editions %}
|
||||||
|
<ul>
|
||||||
|
{% for edition in editions %}
|
||||||
|
<li> <img src="http://covers.openlibrary.org/b/isbn/{{edition.isbn_10}}-S.jpg" /> {{edition.id}} | {{edition.title}} |
|
||||||
|
<a href="{% url isbn isbn=edition.isbn_10 %}">{{edition.isbn_10}}</a> |
|
||||||
|
<a href="{% url isbn isbn=edition.isbn_13 %}">{{edition.isbn_13}}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>No editions are available.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>isbn</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<p>You entered isbn: {{isbn}}</p>
|
||||||
|
|
||||||
|
<!--- editions --->
|
||||||
|
|
||||||
|
{% if editions %}
|
||||||
|
<ul>
|
||||||
|
{% for edition in editions %}
|
||||||
|
<li>{{edition.id}} | {{edition.title}}
|
||||||
|
|
||||||
|
<a href="http://openlibrary.org/isbn/{{edition.isbn_10}}"><img src="http://covers.openlibrary.org/b/isbn/{{edition.isbn_10}}-M.jpg"/ width="120" height="182" ></a>
|
||||||
|
|
||||||
|
<!-- editioncovers for given edition -->
|
||||||
|
{% if edition.covers.all %}
|
||||||
|
<ul id="id">
|
||||||
|
{% for editioncover in edition.covers.all %}
|
||||||
|
<li>cover OL id: {{editioncover.openlibrary_id}}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p class="classname">No editioncover for this edition</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- related work -->
|
||||||
|
{% if edition.work %}
|
||||||
|
<p class="classname">Related work: {{edition.work.id}} | {{edition.work.title}} | first author: {{edition.work.authors.all.0.name}} <br/>
|
||||||
|
All authors: {{edition.work.authors.all}} </p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- related campaigns -->
|
||||||
|
{% if edition.work.campaigns.all %}
|
||||||
|
<ul id="id">
|
||||||
|
{% for campaign in edition.work.campaigns.all %}
|
||||||
|
<li>Campaign: id:{{campaign.id}} | name:{{campaign.name}} | desc:{{campaign.description}} <br/>
|
||||||
|
target:{{campaign.target}} created:{{campaign.created}} deadline:{{campaign.deadline}}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p class="classname">No associated campaigns</p>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>No editions are available.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
106
api/tests.py
106
api/tests.py
|
@ -1,23 +1,95 @@
|
||||||
"""
|
import json
|
||||||
This file demonstrates two different styles of tests (one doctest and one
|
import datetime
|
||||||
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
|
from django.test import TestCase
|
||||||
|
from django.test.client import Client
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
class SimpleTest(TestCase):
|
from regluit.core import bookloader, models
|
||||||
def test_basic_addition(self):
|
|
||||||
"""
|
|
||||||
Tests that 1 + 1 always equals 2.
|
|
||||||
"""
|
|
||||||
self.failUnlessEqual(1 + 1, 2)
|
|
||||||
|
|
||||||
__test__ = {"doctest": """
|
class ApiTests(TestCase):
|
||||||
Another way to test that 1 + 1 is equal to 2.
|
|
||||||
|
|
||||||
>>> 1 + 1 == 2
|
def setUp(self):
|
||||||
True
|
edition = bookloader.add_book(isbn='0441012035')
|
||||||
"""}
|
campaign = models.Campaign.objects.create(
|
||||||
|
name=edition.work.title,
|
||||||
|
work=edition.work,
|
||||||
|
description='Test Campaign',
|
||||||
|
deadline=datetime.datetime.now(),
|
||||||
|
target=1000.0,
|
||||||
|
)
|
||||||
|
self.user = User.objects.create_user('test', 'test@example.com', 'testpass')
|
||||||
|
self.client = Client()
|
||||||
|
|
||||||
|
def test_user(self):
|
||||||
|
self.assertEqual(User.objects.all().count(), 1)
|
||||||
|
self.assertTrue(User.objects.all()[0].api_key.key)
|
||||||
|
|
||||||
|
def test_no_auth(self):
|
||||||
|
r = self.client.get('/api/v1/campaign/', data={'format': 'json'})
|
||||||
|
self.assertEqual(r.status_code, 401)
|
||||||
|
|
||||||
|
def test_campaigns(self):
|
||||||
|
r = self.client.get('/api/v1/campaign/', data={
|
||||||
|
'format': 'json',
|
||||||
|
'username': self.user.username,
|
||||||
|
'api_key': self.user.api_key.key
|
||||||
|
})
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
j = json.loads(r.content)
|
||||||
|
self.assertEqual(len(j['objects']), 1)
|
||||||
|
self.assertEqual(j['objects'][0]['name'], 'Neuromancer')
|
||||||
|
self.assertEqual(j['objects'][0]['work'], '/api/v1/work/1/')
|
||||||
|
|
||||||
|
def test_campaign(self):
|
||||||
|
r = self.client.get('/api/v1/campaign/1/', data={
|
||||||
|
'format': 'json',
|
||||||
|
'username': self.user.username,
|
||||||
|
'api_key': self.user.api_key.key
|
||||||
|
})
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
j = json.loads(r.content)
|
||||||
|
self.assertEqual(j['name'], 'Neuromancer')
|
||||||
|
self.assertEqual(j['work'], '/api/v1/work/1/')
|
||||||
|
|
||||||
|
def test_campaign_lookup_by_isbn(self):
|
||||||
|
r = self.client.get('/api/v1/campaign/', data={
|
||||||
|
'format': 'json',
|
||||||
|
'work__editions__isbn_10': '0441012035',
|
||||||
|
'username': self.user.username,
|
||||||
|
'api_key': self.user.api_key.key
|
||||||
|
})
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
j = json.loads(r.content)
|
||||||
|
self.assertEqual(len(j['objects']), 1)
|
||||||
|
self.assertEqual(j['objects'][0]['name'], 'Neuromancer')
|
||||||
|
self.assertEqual(j['meta']['logged_in_username'], None)
|
||||||
|
self.assertEqual(j['objects'][0]['in_wishlist'], False)
|
||||||
|
|
||||||
|
def test_logged_in_user_info(self):
|
||||||
|
# login and see if adding a work to the users wishlist causes
|
||||||
|
# it to show up as in_wishlist in the campaign info
|
||||||
|
self.client.login(username='test', password='testpass')
|
||||||
|
|
||||||
|
r = self.client.get('/api/v1/campaign/', data={
|
||||||
|
'format': 'json',
|
||||||
|
'work__editions__isbn_10': '0441012035',
|
||||||
|
'username': self.user.username,
|
||||||
|
'api_key': self.user.api_key.key
|
||||||
|
})
|
||||||
|
j = json.loads(r.content)
|
||||||
|
self.assertEqual(j['meta']['logged_in_username'], 'test')
|
||||||
|
self.assertEqual(j['objects'][0]['in_wishlist'], False)
|
||||||
|
|
||||||
|
w = models.Work.objects.get(editions__isbn_10='0441012035')
|
||||||
|
self.user.wishlist.works.add(w)
|
||||||
|
r = self.client.get('/api/v1/campaign/', data={
|
||||||
|
'format': 'json',
|
||||||
|
'work__editions__isbn_10': '0441012035',
|
||||||
|
'username': self.user.username,
|
||||||
|
'api_key': self.user.api_key.key
|
||||||
|
})
|
||||||
|
j = json.loads(r.content)
|
||||||
|
self.assertEqual(j['meta']['logged_in_username'], 'test')
|
||||||
|
self.assertEqual(j['objects'][0]['in_wishlist'], True)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
from tastypie.api import Api
|
||||||
|
|
||||||
|
from regluit.api import resources
|
||||||
|
|
||||||
|
v1_api = Api(api_name='v1')
|
||||||
|
v1_api.register(resources.UserResource())
|
||||||
|
v1_api.register(resources.WorkResource())
|
||||||
|
v1_api.register(resources.EditionResource())
|
||||||
|
v1_api.register(resources.EditionCoverResource())
|
||||||
|
v1_api.register(resources.CampaignResource())
|
||||||
|
v1_api.register(resources.AuthorResource())
|
||||||
|
v1_api.register(resources.SubjectResource())
|
||||||
|
v1_api.register(resources.WishlistResource())
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
(r'^', include(v1_api.urls)),
|
||||||
|
)
|
22
api/views.py
22
api/views.py
|
@ -0,0 +1,22 @@
|
||||||
|
from django.template import RequestContext
|
||||||
|
from django.shortcuts import render_to_response, get_object_or_404
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from regluit.core import models
|
||||||
|
|
||||||
|
def isbn(request,isbn):
|
||||||
|
|
||||||
|
editions = models.Edition.objects.filter(Q(isbn_10 = isbn) | Q(isbn_13 = isbn))
|
||||||
|
# models.Campaign.objects.filter(work__editions__isbn_13='9780811216999')
|
||||||
|
|
||||||
|
return render_to_response('isbn.html',
|
||||||
|
{'isbn':isbn, 'editions':editions},
|
||||||
|
context_instance=RequestContext(request)
|
||||||
|
)
|
||||||
|
|
||||||
|
def editions(request):
|
||||||
|
editions = models.Edition.objects.all()
|
||||||
|
return render_to_response('editions.html',
|
||||||
|
{'editions':editions},
|
||||||
|
context_instance=RequestContext(request)
|
||||||
|
)
|
|
@ -0,0 +1,73 @@
|
||||||
|
# code modified from http://stackoverflow.com/questions/4734645/is-there-a-tool-to-check-database-integrity-in-django/4736176#4736176
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from django.core.management.base import NoArgsCommand
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
from django.db import models
|
||||||
|
from optparse import make_option
|
||||||
|
|
||||||
|
def model_name(model):
|
||||||
|
return '%s.%s' % (model._meta.app_label, model._meta.object_name)
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
args = '[-e|--exclude app_name.ModelName]'
|
||||||
|
help = 'Checks constraints in the database and reports violations on stdout'
|
||||||
|
|
||||||
|
option_list = NoArgsCommand.option_list + (
|
||||||
|
make_option('-e', '--exclude', action='append', type='string', dest='exclude'),
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
# TODO once we're on Django 1.2, write to self.stdout and self.stderr instead of plain print
|
||||||
|
|
||||||
|
exclude = options.get('exclude', None) or []
|
||||||
|
|
||||||
|
failed_instance_count = 0
|
||||||
|
failed_model_count = 0
|
||||||
|
for app in models.get_apps():
|
||||||
|
for model in models.get_models(app):
|
||||||
|
if model_name(model) in exclude:
|
||||||
|
print 'Skipping model %s' % model_name(model)
|
||||||
|
continue
|
||||||
|
fail_count = self.check_model(app, model)
|
||||||
|
if fail_count > 0:
|
||||||
|
failed_model_count += 1
|
||||||
|
failed_instance_count += fail_count
|
||||||
|
print 'Detected %d errors in %d models' % (failed_instance_count, failed_model_count)
|
||||||
|
|
||||||
|
def check_model(self, app, model):
|
||||||
|
meta = model._meta
|
||||||
|
if meta.proxy:
|
||||||
|
print 'WARNING: proxy models not currently supported; ignored'
|
||||||
|
return
|
||||||
|
|
||||||
|
# Define all the checks we can do; they return True if they are ok,
|
||||||
|
# False if not (and print a message to stdout)
|
||||||
|
def check_foreign_key(model, field):
|
||||||
|
foreign_model = field.related.parent_model
|
||||||
|
def check_instance(instance):
|
||||||
|
try:
|
||||||
|
# name: name of the attribute containing the model instance (e.g. 'user')
|
||||||
|
# attname: name of the attribute containing the id (e.g. 'user_id')
|
||||||
|
getattr(instance, field.name)
|
||||||
|
return True
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
print '%s with pk %s refers via field %s to nonexistent %s with pk %s' % \
|
||||||
|
(model_name(model), str(instance.pk), field.name, model_name(foreign_model), getattr(instance, field.attname))
|
||||||
|
return check_instance
|
||||||
|
|
||||||
|
# Make a list of checks to run on each model instance
|
||||||
|
checks = []
|
||||||
|
for field in meta.local_fields + meta.local_many_to_many + meta.virtual_fields:
|
||||||
|
if isinstance(field, models.ForeignKey):
|
||||||
|
checks.append(check_foreign_key(model, field))
|
||||||
|
|
||||||
|
# Run all checks
|
||||||
|
fail_count = 0
|
||||||
|
if checks:
|
||||||
|
for instance in model.objects.all():
|
||||||
|
print 'Checking model %s ...' % model_name(model)
|
||||||
|
for check in checks:
|
||||||
|
if not check(instance):
|
||||||
|
fail_count += 1
|
||||||
|
return fail_count
|
|
@ -0,0 +1,11 @@
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
from regluit.core import models
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "list all editions in the database"
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
editions = models.Edition.objects.all()
|
||||||
|
for edition in editions:
|
||||||
|
print edition.id, edition.title, edition.isbn_10, edition.isbn_13
|
|
@ -6,8 +6,8 @@ class Campaign(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
name = models.CharField(max_length=500, null=False)
|
name = models.CharField(max_length=500, null=False)
|
||||||
description = models.CharField(max_length=10000, null=False)
|
description = models.CharField(max_length=10000, null=False)
|
||||||
target = models.FloatField()
|
target = models.FloatField(null=False)
|
||||||
deadline = models.DateTimeField()
|
deadline = models.DateTimeField(null=False)
|
||||||
paypal_receiver = models.CharField(max_length=100, null=True)
|
paypal_receiver = models.CharField(max_length=100, null=True)
|
||||||
amazon_receiver = models.CharField(max_length=100, null=True)
|
amazon_receiver = models.CharField(max_length=100, null=True)
|
||||||
work = models.ForeignKey("Work", related_name="campaigns")
|
work = models.ForeignKey("Work", related_name="campaigns")
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.contrib.auth.models import User
|
||||||
|
|
||||||
from social_auth.signals import pre_update
|
from social_auth.signals import pre_update
|
||||||
from social_auth.backends.facebook import FacebookBackend
|
from social_auth.backends.facebook import FacebookBackend
|
||||||
|
from tastypie.models import create_api_key
|
||||||
|
|
||||||
|
|
||||||
def facebook_extra_values(sender, user, response, details, **kwargs):
|
def facebook_extra_values(sender, user, response, details, **kwargs):
|
||||||
|
@ -17,14 +18,15 @@ pre_update.connect(facebook_extra_values, sender=FacebookBackend)
|
||||||
|
|
||||||
def create_wishlist(sender, created, instance, **kwargs):
|
def create_wishlist(sender, created, instance, **kwargs):
|
||||||
# use get_model to avoid circular import problem with models
|
# use get_model to avoid circular import problem with models
|
||||||
# this fails when a superuser is being created as part of a syncdb
|
|
||||||
# since the database table for wishlist doesn't exist yet
|
|
||||||
try:
|
try:
|
||||||
Wishlist = get_model('core', 'Wishlist')
|
Wishlist = get_model('core', 'Wishlist')
|
||||||
if created:
|
if created:
|
||||||
Wishlist.objects.create(user=instance)
|
Wishlist.objects.create(user=instance)
|
||||||
|
|
||||||
except DatabaseError:
|
except DatabaseError:
|
||||||
|
# this can happen when creating superuser during syncdb since the
|
||||||
|
# core_wishlist table doesn't exist yet
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
post_save.connect(create_wishlist, sender=User)
|
post_save.connect(create_wishlist, sender=User)
|
||||||
|
post_save.connect(create_api_key, sender=User)
|
||||||
|
|
|
@ -40,6 +40,12 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
<ul class="menu">
|
||||||
|
<li><a href="{% url privacy %}"><span>Privacy</span></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
<h1>Gluejar Privacy Policy</h1>
|
<h1>Gluejar Privacy Policy</h1>
|
||||||
|
|
||||||
Date of last revision: September 13, 2011
|
Date of last revision: September 13, 2011
|
||||||
|
@ -46,3 +50,6 @@ Date of last revision: September 13, 2011
|
||||||
<h2>Contact Us</h2>
|
<h2>Contact Us</h2>
|
||||||
|
|
||||||
<p>If you have any questions regarding this privacy policy, you can contact us at <a href="mailto:contact@gluejar.com?Subject=Questions%about%20privacy%20policy">contact@gluejar.com</a>, or using our contact page.</p>
|
<p>If you have any questions regarding this privacy policy, you can contact us at <a href="mailto:contact@gluejar.com?Subject=Questions%about%20privacy%20policy">contact@gluejar.com</a>, or using our contact page.</p>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,5 @@ urlpatterns = patterns(
|
||||||
"regluit.frontend.views",
|
"regluit.frontend.views",
|
||||||
url(r"^$", "home", name="home"),
|
url(r"^$", "home", name="home"),
|
||||||
url(r"^supporter/(?P<supporter_username>.+)/$", "supporter", name="supporter"),
|
url(r"^supporter/(?P<supporter_username>.+)/$", "supporter", name="supporter"),
|
||||||
|
url(r"^privacy$", "textpage", {'page': 'privacy'}, name="privacy"),
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,3 +16,9 @@ def supporter(request, supporter_username):
|
||||||
{"supporter": supporter},
|
{"supporter": supporter},
|
||||||
context_instance=RequestContext(request)
|
context_instance=RequestContext(request)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def textpage(request, page):
|
||||||
|
return render_to_response(page + '.html',
|
||||||
|
{},
|
||||||
|
context_instance=RequestContext(request)
|
||||||
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
django
|
django
|
||||||
south
|
south
|
||||||
django-extensions
|
django-extensions
|
||||||
django-tastypie
|
https://github.com/toastdriven/django-tastypie/tarball/master
|
||||||
requests
|
requests
|
||||||
https://bitbucket.org/ubernostrum/django-registration/get/tip.tar.gz
|
https://bitbucket.org/ubernostrum/django-registration/get/tip.tar.gz
|
||||||
django-social-auth
|
django-social-auth
|
||||||
|
|
|
@ -105,6 +105,7 @@ INSTALLED_APPS = (
|
||||||
'regluit.core',
|
'regluit.core',
|
||||||
'registration',
|
'registration',
|
||||||
'social_auth',
|
'social_auth',
|
||||||
|
'tastypie',
|
||||||
)
|
)
|
||||||
|
|
||||||
# A sample logging configuration. The only tangible logging
|
# A sample logging configuration. The only tangible logging
|
||||||
|
|
|
@ -20,6 +20,7 @@ body{
|
||||||
#header{ height:90px;}
|
#header{ height:90px;}
|
||||||
|
|
||||||
.logo{ float:left; padding-top:20px;}
|
.logo{ float:left; padding-top:20px;}
|
||||||
|
.logo a img{border: none;}
|
||||||
.topmenu{ float:right; padding-top:25px;}
|
.topmenu{ float:right; padding-top:25px;}
|
||||||
.topmenu ul li{ float:left; padding:0 10px;}
|
.topmenu ul li{ float:left; padding:0 10px;}
|
||||||
.topmenu ul li a{ height:36px; line-height:36px; display:block; color:#fff; text-decoration:none; font-weight:bold; font-size:13px; letter-spacing:1px; text-transform:capitalize;}
|
.topmenu ul li a{ height:36px; line-height:36px; display:block; color:#fff; text-decoration:none; font-weight:bold; font-size:13px; letter-spacing:1px; text-transform:capitalize;}
|
||||||
|
@ -132,3 +133,9 @@ a{ font-weight:bold; font-size:13px; text-decoration:none; cursor:pointer;}
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#footer{
|
||||||
|
border-top: 7px solid #edf3f4;
|
||||||
|
clear: both;
|
||||||
|
height:90px;
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.5 KiB |
2
urls.py
2
urls.py
|
@ -3,6 +3,6 @@ from django.conf.urls.defaults import *
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
(r'^accounts/', include('registration.backends.default.urls')),
|
(r'^accounts/', include('registration.backends.default.urls')),
|
||||||
(r'^socialauth/', include('social_auth.urls')),
|
(r'^socialauth/', include('social_auth.urls')),
|
||||||
|
(r'^api/', include('regluit.api.urls')),
|
||||||
(r'', include('regluit.frontend.urls')),
|
(r'', include('regluit.frontend.urls')),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue