added celery async task for add_related that gets exercised when a book is added to a wishlist. includes new settings for the djkombu celery backend

pull/1/head
Ed Summers 2011-10-19 23:31:16 -04:00
parent a6e8d115db
commit 0c1411f2e8
10 changed files with 57 additions and 16 deletions

View File

@ -18,6 +18,7 @@ def add_by_isbn(isbn, work=None, add_related=True):
is optional, and if not supplied the edition will be associated with
a stub work.
"""
logger.info("adding book for %s", isbn)
# save a lookup to google if we already have this isbn
has_isbn = Q(isbn_10=isbn) | Q(isbn_13=isbn)
for edition in models.Edition.objects.filter(has_isbn):
@ -49,6 +50,7 @@ def add_by_googlebooks_id(googlebooks_id, work=None):
if not created:
return e
logger.info("loading metadata from google for %s", googlebooks_id)
url = "https://www.googleapis.com/books/v1/volumes/%s" % googlebooks_id
d = _get_json(url)['volumeInfo']
@ -89,6 +91,7 @@ def add_related(isbn):
The initial seed ISBN will be added if it's not already there.
"""
# make sure the seed edition is there
logger.info("adding related editions for %s", isbn)
edition = add_by_isbn(isbn)
# this is the work everything will hang off
@ -104,6 +107,7 @@ def thingisbn(isbn):
"""given an ISBN return a list of related edition ISBNs, according to
Library Thing.
"""
logger.info("looking up %s at ThingISBN" % isbn)
url = "http://www.librarything.com/api/thingISBN/%s" % isbn
xml = requests.get(url, headers={"User-Agent": settings.USER_AGENT}).content
doc = ElementTree.fromstring(xml)
@ -113,6 +117,7 @@ def thingisbn(isbn):
def merge_works(w1, w2):
"""will merge the second work (w2) into the first (w1)
"""
logger.info("merging work %s into %s", w1, w2)
for edition in w2.editions.all():
edition.work = w1
edition.save()

View File

@ -102,9 +102,7 @@ class Work(models.Model):
openlibrary_id = models.CharField(max_length=50, null=True)
def cover_image_small(self):
server_id = random.randint(0, 9)
gb_id = self.editions.all()[0].googlebooks_id
return "http://bks%i.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=5" % (server_id, gb_id)
return self.editions.all()[0].cover_image_small()
def __unicode__(self):
return self.title
@ -143,6 +141,14 @@ class Edition(models.Model):
def __unicode__(self):
return "%s (%s)" % (self.title, self.isbn_13)
def cover_image_small(self):
server_id = random.randint(0, 9)
return "http://bks%i.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=5" % (server_id, self.googlebooks_id)
def cover_image_thumbnail(self):
server_id = random.randint(0, 9)
return "http://bks%s.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=1" % (server_id, self.googlebooks_id)
@classmethod
def get_by_isbn(klass, isbn):
for e in Edition.objects.filter(Q(isbn_10=isbn) | Q(isbn_13=isbn)):

View File

@ -4,5 +4,6 @@ import os
import django.core.handlers.wsgi
os.environ['CELERY_LOADER'] = 'django'
os.environ['DJANGO_SETTINGS_MODULE'] = 'regluit.settings.prod'
application = django.core.handlers.wsgi.WSGIHandler()

View File

@ -233,7 +233,7 @@ how do I integrate the your wishlist thing with the tabs thing?
</div>
<div class="book-name">
<span>
{{ work.title }}
<a href="{% url work work.id %}">{{ work.title }}</a>
</span>
</div>
{% ifequal supporter request.user %}

View File

@ -9,6 +9,7 @@ from regluit.frontend.views import CampaignFormView
urlpatterns = patterns(
"regluit.frontend.views",
url(r"^$", "home", name="home"),
url(r"work/(?P<work_id>.+)/$", "work", name="work"),
url(r"^supporter/(?P<supporter_username>.+)/$", "supporter", name="supporter"),
url(r"^search/$", "search", name="search"),
url(r"^privacy/$", TemplateView.as_view(template_name="privacy.html"),

View File

@ -1,31 +1,25 @@
from django.template import RequestContext
import logging
from decimal import Decimal as D
from django.conf import settings
from django.contrib.auth.models import User
# from django.contrib.auth.forms import UserChangeForm
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.views.generic import ListView, DetailView
from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, render_to_response, get_object_or_404
from django.conf import settings
from regluit.core import tasks
from regluit.core import models, bookloader
from regluit.core.search import gluejar_search
from regluit.frontend.forms import UserData,ProfileForm
from regluit.frontend.forms import UserData, ProfileForm
from regluit.frontend.forms import CampaignPledgeForm
from regluit.payment.manager import PaymentManager
from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN
from decimal import Decimal as D
import logging
logger = logging.getLogger(__name__)
from regluit.payment.models import Transaction
@ -36,6 +30,10 @@ def home(request):
args=[request.user.username]))
return render(request, 'home.html', {'suppress_search_box': True})
def work(request, work_id):
work = get_object_or_404(models.Work, id=work_id)
return render(request, 'work.html', {'work': work})
def supporter(request, supporter_username):
supporter = get_object_or_404(User, username=supporter_username)
wishlist = supporter.wishlist
@ -137,6 +135,8 @@ def wishlist(request):
remove_work_id = request.POST.get('remove_work_id', None)
if googlebooks_id:
edition = bookloader.add_by_googlebooks_id(googlebooks_id)
# add related editions asynchronously
tasks.add_related.delay(edition.isbn_10)
request.user.wishlist.works.add(edition.work)
# TODO: redirect to work page, when it exists
return HttpResponseRedirect('/')
@ -158,6 +158,7 @@ class CampaignFormView(FormView):
'campaign': campaign
})
return context
def form_valid(self,form):
pk = self.kwargs["pk"]
pledge_amount = form.cleaned_data["pledge_amount"]

View File

@ -9,3 +9,4 @@ selenium
django-nose-selenium
nose
django-profiles
django-kombu

View File

@ -107,6 +107,7 @@ INSTALLED_APPS = (
'registration',
'social_auth',
'tastypie',
'djcelery',
)
# A sample logging configuration. The only tangible logging
@ -182,3 +183,6 @@ USER_AGENT = "unglue.it.bot v0.0.1 <http://unglue.it>"
SOUTH_TESTS_MIGRATE = True
AUTH_PROFILE_MODULE = "core.userprofile"
import djcelery
djcelery.setup_loader()

View File

@ -79,3 +79,7 @@ PAYPAL_TEST_RH_EMAIL = "rh1_1317336251_biz@gluejar.com"
PAYPAL_TEST_NONPROFIT_PARTNER_EMAIL = ""
BASE_URL = 'http://0.0.0.0/'
# use database as queuing service in development
BROKER_TRANSPORT = "djkombu.transport.DatabaseTransport"
INSTALLED_APPS += ("djkombu",)

View File

@ -697,3 +697,21 @@ span.bounce-search {
border-bottom: 3px solid;
cursor: pointer;
}
/* work page */
ul.edition-list {
list-style: none;
}
ul.edition-list li {
clear: both;
padding: 10px;
height: 80px;
border-bottom: thin gray solid;
}
li.edition img.cover {
vertical-align: top;
}
li.edition span.publisher {
font-weight: bold;
}