2013-03-26 17:54:03 +00:00
'''
imports not from django or regluit
'''
2011-12-05 05:56:24 +00:00
import re
import sys
import json
2011-10-20 03:31:16 +00:00
import logging
2012-03-13 20:57:42 +00:00
import urllib
2013-03-26 17:54:03 +00:00
import requests
import oauth2 as oauth
2012-03-13 20:57:42 +00:00
2012-09-18 18:16:06 +00:00
from datetime import timedelta , date
2013-03-26 17:54:03 +00:00
from decimal import Decimal as D
from itertools import islice , chain
from notification import models as notification
2012-01-09 20:53:09 +00:00
from random import randint
2011-12-05 05:56:24 +00:00
from re import sub
2011-12-23 01:34:24 +00:00
from xml . etree import ElementTree as ET
2013-03-26 17:54:03 +00:00
from tastypie . models import ApiKey
'''
django imports
'''
2011-11-30 02:02:51 +00:00
from django import forms
2011-10-20 03:31:16 +00:00
from django . conf import settings
2011-09-12 05:53:54 +00:00
from django . contrib . auth . models import User
2012-01-02 14:39:11 +00:00
from django . contrib import messages
2012-02-23 20:40:45 +00:00
from django . contrib . auth . decorators import login_required
2013-03-08 02:48:56 +00:00
from django . contrib . auth . views import login
2012-02-03 15:22:53 +00:00
from django . contrib . comments import Comment
2012-05-12 15:12:27 +00:00
from django . contrib . sites . models import Site
2013-03-26 17:54:03 +00:00
from django . core import signing
from django . core . exceptions import ObjectDoesNotExist
from django . core . urlresolvers import reverse
2012-02-23 20:40:45 +00:00
from django . db . models import Q , Count , Sum
2011-11-01 00:26:05 +00:00
from django . forms import Select
2011-11-17 19:35:29 +00:00
from django . forms . models import modelformset_factory
2012-02-11 20:14:31 +00:00
from django . http import HttpResponseRedirect , Http404
2012-02-02 14:03:24 +00:00
from django . http import HttpResponse , HttpResponseNotFound
2013-03-26 17:54:03 +00:00
from django . shortcuts import render , render_to_response , get_object_or_404
2012-04-25 02:20:10 +00:00
from django . template . loader import render_to_string
2013-03-26 17:54:03 +00:00
from django . utils . http import urlencode
from django . utils . translation import ugettext_lazy as _
2011-09-29 06:23:50 +00:00
from django . views . decorators . csrf import csrf_exempt
from django . views . decorators . http import require_POST
2011-10-12 17:47:48 +00:00
from django . views . generic . edit import FormView
2011-12-01 18:17:33 +00:00
from django . views . generic . list import ListView
2011-10-25 01:29:01 +00:00
from django . views . generic . base import TemplateView
2013-03-26 17:54:03 +00:00
'''
regluit imports
'''
2011-10-20 03:31:16 +00:00
from regluit . core import tasks
2011-11-16 18:20:10 +00:00
from regluit . core import models , bookloader , librarything
2011-11-14 20:16:12 +00:00
from regluit . core import userlists
2013-03-01 14:46:52 +00:00
from regluit . core import goodreads
2012-12-13 03:35:35 +00:00
from regluit . core . bookloader import merge_works
2013-03-26 17:54:03 +00:00
from regluit . core . goodreads import GoodreadsClient
from regluit . core . search import gluejar_search
2013-03-01 14:46:52 +00:00
from regluit . core . signals import supporter_message
2013-04-08 20:51:08 +00:00
from regluit . core . tasks import send_mail_task , emit_notifications
2013-03-26 17:54:03 +00:00
2013-03-22 20:39:23 +00:00
from regluit . frontend . forms import UserData , ProfileForm , CampaignPledgeForm , GoodreadsShelfLoadingForm
2011-11-23 16:06:48 +00:00
from regluit . frontend . forms import RightsHolderForm , UserClaimForm , LibraryThingForm , OpenCampaignForm
2012-05-01 14:56:19 +00:00
from regluit . frontend . forms import getManageCampaignForm , DonateForm , CampaignAdminForm , EmailShareForm , FeedbackForm
2012-05-21 14:56:18 +00:00
from regluit . frontend . forms import EbookForm , CustomPremiumForm , EditManagersForm , EditionForm , PledgeCancelForm
2012-12-13 03:35:35 +00:00
from regluit . frontend . forms import getTransferCreditForm , CCForm , CloneCampaignForm , PlainCCForm , WorkForm , OtherWorkForm
2013-03-13 14:40:20 +00:00
from regluit . frontend . forms import MsgForm , AuthForm
2013-04-04 15:09:18 +00:00
from regluit . frontend . forms import PressForm
2013-03-26 17:54:03 +00:00
from regluit . payment import baseprocessor , stripelib
from regluit . payment . credit import credit_transaction
2011-10-13 21:13:37 +00:00
from regluit . payment . manager import PaymentManager
2013-03-26 17:54:03 +00:00
from regluit . payment . models import Transaction , Account , Sent , CreditLog
2012-09-06 20:55:32 +00:00
from regluit . payment . parameters import TRANSACTION_STATUS_ACTIVE , TRANSACTION_STATUS_COMPLETE , TRANSACTION_STATUS_CANCELED , TRANSACTION_STATUS_ERROR , TRANSACTION_STATUS_FAILED , TRANSACTION_STATUS_INCOMPLETE , TRANSACTION_STATUS_NONE , TRANSACTION_STATUS_MODIFIED
2012-09-13 21:12:49 +00:00
from regluit . payment . parameters import PAYMENT_TYPE_AUTHORIZATION , PAYMENT_TYPE_INSTANT
2012-09-19 00:01:07 +00:00
from regluit . payment . parameters import PAYMENT_HOST_STRIPE , PAYMENT_HOST_NONE
2011-12-19 06:33:13 +00:00
2013-03-26 17:54:03 +00:00
from regluit . utils . localdatetime import now , date_today
2011-10-25 01:29:01 +00:00
2011-10-12 17:47:48 +00:00
logger = logging . getLogger ( __name__ )
2011-10-03 16:36:04 +00:00
2012-07-07 22:13:05 +00:00
def static_redirect_view ( request , file_name , dir = " " ) :
return HttpResponseRedirect ( ' /static/ ' + dir + " / " + file_name )
2012-03-08 14:36:59 +00:00
def slideshow ( max ) :
ending = models . Campaign . objects . filter ( status = ' ACTIVE ' ) . order_by ( ' deadline ' )
count = ending . count ( )
j = 0
2012-06-13 12:41:23 +00:00
worklist = [ ]
if max > count :
# add all the works with active campaigns
for campaign in ending :
worklist . append ( campaign . work )
2012-09-11 03:47:06 +00:00
2012-06-13 12:41:23 +00:00
# then fill out the rest of the list with popular but inactive works
remainder = max - count
2012-10-15 04:59:46 +00:00
remainder_works = models . Work . objects . filter ( wishlists__user = recommended_user ) . exclude ( campaigns__status = ' ACTIVE ' ) . exclude ( campaigns__status = ' SUCCESSFUL ' ) [ : remainder ]
2012-06-13 12:41:23 +00:00
worklist . extend ( remainder_works )
2012-03-08 14:36:59 +00:00
else :
2012-06-13 12:41:23 +00:00
# if the active campaign list has more works than we can fit
# in our slideshow, it's the only source we need to draw from
while j < max :
worklist . append ( ending [ j ] . work )
j + = 1
2012-03-23 15:15:37 +00:00
2012-03-08 14:36:59 +00:00
return worklist
2011-10-13 16:23:57 +00:00
2012-03-13 20:57:42 +00:00
def next ( request ) :
2012-03-23 15:15:37 +00:00
if request . COOKIES . has_key ( ' next ' ) :
2012-05-15 18:18:17 +00:00
response = HttpResponseRedirect ( urllib . unquote ( urllib . unquote ( request . COOKIES [ ' next ' ] ) ) )
2012-03-23 15:15:37 +00:00
response . delete_cookie ( ' next ' )
return response
else :
return HttpResponseRedirect ( ' / ' )
2012-08-24 19:14:32 +00:00
def safe_get_work ( work_id ) :
2012-08-29 19:56:14 +00:00
"""
use this rather than querying the db directly for a work by id
"""
2012-08-24 19:14:32 +00:00
try :
work = models . Work . objects . get ( id = work_id )
except models . Work . DoesNotExist :
try :
work = models . WasWork . objects . get ( was = work_id ) . work
except models . WasWork . DoesNotExist :
raise Http404
return work
2013-02-07 20:25:14 +00:00
def cover_width ( work ) :
if work . percent_of_goal ( ) < 100 :
cover_width = 100 - work . percent_of_goal ( )
else :
cover_width = 0
return cover_width
2012-03-13 20:57:42 +00:00
2012-05-24 19:29:45 +00:00
def home ( request , landing = False ) :
if request . user . is_authenticated ( ) and landing == False :
2011-09-27 09:27:15 +00:00
return HttpResponseRedirect ( reverse ( ' supporter ' ,
args = [ request . user . username ] ) )
2013-03-26 18:55:50 +00:00
"""
use campaigns instead of works so that we can order by amount left ,
drive interest toward most - nearly - successful
"""
top_campaigns = models . Campaign . objects . filter ( status = " ACTIVE " ) . order_by ( ' left ' ) [ : 4 ]
2013-03-28 15:12:55 +00:00
most_wished = models . Work . objects . order_by ( ' -num_wishes ' ) [ : 4 ]
2013-03-26 18:55:50 +00:00
unglued_books = models . Work . objects . filter ( campaigns__status = " SUCCESSFUL " ) . order_by ( ' -campaigns__deadline ' )
2012-01-15 23:03:54 +00:00
2013-03-26 17:54:03 +00:00
"""
get various recent types of site activity
"""
latest_comments = Comment . objects . order_by (
' -submit_date '
) [ : 10 ]
latest_pledges = Transaction . objects . filter (
anonymous = False
2013-03-28 15:38:40 +00:00
) . only (
' date_created ' , ' user ' , ' campaign '
2013-03-26 17:54:03 +00:00
) . order_by (
' -date_created '
) [ : 10 ]
latest_wishes = models . Wishes . objects . order_by (
' -created '
) [ : 10 ]
2012-03-08 14:36:59 +00:00
2013-03-26 17:54:03 +00:00
"""
2013-03-26 18:55:50 +00:00
for each event , we ' ll be passing its object and type to the template
2013-03-26 17:54:03 +00:00
( and preserving its date for sorting purposes )
"""
latest_comments_tuple = map (
2013-03-28 15:38:40 +00:00
lambda x : ( x . submit_date , x , ' comment ' ) ,
2013-03-26 17:54:03 +00:00
latest_comments
)
latest_pledges_tuple = map (
2013-03-28 15:38:40 +00:00
lambda x : ( x . date_created , x , ' pledge ' ) ,
2013-03-26 17:54:03 +00:00
latest_pledges
)
latest_wishes_tuple = map (
2013-03-28 15:38:40 +00:00
lambda x : ( x . created , x , ' wish ' ) ,
2013-03-26 17:54:03 +00:00
latest_wishes
)
2013-03-26 18:55:50 +00:00
"""
merge latest actions into a single list , sorted by date , to loop through in template
"""
2013-03-26 17:54:03 +00:00
latest_actions = sorted (
chain ( latest_comments_tuple , latest_pledges_tuple , latest_wishes_tuple ) ,
key = lambda instance : instance [ 0 ] ,
reverse = True
)
2013-03-22 19:47:03 +00:00
if request . user . is_authenticated ( ) :
2013-03-26 17:54:03 +00:00
events = latest_actions [ : 12 ]
2013-03-22 19:47:03 +00:00
else :
2013-03-26 17:54:03 +00:00
events = latest_actions [ : 6 ]
2013-03-22 19:47:03 +00:00
2013-03-26 18:55:50 +00:00
return render ( request , ' home.html ' , {
' suppress_search_box ' : True , ' events ' : events , ' top_campaigns ' : top_campaigns , ' unglued_books ' : unglued_books , ' most_wished ' : most_wished
} )
2011-09-12 03:44:21 +00:00
2011-11-02 19:40:43 +00:00
def stub ( request ) :
2011-11-09 17:24:26 +00:00
path = request . path [ 6 : ] # get rid of /stub/
return render ( request , ' stub.html ' , { ' path ' : path } )
2011-11-06 21:46:46 +00:00
2012-07-07 22:13:05 +00:00
def acks ( request , work ) :
return render ( request , ' front_matter.html ' , { ' campaign ' : work . last_campaign ( ) } )
2013-03-08 02:48:56 +00:00
def superlogin ( request , * * kwargs ) :
extra_context = None
if request . method == ' POST ' and request . user . is_anonymous ( ) :
username = request . POST . get ( " username " , " " )
try :
user = models . User . objects . get ( username = username )
extra_context = { " socials " : user . profile . social_auths }
except :
pass
2013-03-29 15:50:07 +00:00
if request . GET . has_key ( " add " ) :
request . session [ " add_wishlist " ] = request . GET [ " add " ]
2013-03-21 14:14:23 +00:00
return login ( request , extra_context = extra_context , authentication_form = AuthForm , * * kwargs )
2013-03-08 02:48:56 +00:00
2011-11-06 23:54:48 +00:00
def work ( request , work_id , action = ' display ' ) :
2012-08-24 19:14:32 +00:00
work = safe_get_work ( work_id )
2012-07-07 22:13:05 +00:00
if action == " acks " :
return acks ( request , work )
2012-08-24 19:14:32 +00:00
2013-03-29 15:50:07 +00:00
# process waiting add request
if not request . user . is_anonymous ( ) and request . session . has_key ( " add_wishlist " ) :
add_url = request . session [ " add_wishlist " ]
if add_url == request . path :
request . user . wishlist . add_work ( work , " login " , notify = True )
request . session . pop ( " add_wishlist " )
2012-02-28 22:28:33 +00:00
if request . method == ' POST ' and not request . user . is_anonymous ( ) :
activetab = ' 4 '
else :
try :
activetab = request . GET [ ' tab ' ]
if activetab not in [ ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' ] :
activetab = ' 1 ' ;
except :
activetab = ' 1 ' ;
2012-08-24 19:14:32 +00:00
2013-02-25 23:31:37 +00:00
alert = ' '
2011-11-06 22:44:50 +00:00
campaign = work . last_campaign ( )
2012-09-11 03:51:22 +00:00
if campaign and campaign . edition and not request . user . is_staff :
2012-05-01 14:56:19 +00:00
editions = [ campaign . edition ]
else :
editions = work . editions . all ( ) . order_by ( ' -publication_date ' )
2012-01-09 17:44:35 +00:00
try :
2012-01-31 15:07:52 +00:00
pledged = campaign . transactions ( ) . filter ( user = request . user , status = " ACTIVE " )
2012-01-09 17:44:35 +00:00
except :
2012-01-31 15:07:52 +00:00
pledged = None
2012-05-01 17:49:23 +00:00
2012-09-13 21:12:49 +00:00
logger . info ( " pledged: {0} " . format ( pledged ) )
2013-02-07 20:25:14 +00:00
cover_width_number = 0
2012-08-24 19:14:32 +00:00
try :
2012-09-11 03:47:06 +00:00
assert not ( work . last_campaign_status ( ) == ' ACTIVE ' and work . first_ebook ( ) )
2012-08-24 19:14:32 +00:00
except :
2012-09-11 03:47:06 +00:00
logger . warning ( " Campaign running for %s when ebooks are already available: why? " % work . title )
2012-05-13 19:33:54 +00:00
if work . last_campaign_status ( ) == ' ACTIVE ' :
2013-02-07 20:25:14 +00:00
cover_width_number = cover_width ( work )
2012-09-11 03:47:06 +00:00
2012-05-14 02:13:45 +00:00
if action == ' preview ' :
work . last_campaign_status = ' ACTIVE '
2012-05-11 18:13:09 +00:00
2011-11-26 22:09:33 +00:00
if not request . user . is_anonymous ( ) :
2012-03-23 01:24:12 +00:00
claimform = UserClaimForm ( request . user , data = { ' claim-work ' : work . pk , ' claim-user ' : request . user . id } , prefix = ' claim ' )
2012-02-28 22:28:33 +00:00
for edition in editions :
2012-04-27 21:14:57 +00:00
edition . hide_details = 1
if request . method == ' POST ' and not request . user . is_anonymous ( ) :
if request . POST . has_key ( ' ebook_ %d -edition ' % edition . id ) :
edition . ebook_form = EbookForm ( data = request . POST , prefix = ' ebook_ %d ' % edition . id )
if edition . ebook_form . is_valid ( ) :
edition . ebook_form . save ( )
alert = ' Thanks for adding an ebook to unglue.it! '
else :
edition . hide_details = 0
alert = ' your submitted ebook had errors '
else :
#edition.ebook_form = EbookForm( data = {'user':request.user.id, 'edition':edition.pk })
edition . ebook_form = EbookForm ( instance = models . Ebook ( user = request . user , edition = edition , provider = ' x ' ) , prefix = ' ebook_ %d ' % edition . id )
2011-11-26 22:09:33 +00:00
else :
claimform = None
2012-08-24 19:14:32 +00:00
2011-11-06 22:44:50 +00:00
if campaign :
2012-07-23 11:41:20 +00:00
# pull up premiums explicitly tied to the campaign
# mandatory premiums are only displayed in pledge process
premiums = campaign . custom_premiums ( )
2011-11-07 20:39:02 +00:00
else :
premiums = None
2011-11-21 15:51:50 +00:00
2012-02-11 19:15:06 +00:00
wishers = work . num_wishes
2011-11-22 19:28:27 +00:00
base_url = request . build_absolute_uri ( " / " ) [ : - 1 ]
2012-04-03 13:56:41 +00:00
active_claims = work . claim . all ( ) . filter ( status = ' active ' )
if active_claims . count ( ) == 1 :
2012-04-03 19:50:02 +00:00
claimstatus = ' one_active '
rights_holder_name = active_claims [ 0 ] . rights_holder . rights_holder_name
2012-04-03 13:56:41 +00:00
else :
rights_holder_name = None
2012-04-03 19:50:02 +00:00
pending_claims = work . claim . all ( ) . filter ( status = ' pending ' )
pending_claims_count = pending_claims . count ( )
if pending_claims_count > 1 :
claimstatus = ' disputed '
elif pending_claims_count == 1 :
claimstatus = ' one_pending '
rights_holder_name = pending_claims [ 0 ] . rights_holder . rights_holder_name
else :
claimstatus = ' open '
2012-02-01 20:57:03 +00:00
2012-03-23 15:09:51 +00:00
return render ( request , ' work.html ' , {
' work ' : work ,
' premiums ' : premiums ,
' ungluers ' : userlists . supporting_users ( work , 5 ) ,
' claimform ' : claimform ,
' wishers ' : wishers ,
' base_url ' : base_url ,
' editions ' : editions ,
2012-04-03 13:56:41 +00:00
' pledged ' : pledged ,
2012-03-23 15:09:51 +00:00
' activetab ' : activetab ,
2012-04-03 13:56:41 +00:00
' alert ' : alert ,
' claimstatus ' : claimstatus ,
' rights_holder_name ' : rights_holder_name ,
2013-02-07 20:25:14 +00:00
' cover_width ' : cover_width_number
2012-09-25 01:51:57 +00:00
} )
2011-11-21 03:23:51 +00:00
2012-05-14 05:07:02 +00:00
def new_edition ( request , work_id , edition_id , by = None ) :
2012-05-11 18:13:09 +00:00
if not request . user . is_authenticated ( ) :
return render ( request , " admins_only.html " )
# if the work and edition are set, we save the edition and set the work
language = ' en '
description = ' '
title = ' '
if work_id :
try :
work = models . Work . objects . get ( id = work_id )
except models . Work . DoesNotExist :
try :
work = models . WasWork . objects . get ( was = work_id ) . work
except models . WasWork . DoesNotExist :
raise Http404
language = work . language
description = work . description
title = work . title
else :
work = None
2012-05-14 05:07:02 +00:00
if not request . user . is_staff :
if by == ' rh ' and work is not None :
if not request . user in work . last_campaign ( ) . managers . all ( ) :
return render ( request , " admins_only.html " )
else :
return render ( request , " admins_only.html " )
2012-05-11 18:13:09 +00:00
if edition_id :
try :
edition = models . Edition . objects . get ( id = edition_id )
except models . Work . DoesNotExist :
raise Http404
if work :
edition . work = work
language = edition . work . language
description = edition . work . description
else :
edition = models . Edition ( )
if work :
edition . work = work
if request . method == ' POST ' :
edition . new_author_names = request . POST . getlist ( ' new_author ' )
edition . new_subjects = request . POST . getlist ( ' new_subject ' )
if request . POST . has_key ( ' add_author_submit ' ) :
new_author_name = request . POST [ ' add_author ' ] . strip ( )
try :
author = models . Author . objects . get ( name = new_author_name )
except models . Author . DoesNotExist :
author = models . Author . objects . create ( name = new_author_name )
edition . new_author_names . append ( new_author_name )
form = EditionForm ( instance = edition , data = request . POST )
elif request . POST . has_key ( ' add_subject_submit ' ) :
new_subject = request . POST [ ' add_subject ' ] . strip ( )
try :
author = models . Subject . objects . get ( name = new_subject )
except models . Subject . DoesNotExist :
author = models . Subject . objects . create ( name = new_subject )
edition . new_subjects . append ( new_subject )
form = EditionForm ( instance = edition , data = request . POST )
else :
form = EditionForm ( instance = edition , data = request . POST )
if form . is_valid ( ) :
form . save ( )
if not work :
work = models . Work ( title = form . cleaned_data [ ' title ' ] , language = form . cleaned_data [ ' language ' ] , description = form . cleaned_data [ ' description ' ] )
work . save ( )
edition . work = work
edition . save ( )
else :
work . description = form . cleaned_data [ ' description ' ]
work . title = form . cleaned_data [ ' title ' ]
work . save ( )
2012-09-25 01:51:57 +00:00
# note: this is very powerful. it can steal an isbn from another edition/work, and it will wipe the changed isbn from the db
models . Identifier . set ( type = ' isbn ' , value = form . cleaned_data [ ' isbn_13 ' ] , edition = edition , work = work )
if form . cleaned_data [ ' oclcnum ' ] :
# note: this is very powerful.(same comment as for isbn) use with care!
models . Identifier . set ( type = ' oclc ' , value = form . cleaned_data [ ' oclcnum ' ] , edition = edition , work = work )
2012-05-11 18:13:09 +00:00
for author_name in edition . new_author_names :
try :
author = models . Author . objects . get ( name = author_name )
except models . Author . DoesNotExist :
author = models . Author . objects . create ( name = author_name )
author . editions . add ( edition )
for subject_name in edition . new_subjects :
try :
subject = models . Subject . objects . get ( name = subject_name )
except models . Subject . DoesNotExist :
subject = models . Subject . objects . create ( name = subject_name )
subject . works . add ( work )
work_url = reverse ( ' work ' , kwargs = { ' work_id ' : edition . work . id } )
return HttpResponseRedirect ( work_url )
else :
form = EditionForm ( instance = edition , initial = {
' language ' : language ,
' isbn_13 ' : edition . isbn_13 ,
2012-09-25 01:51:57 +00:00
' oclcnum ' : edition . oclc ,
2012-05-11 18:13:09 +00:00
' description ' : description ,
' title ' : title
} )
return render ( request , ' new_edition.html ' , {
' form ' : form , ' edition ' : edition
} )
2011-11-21 03:23:51 +00:00
def manage_campaign ( request , id ) :
campaign = get_object_or_404 ( models . Campaign , id = id )
2011-11-26 02:23:37 +00:00
campaign . not_manager = False
campaign . problems = [ ]
2012-07-10 19:58:19 +00:00
if ( not request . user . is_authenticated ) or ( not request . user in campaign . managers . all ( ) and not request . user . is_staff ) :
2011-11-22 05:28:06 +00:00
campaign . not_manager = True
return render ( request , ' manage_campaign.html ' , { ' campaign ' : campaign } )
2012-05-04 13:56:41 +00:00
alerts = [ ]
activetab = ' #1 '
2012-03-26 19:31:41 +00:00
if request . method == ' POST ' :
if request . POST . has_key ( ' add_premium ' ) :
postcopy = request . POST . copy ( )
postcopy [ ' type ' ] = ' CU '
new_premium_form = CustomPremiumForm ( data = postcopy )
if new_premium_form . is_valid ( ) :
new_premium_form . save ( )
alerts . append ( _ ( ' New premium has been added ' ) )
new_premium_form = CustomPremiumForm ( data = { ' campaign ' : campaign } )
else :
alerts . append ( _ ( ' New premium has not been added ' ) )
2012-05-01 14:56:19 +00:00
form = getManageCampaignForm ( instance = campaign )
2012-05-04 13:56:41 +00:00
activetab = ' #2 '
elif request . POST . has_key ( ' save ' ) or request . POST . has_key ( ' launch ' ) :
2012-05-01 14:56:19 +00:00
form = getManageCampaignForm ( instance = campaign , data = request . POST )
2012-03-26 19:31:41 +00:00
if form . is_valid ( ) :
form . save ( )
2012-06-22 03:10:50 +00:00
campaign . update_left ( )
2012-03-26 19:31:41 +00:00
alerts . append ( _ ( ' Campaign data has been saved ' ) )
2012-05-04 13:56:41 +00:00
activetab = ' #2 '
2011-11-26 02:23:37 +00:00
else :
2012-03-26 19:31:41 +00:00
alerts . append ( _ ( ' Campaign data has NOT been saved ' ) )
if ' launch ' in request . POST . keys ( ) :
2012-05-04 13:56:41 +00:00
activetab = ' #3 '
2012-09-27 15:14:09 +00:00
if ( campaign . launchable and form . is_valid ( ) ) and ( not settings . IS_PREVIEW or request . user . is_staff ) :
2012-03-26 19:31:41 +00:00
campaign . activate ( )
alerts . append ( _ ( ' Campaign has been launched ' ) )
else :
alerts . append ( _ ( ' Campaign has NOT been launched ' ) )
new_premium_form = CustomPremiumForm ( data = { ' campaign ' : campaign } )
elif request . POST . has_key ( ' inactivate ' ) :
2012-05-04 13:56:41 +00:00
activetab = ' #2 '
2012-03-26 19:31:41 +00:00
if request . POST . has_key ( ' premium_id ' ) :
2012-05-08 14:51:04 +00:00
premiums_to_stop = request . POST . getlist ( ' premium_id ' )
2012-03-26 19:31:41 +00:00
for premium_to_stop in premiums_to_stop :
selected_premium = models . Premium . objects . get ( id = premium_to_stop )
if selected_premium . type == ' CU ' :
selected_premium . type = ' XX '
selected_premium . save ( )
alerts . append ( _ ( ' Premium %s has been inactivated ' % premium_to_stop ) )
2012-05-01 14:56:19 +00:00
form = getManageCampaignForm ( instance = campaign )
2012-03-26 19:31:41 +00:00
new_premium_form = CustomPremiumForm ( data = { ' campaign ' : campaign } )
2011-11-22 05:28:06 +00:00
else :
2012-05-01 14:56:19 +00:00
form = getManageCampaignForm ( instance = campaign )
2012-03-26 19:31:41 +00:00
new_premium_form = CustomPremiumForm ( data = { ' campaign ' : campaign } )
2012-05-04 13:56:41 +00:00
work = campaign . work
2012-03-26 19:31:41 +00:00
return render ( request , ' manage_campaign.html ' , {
' campaign ' : campaign ,
' form ' : form ,
' problems ' : campaign . problems ,
' alerts ' : alerts ,
2012-10-02 18:42:39 +00:00
' premiums ' : campaign . custom_premiums ( ) ,
2012-03-26 19:31:41 +00:00
' premium_form ' : new_premium_form ,
2012-05-04 13:56:41 +00:00
' work ' : work ,
' activetab ' : activetab ,
2012-03-26 19:31:41 +00:00
} )
2011-11-15 16:27:32 +00:00
2011-11-22 01:12:13 +00:00
def googlebooks ( request , googlebooks_id ) :
try :
2012-01-09 18:55:22 +00:00
edition = models . Identifier . objects . get ( type = ' goog ' , value = googlebooks_id ) . edition
except models . Identifier . DoesNotExist :
2012-01-31 15:08:43 +00:00
try :
edition = bookloader . add_by_googlebooks_id ( googlebooks_id )
if edition . new :
# add related editions asynchronously
2012-02-16 18:19:36 +00:00
tasks . populate_edition . delay ( edition . isbn_13 )
2012-01-31 15:08:43 +00:00
except bookloader . LookupFailure :
logger . warning ( " failed to load googlebooks_id %s " % googlebooks_id )
return HttpResponseNotFound ( " failed looking up googlebooks id %s " % googlebooks_id )
2011-11-22 01:12:13 +00:00
if not edition :
return HttpResponseNotFound ( " invalid googlebooks id " )
work_url = reverse ( ' work ' , kwargs = { ' work_id ' : edition . work . id } )
2013-03-29 15:50:07 +00:00
# process waiting add request
if not request . user . is_anonymous ( ) and request . session . has_key ( " add_wishlist " ) :
add_url = request . session [ " add_wishlist " ]
if add_url == request . path :
request . user . wishlist . add_work ( edition . work , " login " , notify = True )
request . session . pop ( " add_wishlist " )
2011-11-22 01:12:13 +00:00
return HttpResponseRedirect ( work_url )
2011-10-20 03:31:16 +00:00
2011-11-15 02:13:39 +00:00
def subjects ( request ) :
order = request . GET . get ( ' order ' )
subjects = models . Subject . objects . all ( )
2011-12-19 06:33:13 +00:00
subjects = subjects . annotate ( Count ( ' works ' ) )
2011-11-15 02:13:39 +00:00
if request . GET . get ( ' order ' ) == ' count ' :
2011-12-19 06:33:13 +00:00
subjects = subjects . order_by ( ' -works__count ' )
2011-11-15 02:13:39 +00:00
else :
subjects = subjects . order_by ( ' name ' )
2011-10-20 03:31:16 +00:00
2011-11-15 02:13:39 +00:00
return render ( request , ' subjects.html ' , { ' subjects ' : subjects } )
2011-11-07 21:01:08 +00:00
2012-07-21 20:26:16 +00:00
class FilterableListView ( ListView ) :
def get_queryset ( self ) :
if self . request . GET . has_key ( ' pub_lang ' ) :
if self . model is models . Campaign :
return self . get_queryset_all ( ) . filter ( work__language = self . request . GET [ ' pub_lang ' ] )
else :
return self . get_queryset_all ( ) . filter ( language = self . request . GET [ ' pub_lang ' ] )
else :
return self . get_queryset_all ( )
def get_context_data ( self , * * kwargs ) :
context = super ( FilterableListView , self ) . get_context_data ( * * kwargs )
if self . request . GET . has_key ( ' pub_lang ' ) :
context [ ' pub_lang ' ] = self . request . GET [ ' pub_lang ' ]
else :
context [ ' pub_lang ' ] = ' '
context [ ' show_langs ' ] = True
context [ ' WISHED_LANGS ' ] = settings . WISHED_LANGS
return context
2011-12-03 00:29:23 +00:00
recommended_user = User . objects . filter ( username = settings . UNGLUEIT_RECOMMENDED_USERNAME )
2012-07-21 20:26:16 +00:00
class WorkListView ( FilterableListView ) :
2011-12-03 00:29:23 +00:00
template_name = " work_list.html "
context_object_name = " work_list "
2013-03-07 02:54:12 +00:00
max_works = 100000
2011-12-03 00:29:23 +00:00
2012-07-21 20:26:16 +00:00
def get_queryset_all ( self ) :
2011-12-03 00:29:23 +00:00
facet = self . kwargs [ ' facet ' ]
if ( facet == ' popular ' ) :
2013-03-07 02:54:12 +00:00
return models . Work . objects . exclude ( num_wishes = 0 ) . order_by ( ' -num_wishes ' , ' id ' )
2011-12-03 00:29:23 +00:00
elif ( facet == ' recommended ' ) :
2013-03-07 02:54:12 +00:00
self . template_name = " recommended.html "
2012-03-12 20:40:21 +00:00
return models . Work . objects . filter ( wishlists__user = recommended_user ) . order_by ( ' -num_wishes ' )
2012-01-31 22:56:34 +00:00
elif ( facet == ' new ' ) :
2013-03-07 02:54:12 +00:00
return models . Work . objects . exclude ( num_wishes = 0 ) . order_by ( ' -created ' , ' -num_wishes ' , ' id ' )
2011-12-03 00:29:23 +00:00
else :
2012-02-01 17:43:46 +00:00
return models . Work . objects . all ( ) . order_by ( ' -created ' , ' id ' )
2012-07-21 20:26:16 +00:00
2011-12-03 00:29:23 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( WorkListView , self ) . get_context_data ( * * kwargs )
2011-12-03 03:31:39 +00:00
qs = self . get_queryset ( )
context [ ' ungluers ' ] = userlists . work_list_users ( qs , 5 )
2013-03-05 21:18:54 +00:00
context [ ' facet ' ] = self . kwargs . get ( ' facet ' , ' ' )
2013-03-07 02:54:12 +00:00
works_unglued = qs . exclude ( editions__ebooks__isnull = True ) . distinct ( ) | qs . filter ( campaigns__status = ' SUCCESSFUL ' ) . distinct ( )
2013-03-05 21:18:54 +00:00
context [ ' works_unglued ' ] = works_unglued . order_by ( ' -campaigns__status ' , ' campaigns__deadline ' , ' -num_wishes ' ) [ : self . max_works ]
context [ ' works_active ' ] = qs . filter ( campaigns__status = ' ACTIVE ' ) . distinct ( ) [ : self . max_works ]
context [ ' works_wished ' ] = qs . exclude ( editions__ebooks__isnull = False ) . exclude ( campaigns__status = ' ACTIVE ' ) . exclude ( campaigns__status = ' SUCCESSFUL ' ) . distinct ( ) [ : self . max_works ]
2012-02-29 18:15:38 +00:00
2012-03-02 14:40:10 +00:00
context [ ' activetab ' ] = " #3 "
2012-02-29 18:15:38 +00:00
counts = { }
counts [ ' unglued ' ] = context [ ' works_unglued ' ] . count ( )
counts [ ' unglueing ' ] = context [ ' works_active ' ] . count ( )
counts [ ' wished ' ] = context [ ' works_wished ' ] . count ( )
context [ ' counts ' ] = counts
2012-05-08 18:28:06 +00:00
2011-12-03 00:29:23 +00:00
return context
2012-01-15 21:48:26 +00:00
2013-03-26 03:41:19 +00:00
class ByPubView ( WorkListView ) :
2013-03-05 21:18:54 +00:00
template_name = " bypub_list.html "
context_object_name = " work_list "
2013-03-26 18:53:48 +00:00
max_works = 100000
publisher_name = None
publisher = None
2013-03-26 03:41:19 +00:00
def get_publisher_name ( self ) :
self . publisher_name = get_object_or_404 ( models . PublisherName , id = self . kwargs [ ' pubname ' ] )
2013-03-26 18:53:48 +00:00
self . set_publisher ( )
def set_publisher ( self ) :
2013-03-27 16:22:30 +00:00
if self . publisher_name . key_publisher . count ( ) :
2013-03-26 18:53:48 +00:00
self . publisher = self . publisher_name . key_publisher . all ( ) [ 0 ]
elif self . publisher_name . publisher :
self . publisher = self . publisher_name . publisher
self . publisher_name = self . publisher . name
2013-03-26 03:41:19 +00:00
2013-03-05 21:18:54 +00:00
def get_queryset_all ( self ) :
facet = self . kwargs . get ( ' facet ' , ' ' )
2013-03-26 03:41:19 +00:00
self . get_publisher_name ( )
objects = models . Work . objects . filter ( editions__publisher_name__id = self . publisher_name . id ) . distinct ( )
2013-03-05 21:18:54 +00:00
if ( facet == ' popular ' ) :
return objects . order_by ( ' -num_wishes ' , ' id ' )
elif ( facet == ' pubdate ' ) :
2013-03-07 02:54:12 +00:00
return objects . order_by ( ' -editions__publication_date ' ) # turns out this messes up distinct, and MySQL doesn't support DISTINCT ON
2013-03-05 21:18:54 +00:00
elif ( facet == ' new ' ) :
return objects . filter ( num_wishes__gt = 0 ) . order_by ( ' -created ' , ' -num_wishes ' , ' id ' )
else :
return objects . order_by ( ' title ' , ' id ' )
def get_context_data ( self , * * kwargs ) :
2013-03-26 03:41:19 +00:00
context = super ( ByPubView , self ) . get_context_data ( * * kwargs )
context [ ' pubname ' ] = self . publisher_name
2013-03-26 18:53:48 +00:00
context [ ' publisher ' ] = self . publisher
2013-03-05 21:18:54 +00:00
return context
2013-03-26 03:41:19 +00:00
class ByPubListView ( ByPubView ) :
def get_publisher_name ( self ) :
self . publisher_name = get_object_or_404 ( models . PublisherName , name = self . kwargs [ ' pubname ' ] )
2013-03-26 18:53:48 +00:00
self . set_publisher ( )
2013-03-26 03:41:19 +00:00
2012-07-21 20:26:16 +00:00
class UngluedListView ( FilterableListView ) :
2012-01-15 21:48:26 +00:00
template_name = " unglued_list.html "
context_object_name = " work_list "
2012-07-21 20:26:16 +00:00
def get_queryset_all ( self ) :
2012-01-15 21:48:26 +00:00
facet = self . kwargs [ ' facet ' ]
if ( facet == ' popular ' ) :
2012-02-29 19:20:50 +00:00
return models . Work . objects . filter ( editions__ebooks__isnull = False ) . distinct ( ) . order_by ( ' -num_wishes ' )
2013-02-04 15:09:08 +00:00
elif ( facet == ' cc ' or facet == ' creativecommons ' ) :
# assumes all ebooks have a PD or CC license. compare rights_badge property
2013-02-04 18:32:21 +00:00
return models . Work . objects . filter (
editions__ebooks__isnull = False ,
editions__ebooks__rights__in = [ ' CC BY ' , ' CC BY-NC-SA ' , ' CC BY-NC-ND ' , ' CC BY-NC ' , ' CC BY-ND ' , ' CC BY-SA ' ]
) . distinct ( ) . order_by ( ' -num_wishes ' )
2013-02-04 15:09:08 +00:00
elif ( facet == ' pd ' or facet == ' publicdomain ' ) :
2013-02-04 18:32:21 +00:00
return models . Work . objects . filter (
editions__ebooks__isnull = False ,
editions__ebooks__rights__in = [ ' PD-US ' , ' CC0 ' , ' ' ]
) . distinct ( ) . order_by ( ' -num_wishes ' )
2013-02-06 23:14:56 +00:00
else :
#(facet == '' or facet == 'unglued' or facet is other)
return models . Work . objects . filter ( campaigns__status = " SUCCESSFUL " ) . distinct ( ) . order_by ( ' -campaigns__deadline ' )
2012-01-15 21:48:26 +00:00
def get_context_data ( self , * * kwargs ) :
2013-02-04 15:09:08 +00:00
context = super ( UngluedListView , self ) . get_context_data ( * * kwargs )
qs = self . get_queryset ( )
context [ ' ungluers ' ] = userlists . work_list_users ( qs , 5 )
facet = self . kwargs [ ' facet ' ]
context [ ' facet ' ] = facet
if facet == ' cc ' or facet == ' creativecommons ' :
context [ ' activetab ' ] = " #2 "
elif facet == ' pd ' or facet == ' publicdomain ' :
context [ ' activetab ' ] = " #3 "
else :
2012-03-02 14:40:10 +00:00
context [ ' activetab ' ] = " #1 "
2013-02-04 15:09:08 +00:00
return context
2012-01-15 21:48:26 +00:00
2012-07-21 20:26:16 +00:00
class CampaignListView ( FilterableListView ) :
2011-12-01 18:17:33 +00:00
template_name = " campaign_list.html "
context_object_name = " campaign_list "
model = models . Campaign
2012-07-21 20:26:16 +00:00
def get_queryset_all ( self ) :
2011-12-01 18:17:33 +00:00
facet = self . kwargs [ ' facet ' ]
if ( facet == ' newest ' ) :
2011-12-06 21:37:03 +00:00
return models . Campaign . objects . filter ( status = ' ACTIVE ' ) . order_by ( ' -activated ' )
2011-12-01 22:32:53 +00:00
elif ( facet == ' pledged ' ) :
2011-12-06 21:37:03 +00:00
return models . Campaign . objects . filter ( status = ' ACTIVE ' ) . annotate ( total_pledge = Sum ( ' transaction__amount ' ) ) . order_by ( ' -total_pledge ' )
2011-12-01 22:32:53 +00:00
elif ( facet == ' pledges ' ) :
2011-12-06 21:37:03 +00:00
return models . Campaign . objects . filter ( status = ' ACTIVE ' ) . annotate ( pledges = Count ( ' transaction ' ) ) . order_by ( ' -pledges ' )
2011-12-01 18:17:33 +00:00
elif ( facet == ' almost ' ) :
2011-12-06 21:37:03 +00:00
return models . Campaign . objects . filter ( status = ' ACTIVE ' ) . all ( ) # STUB: will need to make db changes to make this work
2011-12-01 18:17:33 +00:00
elif ( facet == ' ending ' ) :
2011-12-06 21:37:03 +00:00
return models . Campaign . objects . filter ( status = ' ACTIVE ' ) . order_by ( ' deadline ' )
2011-12-01 18:17:33 +00:00
else :
return models . Campaign . objects . all ( )
2011-12-03 03:53:39 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( CampaignListView , self ) . get_context_data ( * * kwargs )
qs = self . get_queryset ( )
context [ ' ungluers ' ] = userlists . campaign_list_users ( qs , 5 )
context [ ' facet ' ] = self . kwargs [ ' facet ' ]
return context
2012-08-07 18:12:50 +00:00
2012-12-13 03:35:35 +00:00
class MergeView ( FormView ) :
template_name = " merge.html "
work = None
def dispatch ( self , request , * args , * * kwargs ) :
if not request . user . is_staff :
return render ( request , " admins_only.html " )
else :
return super ( MergeView , self ) . dispatch ( request , * args , * * kwargs )
def get_context_data ( self , * * kwargs ) :
context = super ( MergeView , self ) . get_context_data ( * * kwargs )
context [ ' work ' ] = self . work
return context
def get_form_class ( self ) :
if self . request . method == ' POST ' and self . request . POST . has_key ( ' confirm_merge_works ' ) :
return WorkForm
else :
return OtherWorkForm
def get_form_kwargs ( self ) :
self . work = get_object_or_404 ( models . Work , id = self . kwargs [ " work_id " ] )
form_kwargs = { ' work ' : self . work }
if self . request . method == ' POST ' :
form_kwargs . update ( { ' data ' : self . request . POST } )
return form_kwargs
def form_valid ( self , form ) :
other_work = form . cleaned_data [ ' other_work ' ]
context = self . get_context_data ( )
if self . request . POST . has_key ( ' confirm_merge_works ' ) :
context [ ' old_work_id ' ] = other_work . id
merge_works ( self . work , other_work , self . request . user )
context [ ' merge_complete ' ] = True
else :
context [ ' form ' ] = WorkForm ( initial = { ' other_work ' : other_work } )
context [ ' other_work ' ] = other_work
return render ( self . request , self . template_name , context )
2012-08-07 18:12:50 +00:00
class DonationView ( TemplateView ) :
template_name = " donation.html "
def get ( self , request , * args , * * kwargs ) :
2012-08-14 01:00:28 +00:00
context = self . get_context_data ( )
context [ ' transfer_form ' ] = getTransferCreditForm ( self . request . user . credit . available )
return self . render_to_response ( context )
2012-08-07 18:12:50 +00:00
def post ( self , request , * args , * * kwargs ) :
2012-08-14 01:00:28 +00:00
context = self . get_context_data ( )
transfer_form = getTransferCreditForm ( self . request . user . credit . available , data = self . request . POST )
if transfer_form . is_valid ( ) :
if self . request . user . credit . transfer_to ( transfer_form . cleaned_data [ ' recipient ' ] , transfer_form . cleaned_data [ ' amount ' ] ) :
#successful transfer
context [ ' transfer_message ' ] = ' Your transfer has been successfully executed. '
context [ ' recipient ' ] = transfer_form . cleaned_data [ ' recipient ' ]
context [ ' transfer_amount ' ] = transfer_form . cleaned_data [ ' amount ' ]
context [ ' transfer_form ' ] = getTransferCreditForm ( self . request . user . credit . available )
else :
#unsuccessful transfer
context [ ' transfer_message ' ] = ' Your transfer was not successful. '
context [ ' transfer_form ' ] = transfer_form
else :
#not valid
context [ ' transfer_form ' ] = transfer_form
return self . render_to_response ( context )
2012-08-07 18:12:50 +00:00
def get_context_data ( self , * args , * * kwargs ) :
2012-09-21 21:15:30 +00:00
context = { ' user ' : self . request . user , ' nonprofit ' : settings . NONPROFIT }
context [ ' donate_form ' ] = DonateForm ( initial = { ' username ' : self . request . user . username } )
2012-08-07 18:12:50 +00:00
return context
2011-12-01 18:17:33 +00:00
2011-11-28 23:39:06 +00:00
class PledgeView ( FormView ) :
template_name = " pledge.html "
form_class = CampaignPledgeForm
2012-08-31 07:16:04 +00:00
transaction = None
campaign = None
work = None
premiums = None
data = None
2012-03-15 21:54:38 +00:00
2012-09-07 20:13:53 +00:00
def get_preapproval_amount ( self ) :
2011-11-30 02:02:51 +00:00
preapproval_amount = self . request . REQUEST . get ( ' preapproval_amount ' , None )
2012-09-07 20:13:53 +00:00
if preapproval_amount :
return preapproval_amount
premium_id = self . request . REQUEST . get ( ' premium_id ' , None )
if premium_id != None :
2011-11-28 23:39:06 +00:00
try :
preapproval_amount = D ( models . Premium . objects . get ( id = premium_id ) . amount )
except :
preapproval_amount = None
2012-09-07 21:11:25 +00:00
if self . transaction :
if preapproval_amount :
preapproval_amount = preapproval_amount if preapproval_amount > self . transaction . amount else self . transaction . amount
else :
preapproval_amount = self . transaction . amount
2012-09-07 20:13:53 +00:00
return preapproval_amount
2012-08-31 07:16:04 +00:00
def get_form_kwargs ( self ) :
2012-09-19 21:30:47 +00:00
2012-05-13 19:18:48 +00:00
assert self . request . user . is_authenticated ( )
2012-08-31 07:16:04 +00:00
self . work = get_object_or_404 ( models . Work , id = self . kwargs [ " work_id " ] )
2012-03-15 21:54:38 +00:00
2012-06-21 17:16:51 +00:00
# if there is no campaign or if campaign is not active, we should raise an error
2012-05-01 13:56:19 +00:00
try :
2012-08-31 07:16:04 +00:00
self . campaign = self . work . last_campaign ( )
# TODO need to sort the premiums
self . premiums = self . campaign . custom_premiums ( ) | models . Premium . objects . filter ( id = 150 )
# Campaign must be ACTIVE
assert self . campaign . status == ' ACTIVE '
except Exception , e :
raise e
2012-05-01 13:56:19 +00:00
2012-08-31 07:16:04 +00:00
transactions = self . campaign . transactions ( ) . filter ( user = self . request . user , status = TRANSACTION_STATUS_ACTIVE , type = PAYMENT_TYPE_AUTHORIZATION )
2012-10-14 15:33:13 +00:00
premium_id = self . request . REQUEST . get ( ' premium_id ' , 150 )
2012-08-31 07:16:04 +00:00
if transactions . count ( ) == 0 :
2012-10-18 18:13:42 +00:00
ack_name = self . request . user . profile . ack_name
2012-08-31 07:16:04 +00:00
ack_dedication = ' '
2012-10-18 18:13:42 +00:00
anonymous = self . request . user . profile . anon_pref
2012-08-31 07:16:04 +00:00
else :
2012-09-07 21:11:25 +00:00
self . transaction = transactions [ 0 ]
2012-10-15 15:39:09 +00:00
if premium_id == 150 and self . transaction . premium is not None :
2012-08-31 07:16:04 +00:00
premium_id = self . transaction . premium . id
2012-10-23 13:37:00 +00:00
if self . transaction . ack_name :
ack_name = self . transaction . ack_name
else :
ack_name = self . request . user . profile . ack_name
ack_dedication = self . transaction . ack_dedication
2012-08-31 07:16:04 +00:00
anonymous = self . transaction . anonymous
2012-09-07 20:13:53 +00:00
2012-09-07 21:11:25 +00:00
self . data = { ' preapproval_amount ' : self . get_preapproval_amount ( ) , ' premium_id ' : premium_id ,
' ack_name ' : ack_name , ' ack_dedication ' : ack_dedication , ' anonymous ' : anonymous }
2012-08-31 07:16:04 +00:00
if self . request . method == ' POST ' :
self . data . update ( self . request . POST . dict ( ) )
2012-10-13 02:24:58 +00:00
if not self . request . POST . has_key ( ' anonymous ' ) :
del self . data [ ' anonymous ' ]
2012-10-13 03:43:51 +00:00
if not self . request . POST . has_key ( ' ack_name ' ) :
del self . data [ ' ack_name ' ]
if not self . request . POST . has_key ( ' ack_dedication ' ) :
del self . data [ ' ack_dedication ' ]
2012-08-31 07:16:04 +00:00
return { ' data ' : self . data }
else :
2012-09-07 21:11:25 +00:00
return { ' initial ' : self . data }
2011-11-28 23:39:06 +00:00
2012-08-31 07:16:04 +00:00
def get_context_data ( self , * * kwargs ) :
""" set up the pledge page """
2012-03-15 21:54:38 +00:00
2012-08-31 07:16:04 +00:00
context = super ( PledgeView , self ) . get_context_data ( * * kwargs )
2012-10-02 13:18:44 +00:00
context [ ' nonprofit ' ] = settings . NONPROFIT
2012-08-31 07:16:04 +00:00
2012-05-25 22:44:28 +00:00
context . update ( {
2012-08-31 07:16:04 +00:00
' work ' : self . work ,
' campaign ' : self . campaign ,
' premiums ' : self . premiums ,
' premium_id ' : self . data [ ' premium_id ' ] ,
' faqmenu ' : ' modify ' if self . transaction else ' pledge ' ,
' transaction ' : self . transaction ,
' tid ' : self . transaction . id if self . transaction else None ,
2013-02-07 20:25:14 +00:00
' cover_width ' : cover_width ( self . work )
2012-08-31 07:16:04 +00:00
} )
2012-05-13 19:18:48 +00:00
2011-11-28 23:39:06 +00:00
return context
def form_valid ( self , form ) :
2012-03-21 21:53:33 +00:00
# right now, if there is a non-zero pledge amount, go with that. otherwise, do the pre_approval
2011-11-28 23:39:06 +00:00
2012-08-31 07:16:04 +00:00
p = PaymentManager ( )
if self . transaction :
# modifying the transaction...
assert self . transaction . type == PAYMENT_TYPE_AUTHORIZATION and self . transaction . status == TRANSACTION_STATUS_ACTIVE
status , url = p . modify_transaction ( self . transaction , form . cleaned_data [ " preapproval_amount " ] ,
paymentReason = " Unglue.it Pledge for {0} " . format ( self . campaign . name ) ,
2012-09-07 13:46:38 +00:00
pledge_extra = form . pledge_extra
2012-08-31 07:16:04 +00:00
)
logger . info ( " status: {0} , url: {1} " . format ( status , url ) )
2012-01-10 20:16:04 +00:00
2012-08-31 07:16:04 +00:00
if status and url is not None :
logger . info ( " PledgeView (Modify): " + url )
return HttpResponseRedirect ( url )
elif status and url is None :
2012-09-07 21:48:48 +00:00
return HttpResponseRedirect ( " {0} ?tid= {1} " . format ( reverse ( ' pledge_modified ' ) , self . transaction . id ) )
2012-08-31 07:16:04 +00:00
else :
return HttpResponse ( " No modification made " )
2011-11-28 23:39:06 +00:00
else :
2012-08-31 07:16:04 +00:00
t , url = p . process_transaction ( ' USD ' , form . cleaned_data [ " preapproval_amount " ] ,
2012-09-19 00:01:07 +00:00
host = PAYMENT_HOST_NONE ,
2012-08-31 07:16:04 +00:00
campaign = self . campaign ,
user = self . request . user ,
paymentReason = " Unglue.it Pledge for {0} " . format ( self . campaign . name ) ,
2012-09-07 13:46:38 +00:00
pledge_extra = form . pledge_extra
2012-08-31 07:16:04 +00:00
)
if url :
logger . info ( " PledgeView url: " + url )
return HttpResponseRedirect ( url )
else :
logger . error ( " Attempt to produce transaction id {0} failed " . format ( t . id ) )
return HttpResponse ( " Our attempt to enable your transaction failed. We have logged this error. " )
2012-01-09 17:36:03 +00:00
2012-09-06 05:01:17 +00:00
class FundPledgeView ( FormView ) :
template_name = " fund_the_pledge.html "
form_class = CCForm
transaction = None
2012-03-19 23:32:37 +00:00
2012-09-06 05:01:17 +00:00
def get_form_kwargs ( self ) :
2012-09-10 20:17:30 +00:00
kwargs = super ( FundPledgeView , self ) . get_form_kwargs ( )
2012-03-19 23:32:37 +00:00
assert self . request . user . is_authenticated ( )
2012-09-06 05:01:17 +00:00
if self . transaction is None :
self . transaction = get_object_or_404 ( Transaction , id = self . kwargs [ " t_id " ] )
2012-10-13 17:45:46 +00:00
2012-09-10 20:17:30 +00:00
if kwargs . has_key ( ' data ' ) :
data = kwargs [ ' data ' ] . copy ( )
2012-03-21 21:53:33 +00:00
else :
2012-09-10 20:17:30 +00:00
data = { }
2012-03-19 23:32:37 +00:00
2012-09-10 20:17:30 +00:00
data . update (
{ ' preapproval_amount ' : self . transaction . max_amount ,
2012-09-06 05:01:17 +00:00
' username ' : self . request . user . username ,
' work_id ' : self . transaction . campaign . work . id ,
2012-09-10 20:17:30 +00:00
' title ' : self . transaction . campaign . work . title }
)
2012-03-19 23:32:37 +00:00
2012-09-10 20:17:30 +00:00
kwargs [ ' data ' ] = data
2012-03-19 23:32:37 +00:00
2012-09-10 20:17:30 +00:00
return kwargs
2012-09-06 05:01:17 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( FundPledgeView , self ) . get_context_data ( * * kwargs )
2012-09-06 20:55:32 +00:00
context [ ' modified ' ] = self . transaction . status == TRANSACTION_STATUS_MODIFIED
2012-09-06 05:01:17 +00:00
context [ ' preapproval_amount ' ] = self . transaction . max_amount
2012-09-06 20:55:32 +00:00
context [ ' needed ' ] = self . transaction . max_amount - self . request . user . credit . available
2012-09-06 05:01:17 +00:00
context [ ' transaction ' ] = self . transaction
context [ ' nonprofit ' ] = settings . NONPROFIT
2012-09-11 22:17:37 +00:00
context [ ' STRIPE_PK ' ] = stripelib . STRIPE_PK
2012-09-06 20:55:32 +00:00
# note that get_form_kwargs() will already have been called once
2012-09-07 13:39:36 +00:00
donate_args = self . get_form_kwargs ( )
donate_args [ ' data ' ] [ ' preapproval_amount ' ] = context [ ' needed ' ]
context [ ' donate_form ' ] = DonateForm ( * * donate_args )
2012-03-19 23:32:37 +00:00
return context
2012-09-10 20:17:30 +00:00
def post ( self , request , * args , * * kwargs ) :
logger . info ( ' request.POST: {0} ' . format ( request . POST ) )
return super ( FundPledgeView , self ) . post ( request , * args , * * kwargs )
2012-03-22 19:09:13 +00:00
2012-03-19 23:32:37 +00:00
def form_valid ( self , form ) :
2012-09-11 22:17:37 +00:00
""" note desire to pledge; make sure there is a credit card to charge """
2012-09-11 22:53:39 +00:00
2012-10-13 17:40:36 +00:00
if self . transaction . user . id != self . request . user . id :
# trouble!
2012-10-15 02:47:40 +00:00
return render ( self . request , " pledge_user_error.html " , { ' transaction ' : self . transaction } )
2012-09-11 22:53:39 +00:00
2012-09-22 00:40:33 +00:00
p = PaymentManager ( )
2012-10-13 17:45:46 +00:00
# if the user has active account, use it. Otherwise...
if not self . request . user . profile . account :
stripe_token = form . cleaned_data [ " stripe_token " ]
# if we get a stripe_token, create a new stripe account for the user
if stripe_token :
try :
p . make_account ( user = self . request . user , host = settings . PAYMENT_PROCESSOR , token = stripe_token )
except baseprocessor . ProcessorError as e :
2012-11-14 19:51:32 +00:00
return render ( self . request , " pledge_card_error.html " , { ' transaction ' : self . transaction , ' exception ' : e } )
else : # empty token
e = baseprocessor . ProcessorError ( " Empty token " )
return render ( self . request , " pledge_card_error.html " , { ' transaction ' : self . transaction , ' exception ' : e } )
2012-10-13 17:45:46 +00:00
self . transaction . host = settings . PAYMENT_PROCESSOR
preapproval_amount = form . cleaned_data [ " preapproval_amount " ]
2012-09-24 23:29:20 +00:00
# with the Account in hand, now authorize transaction
2012-10-13 17:38:39 +00:00
self . transaction . max_amount = preapproval_amount
2012-10-13 17:45:46 +00:00
t , url = p . authorize ( self . transaction )
2012-09-22 00:40:33 +00:00
logger . info ( " t, url: {0} {1} " . format ( t , url ) )
2012-09-25 18:52:56 +00:00
# redirecting user to pledge_complete on successful preapproval (in the case of stripe)
if url is not None :
return HttpResponseRedirect ( url )
2012-10-13 04:46:34 +00:00
else :
2012-10-15 02:47:40 +00:00
return render ( self . request , " pledge_card_error.html " , { ' transaction ' : self . transaction } )
2012-03-19 23:32:37 +00:00
2012-09-06 05:01:17 +00:00
class NonprofitCampaign ( FormView ) :
template_name = " nonprofit.html "
form_class = CCForm
def get_context_data ( self , * * kwargs ) :
context = super ( NonprofitCampaign , self ) . get_context_data ( * * kwargs )
context [ ' nonprofit ' ] = settings . NONPROFIT
context [ ' get ' ] = self . request . GET
return context
def get_form_kwargs ( self ) :
if self . request . method == ' POST ' :
return { ' data ' : self . request . POST }
2012-03-19 23:32:37 +00:00
else :
2012-09-06 05:01:17 +00:00
return { ' initial ' : self . request . GET }
2012-03-19 23:32:37 +00:00
2012-09-06 05:01:17 +00:00
2012-03-19 23:32:37 +00:00
2012-09-06 05:01:17 +00:00
def form_valid ( self , form ) :
username = form . cleaned_data [ ' username ' ]
forward = { ' username ' : username }
forward [ ' work_id ' ] = form . cleaned_data [ ' work_id ' ]
2012-09-06 15:36:13 +00:00
amount = form . cleaned_data [ ' preapproval_amount ' ]
forward [ ' cents ' ] = int ( 100 * ( amount - int ( amount ) ) )
forward [ ' amount ' ] = int ( amount )
2012-09-06 05:01:17 +00:00
forward [ ' sent ' ] = Sent . objects . create ( user = username , amount = form . cleaned_data [ ' preapproval_amount ' ] ) . pk
token = signing . dumps ( forward )
2013-03-09 18:29:03 +00:00
return HttpResponseRedirect ( settings . BASE_URL_SECURE + reverse ( ' donation_credit ' , kwargs = { ' token ' : token } ) )
2012-07-10 20:36:32 +00:00
2012-09-06 05:01:17 +00:00
class DonationCredit ( TemplateView ) :
template_name = " donation_credit.html "
2012-07-10 20:36:32 +00:00
2012-09-06 05:01:17 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( DonationCredit , self ) . get_context_data ( * * kwargs )
2012-09-06 18:04:47 +00:00
context [ ' faqmenu ' ] = " donation "
2012-09-06 20:55:32 +00:00
context [ ' nonprofit ' ] = settings . NONPROFIT
2012-09-06 05:01:17 +00:00
try :
envelope = signing . loads ( kwargs [ ' token ' ] )
context [ ' envelope ' ] = envelope
except signing . BadSignature :
self . template_name = " donation_error.html "
return context
try :
work = models . Work . objects . get ( id = envelope [ ' work_id ' ] )
campaign = work . last_campaign ( )
except models . Work . DoesNotExist :
campaign = None
context [ ' work ' ] = work
try :
user = User . objects . get ( username = envelope [ ' username ' ] )
except User . DoesNotExist :
self . template_name = " donation_user_error.html "
context [ ' error ' ] = ' user does not exist '
return context
if user != self . request . user :
self . template_name = " donation_user_error.html "
context [ ' error ' ] = ' wrong user logged in '
return context
try :
# check token not used
CreditLog . objects . get ( sent = envelope [ ' sent ' ] )
context [ ' error ' ] = ' credit already registered '
return context
except CreditLog . DoesNotExist :
#not used yet!
2012-09-06 15:36:13 +00:00
amount = envelope [ ' amount ' ] + envelope [ ' cents ' ] / D ( 100 )
CreditLog . objects . create ( user = user , amount = amount , action = ' deposit ' , sent = envelope [ ' sent ' ] )
2012-09-06 20:55:32 +00:00
ts = Transaction . objects . filter ( user = user , campaign = campaign , status = TRANSACTION_STATUS_NONE ) . order_by ( ' -pk ' )
if ts . count ( ) == 0 :
ts = Transaction . objects . filter ( user = user , campaign = campaign , status = TRANSACTION_STATUS_MODIFIED ) . order_by ( ' -pk ' )
2012-09-06 05:01:17 +00:00
if ts . count ( ) > 0 :
t = ts [ 0 ]
2012-09-06 15:36:13 +00:00
credit_transaction ( t , user , amount )
2012-09-06 05:01:17 +00:00
for t in ts [ 1 : ] :
t . status = TRANSACTION_STATUS_CANCELED
t . save ( )
context [ ' transaction ' ] = t
return context
else :
2012-09-06 15:36:13 +00:00
user . credit . add_to_balance ( amount )
2012-09-06 05:01:17 +00:00
return context
2012-07-10 20:36:32 +00:00
class PledgeRechargeView ( TemplateView ) :
"""
a view to allow for recharge of a transaction for failed transactions or ones with errors
"""
template_name = " pledge_recharge.html "
def get_context_data ( self , * * kwargs ) :
2012-07-12 02:51:36 +00:00
context = super ( PledgeRechargeView , self ) . get_context_data ( * * kwargs )
2012-07-10 20:36:32 +00:00
2012-08-31 07:16:04 +00:00
# the following should be true since PledgeView.as_view is wrapped in login_required
2012-07-10 20:36:32 +00:00
assert self . request . user . is_authenticated ( )
user = self . request . user
work = get_object_or_404 ( models . Work , id = self . kwargs [ " work_id " ] )
2012-07-13 17:17:51 +00:00
campaign = work . last_campaign ( )
if campaign is None :
return Http404
transaction = campaign . transaction_to_recharge ( user )
# calculate a URL to do a preapproval -- in the future, we may want to do a straight up payment
2012-07-13 22:55:41 +00:00
return_url = None
nevermind_url = None
2012-07-10 20:36:32 +00:00
2012-07-13 22:55:41 +00:00
if transaction is not None :
2012-09-07 13:46:38 +00:00
# the recipients of this authorization is not specified here but rather by the PaymentManager.
2012-07-13 22:55:41 +00:00
paymentReason = " Unglue.it Recharge for {0} " . format ( campaign . name )
2012-08-31 07:16:04 +00:00
p = PaymentManager ( )
2012-09-07 13:46:38 +00:00
t , url = p . authorize ( transaction , return_url = return_url , paymentReason = paymentReason )
2012-07-13 22:55:41 +00:00
logger . info ( " Recharge url: {0} " . format ( url ) )
else :
url = None
2012-07-10 20:36:32 +00:00
context . update ( {
' work ' : work ,
2012-07-13 17:17:51 +00:00
' transaction ' : transaction ,
2012-07-13 22:55:41 +00:00
' payment_processor ' : transaction . host if transaction is not None else None ,
' recharge_url ' : url
2012-07-10 20:36:32 +00:00
} )
return context
2012-01-09 17:36:03 +00:00
class PledgeCompleteView ( TemplateView ) :
2012-01-11 01:15:39 +00:00
""" A callback for PayPal to tell unglue.it that a payment transaction has completed successfully.
Possible things to implement :
2012-03-19 23:32:37 +00:00
after pledging , supporter receives email including thanks , work pledged , amount , expiry date , any next steps they should expect ; others ?
study other confirmation emails for their contents
should note that a confirmation email has been sent to $ email from $ sender
should briefly note next steps ( e . g . if this campaign succeeds you will be emailed on date X )
2012-01-11 01:15:39 +00:00
"""
2012-01-09 17:36:03 +00:00
template_name = " pledge_complete.html "
2012-01-10 20:16:04 +00:00
def get_context_data ( self ) :
2012-01-09 17:36:03 +00:00
# pick up all get and post parameters and display
2012-01-10 20:16:04 +00:00
context = super ( PledgeCompleteView , self ) . get_context_data ( )
2012-01-09 17:36:03 +00:00
2012-01-11 01:15:39 +00:00
if self . request . user . is_authenticated ( ) :
user = self . request . user
else :
user = None
# pull out the transaction id and try to get the corresponding Transaction
transaction_id = self . request . REQUEST . get ( " tid " )
transaction = Transaction . objects . get ( id = transaction_id )
# work and campaign in question
try :
campaign = transaction . campaign
work = campaign . work
except Exception , e :
campaign = None
work = None
# we need to check whether the user tied to the transaction is indeed the authenticated user.
try :
2012-09-07 21:48:48 +00:00
if user . id != transaction . user . id :
2012-03-19 18:46:41 +00:00
# should be 403 -- but let's try 404 for now -- 403 exception coming in Django 1.4
raise Http404
2012-01-11 01:15:39 +00:00
except Exception , e :
2012-03-19 18:46:41 +00:00
raise Http404
2012-01-11 01:15:39 +00:00
# check that the user had not already approved the transaction
# do we need to first run PreapprovalDetails to check on the status
# is it of type=PAYMENT_TYPE_AUTHORIZATION and status is NONE or ACTIVE (but approved is false)
2012-01-09 17:36:03 +00:00
2012-01-11 01:15:39 +00:00
if transaction . type == PAYMENT_TYPE_AUTHORIZATION :
correct_transaction_type = True
else :
correct_transaction_type = False
2012-03-16 20:03:38 +00:00
# add the work corresponding to the Transaction on the user's wishlist if it's not already on the wishlist
2012-10-16 14:41:30 +00:00
# fire add-wishlist notification if needed
2012-09-07 21:48:48 +00:00
if user is not None and correct_transaction_type and ( campaign is not None ) and ( work is not None ) :
2012-03-16 20:03:38 +00:00
# ok to overwrite Wishes.source?
2012-10-16 15:36:51 +00:00
user . wishlist . add_work ( work , ' pledging ' , notify = True )
2012-03-26 19:26:47 +00:00
2012-05-01 17:49:23 +00:00
worklist = slideshow ( 8 )
works = worklist [ : 4 ]
works2 = worklist [ 4 : 8 ]
2012-03-26 19:26:47 +00:00
2012-01-11 01:15:39 +00:00
context [ " transaction " ] = transaction
context [ " work " ] = work
context [ " campaign " ] = campaign
2012-02-21 14:24:23 +00:00
context [ " faqmenu " ] = " complete "
2012-03-26 19:26:47 +00:00
context [ " works " ] = works
2012-05-13 02:42:09 +00:00
context [ " works2 " ] = works2
2012-05-14 20:56:36 +00:00
context [ " site " ] = Site . objects . get_current ( )
2012-01-11 01:15:39 +00:00
return context
2012-09-07 21:48:48 +00:00
class PledgeModifiedView ( PledgeCompleteView ) :
def get_context_data ( self ) :
context = super ( PledgeModifiedView , self ) . get_context_data ( )
context [ ' modified ' ] = True
return context
2012-01-09 17:36:03 +00:00
2012-05-21 14:56:18 +00:00
class PledgeCancelView ( FormView ) :
""" A view for allowing a user to cancel the active transaction for specified campaign """
2012-01-09 17:36:03 +00:00
template_name = " pledge_cancel.html "
2012-05-21 14:56:18 +00:00
form_class = PledgeCancelForm
2012-01-09 17:36:03 +00:00
2012-05-21 14:56:18 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( PledgeCancelView , self ) . get_context_data ( * * kwargs )
2012-05-18 23:59:48 +00:00
2012-05-23 14:22:48 +00:00
# initialize error to be None
context [ " error " ] = None
2012-05-18 23:59:48 +00:00
2012-05-21 14:56:18 +00:00
# the following should be true since PledgeCancelView.as_view is wrapped in login_required
2012-05-23 14:22:48 +00:00
if self . request . user . is_authenticated ( ) :
user = self . request . user
else :
2012-05-25 01:47:50 +00:00
context [ " error " ] = " You are not logged in. "
2012-05-23 14:22:48 +00:00
return context
2012-05-18 23:59:48 +00:00
2012-05-21 14:56:18 +00:00
campaign = get_object_or_404 ( models . Campaign , id = self . kwargs [ " campaign_id " ] )
2012-05-23 14:22:48 +00:00
if campaign . status != ' ACTIVE ' :
context [ " error " ] = " {0} is not an active campaign " . format ( campaign )
return context
2012-05-21 14:56:18 +00:00
work = campaign . work
transactions = campaign . transactions ( ) . filter ( user = user , status = TRANSACTION_STATUS_ACTIVE )
2012-05-23 14:22:48 +00:00
if transactions . count ( ) < 1 :
2012-05-25 01:47:50 +00:00
context [ " error " ] = " You don ' t have an active transaction for this campaign. "
2012-05-23 14:22:48 +00:00
return context
elif transactions . count ( ) > 1 :
2012-05-25 01:47:50 +00:00
logger . error ( " User {0} has {1} active transactions for campaign id {2} " . format ( user , transactions . count ( ) , campaign . id ) )
2012-05-23 14:22:48 +00:00
context [ " error " ] = " You have {0} active transactions for this campaign " . format ( transactions . count ( ) )
return context
2012-05-21 14:56:18 +00:00
transaction = transactions [ 0 ]
2012-05-23 14:22:48 +00:00
if transaction . type != PAYMENT_TYPE_AUTHORIZATION :
2012-05-25 01:47:50 +00:00
logger . error ( " Transaction id {0} transaction type, which should be {1} , is actually {2} " . format ( transaction . id , PAYMENT_TYPE_AUTHORIZATION , transaction . type ) )
2012-05-23 14:22:48 +00:00
context [ " error " ] = " Your transaction type, which should be {0} , is actually {1} " . format ( PAYMENT_TYPE_AUTHORIZATION , transaction . type )
return context
# we've located the transaction, work, and campaign referenced in the view
2012-05-18 23:59:48 +00:00
context [ " transaction " ] = transaction
context [ " work " ] = work
context [ " campaign " ] = campaign
context [ " faqmenu " ] = " cancel "
return context
2012-05-23 14:22:48 +00:00
def form_valid ( self , form ) :
# check that user does, in fact, have an active transaction for specified campaign
logger . info ( " arrived at pledge_cancel form_valid " )
# pull campaign_id from form, not from URI as we do from GET
campaign_id = self . request . REQUEST . get ( ' campaign_id ' )
2012-05-25 01:47:50 +00:00
# this following logic should be extraneous.
if self . request . user . is_authenticated ( ) :
user = self . request . user
else :
return HttpResponse ( " You need to be logged in. " )
2012-05-23 14:22:48 +00:00
try :
2012-05-23 16:12:21 +00:00
# look up the specified campaign and attempt to pull up the appropriate transaction
# i.e., the transaction actually belongs to user, that the transaction is active
2012-05-23 14:22:48 +00:00
campaign = get_object_or_404 ( models . Campaign , id = self . kwargs [ " campaign_id " ] , status = ' ACTIVE ' )
transaction = campaign . transaction_set . get ( user = user , status = TRANSACTION_STATUS_ACTIVE ,
type = PAYMENT_TYPE_AUTHORIZATION )
2012-05-23 16:12:21 +00:00
# attempt to cancel the transaction and redirect to the Work page if cancel is successful
2012-05-23 14:22:48 +00:00
# here's a place that would be nice to use https://docs.djangoproject.com/en/dev/ref/contrib/messages/
2012-05-23 16:12:21 +00:00
# to display the success or failure of the cancel operation as a popup in the context of the work page
2012-05-23 14:22:48 +00:00
p = PaymentManager ( )
result = p . cancel_transaction ( transaction )
2012-05-25 01:47:50 +00:00
# put a notification here for pledge cancellation?
2012-05-23 16:12:21 +00:00
if result :
# Now if we redirect the user to the Work page and the IPN hasn't arrived, the status of the
# transaction might be out of date. Let's try an explicit polling of the transaction result before redirecting
# We might want to remove this in a production system
if settings . DEBUG :
update_status = p . update_preapproval ( transaction )
2012-06-15 20:14:26 +00:00
# send a notice out that the transaction has been canceled -- leverage the pledge_modify notice for now
# BUGBUG: should have a pledge cancel notice actually since I think it's different
from regluit . payment . signals import pledge_modified
pledge_modified . send ( sender = self , transaction = transaction , up_or_down = " canceled " )
logger . info ( " pledge_modified notice for cancellation: sender {0} , transaction {1} " . format ( self , transaction ) )
2012-05-23 16:12:21 +00:00
return HttpResponseRedirect ( reverse ( ' work ' , kwargs = { ' work_id ' : campaign . work . id } ) )
else :
2012-05-25 01:47:50 +00:00
logger . error ( " Attempt to cancel transaction id {0} failed " . format ( transaction . id ) )
return HttpResponse ( " Our attempt to cancel your transaction failed. We have logged this error. " )
except Exception , e :
logger . error ( " Exception from attempt to cancel pledge for campaign id {0} for username {1} : {2} " . format ( campaign_id , user . username , e ) )
2012-09-07 13:46:38 +00:00
return HttpResponse ( " Sorry, something went wrong in canceling your campaign pledge. We have logged this error. " )
2011-12-03 00:37:27 +00:00
2011-11-16 05:22:22 +00:00
def claim ( request ) :
if request . method == ' GET ' :
data = request . GET
else :
data = request . POST
2012-03-23 01:24:12 +00:00
form = UserClaimForm ( request . user , data = data , prefix = ' claim ' )
2011-11-16 05:22:22 +00:00
if form . is_valid ( ) :
2011-11-23 16:06:48 +00:00
# make sure we're not creating a duplicate claim
2012-10-07 14:58:59 +00:00
if not models . Claim . objects . filter ( work = form . cleaned_data [ ' work ' ] , rights_holder = form . cleaned_data [ ' rights_holder ' ] ) . exclude ( status = ' release ' ) . count ( ) :
2011-11-16 05:22:22 +00:00
form . save ( )
2012-10-07 14:58:59 +00:00
return HttpResponseRedirect ( reverse ( ' work ' , kwargs = { ' work_id ' : form . cleaned_data [ ' work ' ] . id } ) )
2011-11-16 05:22:22 +00:00
else :
2012-10-07 14:58:59 +00:00
try :
work = models . Work . objects . get ( id = data [ ' claim-work ' ] )
except models . Work . DoesNotExist :
try :
work = models . WasWork . objects . get ( was = data [ ' claim-work ' ] ) . work
except models . WasWork . DoesNotExist :
raise Http404
2012-03-23 01:24:12 +00:00
rights_holder = models . RightsHolder . objects . get ( id = data [ ' claim-rights_holder ' ] )
2012-04-05 20:55:10 +00:00
active_claims = work . claim . exclude ( status = ' release ' )
context = { ' form ' : form , ' work ' : work , ' rights_holder ' : rights_holder , ' active_claims ' : active_claims }
2011-11-16 05:22:22 +00:00
return render ( request , " claim.html " , context )
2012-10-07 14:58:59 +00:00
2011-11-16 05:22:22 +00:00
2011-11-20 02:12:18 +00:00
def rh_tools ( request ) :
if not request . user . is_authenticated ( ) :
return render ( request , " rh_tools.html " )
claims = request . user . claim . filter ( user = request . user )
campaign_form = " xxx "
if not claims :
return render ( request , " rh_tools.html " )
for claim in claims :
2012-04-07 18:12:54 +00:00
if claim . status == ' active ' :
claim . campaigns = claim . work . campaigns . all ( )
else :
claim . campaigns = [ ]
2011-11-20 02:12:18 +00:00
for campaign in claim . campaigns :
2011-11-22 05:28:06 +00:00
if campaign . status in [ ' ACTIVE ' , ' INITIALIZED ' ] :
2012-04-03 19:50:02 +00:00
if request . method == ' POST ' and request . POST . has_key ( ' edit_managers_ %s ' % campaign . id ) :
campaign . edit_managers_form = EditManagersForm ( instance = campaign , data = request . POST , prefix = campaign . id )
if campaign . edit_managers_form . is_valid ( ) :
campaign . edit_managers_form . save ( )
2012-04-07 18:12:54 +00:00
campaign . edit_managers_form = EditManagersForm ( instance = campaign , prefix = campaign . id )
2012-04-03 19:50:02 +00:00
else :
campaign . edit_managers_form = EditManagersForm ( instance = campaign , prefix = campaign . id )
2012-09-28 21:44:08 +00:00
if claim . can_open_new :
2012-04-05 21:53:00 +00:00
if request . method == ' POST ' and request . POST . has_key ( ' work ' ) and int ( request . POST [ ' work ' ] ) == claim . work . id :
2011-11-20 02:12:18 +00:00
claim . campaign_form = OpenCampaignForm ( request . POST )
if claim . campaign_form . is_valid ( ) :
2011-11-29 04:37:17 +00:00
new_campaign = claim . campaign_form . save ( commit = False )
2012-03-07 19:42:16 +00:00
new_campaign . deadline = date_today ( ) + timedelta ( days = int ( settings . UNGLUEIT_LONGEST_DEADLINE ) )
2011-11-29 04:37:17 +00:00
new_campaign . target = D ( settings . UNGLUEIT_MINIMUM_TARGET )
new_campaign . save ( )
claim . campaign_form . save_m2m ( )
2011-11-20 02:12:18 +00:00
else :
2012-05-07 21:32:45 +00:00
claim . campaign_form = OpenCampaignForm ( data = { ' work ' : claim . work , ' name ' : claim . work . title , ' userid ' : request . user . id , ' managers_1 ' : request . user . id } )
2012-09-21 16:10:13 +00:00
campaigns = request . user . campaigns . all ( )
new_campaign = None
for campaign in campaigns :
if campaign . clonable ( ) :
if request . method == ' POST ' and request . POST . has_key ( ' c %s -campaign_id ' % campaign . id ) :
clone_form = CloneCampaignForm ( data = request . POST , prefix = ' c %s ' % campaign . id )
if clone_form . is_valid ( ) :
2012-09-21 17:54:59 +00:00
campaign . clone ( )
2012-09-21 16:10:13 +00:00
else :
campaign . clone_form = CloneCampaignForm ( initial = { ' campaign_id ' : campaign . id } , prefix = ' c %s ' % campaign . id )
return render ( request , " rh_tools.html " , { ' claims ' : claims , ' campaigns ' : campaigns } )
2011-11-20 02:12:18 +00:00
2011-11-15 04:28:55 +00:00
def rh_admin ( request ) :
2011-11-19 00:50:47 +00:00
if not request . user . is_authenticated ( ) :
return render ( request , " admins_only.html " )
2011-11-21 20:08:15 +00:00
if not request . user . is_staff :
2011-11-15 04:28:55 +00:00
return render ( request , " admins_only.html " )
2011-11-17 19:35:29 +00:00
PendingFormSet = modelformset_factory ( models . Claim , fields = [ ' status ' ] , extra = 0 )
pending_data = models . Claim . objects . filter ( status = ' pending ' )
active_data = models . Claim . objects . filter ( status = ' active ' )
2011-11-15 04:28:55 +00:00
if request . method == ' POST ' :
2011-11-17 19:35:29 +00:00
if ' create_rights_holder ' in request . POST . keys ( ) :
form = RightsHolderForm ( data = request . POST )
pending_formset = PendingFormSet ( queryset = pending_data )
if form . is_valid ( ) :
form . save ( )
2012-04-07 19:31:11 +00:00
form = RightsHolderForm ( )
2011-11-17 19:35:29 +00:00
if ' set_claim_status ' in request . POST . keys ( ) :
pending_formset = PendingFormSet ( request . POST , request . FILES , queryset = pending_data )
form = RightsHolderForm ( )
if pending_formset . is_valid ( ) :
pending_formset . save ( )
2011-11-20 02:12:18 +00:00
pending_formset = PendingFormSet ( queryset = pending_data )
2011-11-15 04:28:55 +00:00
else :
form = RightsHolderForm ( )
2011-11-17 19:35:29 +00:00
pending_formset = PendingFormSet ( queryset = pending_data )
2011-11-15 04:28:55 +00:00
rights_holders = models . RightsHolder . objects . all ( )
2011-11-17 19:35:29 +00:00
2011-11-16 19:45:37 +00:00
context = {
' request ' : request ,
' rights_holders ' : rights_holders ,
' form ' : form ,
2011-11-17 19:35:29 +00:00
' pending ' : zip ( pending_data , pending_formset ) ,
' pending_formset ' : pending_formset ,
' active_data ' : active_data ,
2011-11-16 19:45:37 +00:00
}
2011-11-15 04:28:55 +00:00
return render ( request , " rights_holders.html " , context )
2011-12-20 22:42:06 +00:00
def campaign_admin ( request ) :
if not request . user . is_authenticated ( ) :
return render ( request , " admins_only.html " )
if not request . user . is_staff :
return render ( request , " admins_only.html " )
context = { }
2011-12-21 22:32:08 +00:00
def campaigns_types ( ) :
# pull out Campaigns with Transactions that are ACTIVE -- and hence can be executed
# Campaign.objects.filter(transaction__status='ACTIVE')
2012-04-25 17:55:30 +00:00
campaigns_with_active_transactions = models . Campaign . objects . filter ( transaction__status = TRANSACTION_STATUS_ACTIVE )
2011-12-21 22:32:08 +00:00
# pull out Campaigns with Transactions that are INCOMPLETE
2012-04-25 17:55:30 +00:00
campaigns_with_incomplete_transactions = models . Campaign . objects . filter ( transaction__status = TRANSACTION_STATUS_INCOMPLETE )
2011-12-21 22:32:08 +00:00
# show all Campaigns with Transactions that are COMPLETED
2012-05-04 14:30:05 +00:00
campaigns_with_completed_transactions = models . Campaign . objects . filter ( transaction__status = TRANSACTION_STATUS_COMPLETE )
2011-12-21 22:32:08 +00:00
# show Campaigns with Transactions that are CANCELED
2012-04-25 20:10:53 +00:00
campaigns_with_canceled_transactions = models . Campaign . objects . filter ( transaction__status = TRANSACTION_STATUS_CANCELED )
2011-12-21 22:32:08 +00:00
2012-04-25 20:10:53 +00:00
return ( campaigns_with_active_transactions , campaigns_with_incomplete_transactions , campaigns_with_completed_transactions , campaigns_with_canceled_transactions )
2011-12-21 22:32:08 +00:00
2011-12-20 22:42:06 +00:00
form = CampaignAdminForm ( )
2011-12-21 22:32:08 +00:00
pm = PaymentManager ( )
check_status_results = None
command_status = None
2011-12-20 22:42:06 +00:00
if request . method == ' GET ' :
2011-12-21 22:32:08 +00:00
pass
2011-12-20 22:42:06 +00:00
elif request . method == ' POST ' :
2011-12-21 22:32:08 +00:00
if ' campaign_checkstatus ' in request . POST . keys ( ) :
# campaign_checkstatus
try :
2011-12-23 01:34:24 +00:00
status = pm . checkStatus ( )
check_status_results = " "
# parse the output to display chat transaction statuses have been updated
if len ( status [ " preapprovals " ] ) :
for t in status [ " preapprovals " ] :
check_status_results + = " <p>Preapproval key: %s updated</p> " % ( t [ " key " ] )
else :
check_status_results + = " <p>No preapprovals needed updating</p> "
if len ( status [ " payments " ] ) :
for t in status [ " payments " ] :
info = " , " . join ( [ " %s : %s " % ( k , v ) for ( k , v ) in t . items ( ) ] )
check_status_results + = " <p>Payment updated: %s </p> " % ( info )
else :
check_status_results + = " <p>No payments needed updating</p> "
command_status = _ ( " Transactions updated based on PaymentDetails and PreapprovalDetails " )
2011-12-21 22:32:08 +00:00
except Exception , e :
check_status_results = e
2011-12-23 14:59:07 +00:00
elif ' execute_campaigns ' in request . POST . keys ( ) :
c_id = request . POST . get ( ' active_campaign ' , None )
if c_id is not None :
try :
campaign = models . Campaign . objects . get ( id = c_id )
results = pm . execute_campaign ( campaign )
command_status = str ( results )
except Exception , e :
command_status = " Error in executing transactions for campaign %s " % ( str ( e ) )
2011-12-21 22:32:08 +00:00
elif ' finish_campaigns ' in request . POST . keys ( ) :
2011-12-23 14:59:07 +00:00
c_id = request . POST . get ( ' incomplete_campaign ' , None )
if c_id is not None :
try :
campaign = models . Campaign . objects . get ( id = c_id )
results = pm . finish_campaign ( campaign )
command_status = str ( results )
except Exception , e :
command_status = " Error in finishing transactions for campaign %s " % ( str ( e ) )
2011-12-21 22:32:08 +00:00
elif ' cancel_campaigns ' in request . POST . keys ( ) :
2011-12-23 14:59:07 +00:00
c_id = request . POST . get ( ' active_campaign ' , None )
if c_id is not None :
try :
campaign = models . Campaign . objects . get ( id = c_id )
results = pm . cancel_campaign ( campaign )
command_status = str ( results )
except Exception , e :
command_status = " Error in canceling transactions for campaign %s " % ( str ( e ) )
2011-12-21 01:36:27 +00:00
2011-12-21 22:32:08 +00:00
( campaigns_with_active_transactions , campaigns_with_incomplete_transactions , campaigns_with_completed_transactions ,
campaigns_with_canceled_transactions ) = campaigns_types ( )
2011-12-20 22:42:06 +00:00
context . update ( {
' form ' : form ,
2011-12-21 01:36:27 +00:00
' check_status_results ' : check_status_results ,
' campaigns_with_active_transactions ' : campaigns_with_active_transactions ,
' campaigns_with_incomplete_transactions ' : campaigns_with_incomplete_transactions ,
2011-12-21 22:32:08 +00:00
' campaigns_with_completed_transactions ' : campaigns_with_completed_transactions ,
' campaigns_with_canceled_transactions ' : campaigns_with_canceled_transactions ,
' command_status ' : command_status
2011-12-20 22:42:06 +00:00
} )
2011-12-21 22:32:08 +00:00
2011-12-20 22:42:06 +00:00
return render ( request , " campaign_admin.html " , context )
2011-11-15 04:28:55 +00:00
2011-11-03 20:28:53 +00:00
def supporter ( request , supporter_username , template_name ) :
2011-10-19 07:13:29 +00:00
supporter = get_object_or_404 ( User , username = supporter_username )
wishlist = supporter . wishlist
2012-03-07 18:23:34 +00:00
works = [ ]
works2 = [ ]
works_unglued = [ ]
works_active = [ ]
works_wished = [ ]
2012-12-31 18:46:23 +00:00
works_on_wishlist = wishlist . works . all ( )
2012-02-22 03:00:23 +00:00
2012-12-31 18:46:23 +00:00
if ( works_on_wishlist ) :
2012-03-07 18:23:34 +00:00
# querysets for tabs
2012-12-31 18:46:23 +00:00
# unglued tab is anything with an existing ebook or successful campaign
2012-03-07 18:23:34 +00:00
## .order_by() may clash with .distinct() and this should be fixed
2012-12-31 18:46:23 +00:00
unglueit_works = works_on_wishlist . filter ( campaigns__status = " SUCCESSFUL " ) . distinct ( )
works_otherwise_available = works_on_wishlist . filter ( editions__ebooks__isnull = False ) . distinct ( )
works_unglued = unglueit_works | works_otherwise_available
works_unglued = works_unglued . order_by ( ' -campaigns__status ' , ' campaigns__deadline ' , ' -num_wishes ' )
works_active = works_on_wishlist . filter ( campaigns__status = ' ACTIVE ' ) . order_by ( ' campaigns__deadline ' ) . distinct ( )
2012-03-07 18:23:34 +00:00
# everything else goes in tab 3
2012-12-31 18:46:23 +00:00
works_wished = works_on_wishlist . exclude ( pk__in = works_active . values_list ( ' pk ' , flat = True ) ) . exclude ( pk__in = works_unglued . values_list ( ' pk ' , flat = True ) ) . order_by ( ' -num_wishes ' )
2012-03-07 18:23:34 +00:00
# badge counts
backed = works_unglued . count ( )
backing = works_active . count ( )
wished = works_wished . count ( )
2012-02-22 03:00:23 +00:00
2012-03-08 14:36:59 +00:00
else :
2012-03-07 18:23:34 +00:00
backed = 0
backing = 0
wished = 0
2012-03-08 14:36:59 +00:00
worklist = slideshow ( 8 )
works = worklist [ : 4 ]
works2 = worklist [ 4 : 8 ]
2012-03-28 13:08:05 +00:00
2012-05-11 18:13:09 +00:00
# default to showing the Active tab if there are active campaigns, else show Wishlist
2012-03-28 13:08:05 +00:00
if backing > 0 :
2012-05-11 18:13:09 +00:00
activetab = " #2 "
2012-12-31 20:20:03 +00:00
elif wished == 0 :
activetab = " #1 "
2012-03-28 13:08:05 +00:00
else :
2012-05-11 18:13:09 +00:00
activetab = " #3 "
2012-02-23 20:40:45 +00:00
2011-10-23 18:40:06 +00:00
# following block to support profile admin form in supporter page
2011-10-19 07:13:29 +00:00
if request . user . is_authenticated ( ) and request . user . username == supporter_username :
2011-11-17 00:47:29 +00:00
2011-11-09 17:24:26 +00:00
try :
profile_obj = request . user . get_profile ( )
except ObjectDoesNotExist :
profile_obj = models . UserProfile ( )
profile_obj . user = request . user
2011-11-17 00:47:29 +00:00
2011-10-19 07:13:29 +00:00
if request . method == ' POST ' :
2011-10-23 18:40:06 +00:00
profile_form = ProfileForm ( data = request . POST , instance = profile_obj )
2011-10-19 07:13:29 +00:00
if profile_form . is_valid ( ) :
2012-01-24 17:36:45 +00:00
if profile_form . cleaned_data [ ' clear_facebook ' ] or profile_form . cleaned_data [ ' clear_twitter ' ] or profile_form . cleaned_data [ ' clear_goodreads ' ] :
2011-11-14 18:23:14 +00:00
if profile_form . cleaned_data [ ' clear_facebook ' ] :
profile_obj . facebook_id = 0
2013-03-18 18:56:27 +00:00
if profile_obj . avatar_source == models . FACEBOOK :
profile_obj . avatar_source = models . GRAVATAR
2011-11-14 18:23:14 +00:00
if profile_form . cleaned_data [ ' clear_twitter ' ] :
profile_obj . twitter_id = " "
2013-03-18 18:56:27 +00:00
if profile_obj . avatar_source == models . TWITTER :
profile_obj . avatar_source = models . GRAVATAR
2012-01-24 17:36:45 +00:00
if profile_form . cleaned_data [ ' clear_goodreads ' ] :
profile_obj . goodreads_user_id = None
profile_obj . goodreads_user_name = None
profile_obj . goodreads_user_link = None
profile_obj . goodreads_auth_token = None
profile_obj . goodreads_auth_secret = None
2011-11-14 18:23:14 +00:00
profile_obj . save ( )
2011-10-19 07:13:29 +00:00
profile_form . save ( )
2011-11-17 00:47:29 +00:00
2011-10-19 07:13:29 +00:00
else :
2011-11-09 17:24:26 +00:00
profile_form = ProfileForm ( instance = profile_obj )
2011-11-17 00:47:29 +00:00
if request . user . profile . goodreads_user_id is not None :
2012-01-24 17:36:45 +00:00
goodreads_id = request . user . profile . goodreads_user_id
2011-11-17 00:47:29 +00:00
else :
2012-01-24 17:36:45 +00:00
goodreads_id = None
2011-11-17 00:47:29 +00:00
if request . user . profile . librarything_id is not None :
librarything_id = request . user . profile . librarything_id
else :
librarything_id = None
2011-10-19 16:55:48 +00:00
else :
profile_form = ' '
2012-01-24 17:36:45 +00:00
goodreads_id = None
2011-11-17 00:47:29 +00:00
librarything_id = None
2011-10-19 07:13:29 +00:00
context = {
2011-10-14 14:18:38 +00:00
" supporter " : supporter ,
" wishlist " : wishlist ,
2012-02-22 03:00:23 +00:00
" works_unglued " : works_unglued ,
" works_active " : works_active ,
" works_wished " : works_wished ,
2012-03-07 18:23:34 +00:00
" works " : works ,
" works2 " : works2 ,
2011-10-14 14:18:38 +00:00
" backed " : backed ,
" backing " : backing ,
" wished " : wished ,
2011-10-19 07:13:29 +00:00
" profile_form " : profile_form ,
2011-11-16 20:45:33 +00:00
" ungluers " : userlists . other_users ( supporter , 5 ) ,
2011-11-17 00:47:29 +00:00
" goodreads_auth_url " : reverse ( ' goodreads_auth ' ) ,
2012-01-24 17:36:45 +00:00
" goodreads_id " : goodreads_id ,
2012-02-23 20:40:45 +00:00
" librarything_id " : librarything_id ,
2012-03-28 13:08:05 +00:00
" activetab " : activetab
2011-10-19 07:13:29 +00:00
}
2011-11-03 20:28:53 +00:00
return render ( request , template_name , context )
2011-10-03 16:36:04 +00:00
def edit_user ( request ) :
if not request . user . is_authenticated ( ) :
2013-03-08 02:48:56 +00:00
return HttpResponseRedirect ( reverse ( ' superlogin ' ) )
2012-04-25 02:20:10 +00:00
form = UserData ( )
2011-10-03 16:36:04 +00:00
if request . method == ' POST ' :
2012-04-25 02:20:10 +00:00
if ' change_username ' in request . POST . keys ( ) :
2012-05-26 21:30:12 +00:00
form = UserData ( request . POST )
form . oldusername = request . user . username
2012-04-25 02:20:10 +00:00
if form . is_valid ( ) : # All validation rules pass, go and change the username
request . user . username = form . cleaned_data [ ' username ' ]
request . user . save ( )
return HttpResponseRedirect ( reverse ( ' home ' ) ) # Redirect after POST
2013-03-13 01:58:15 +00:00
return render ( request , ' registration/user_change_form.html ' , { ' form ' : form } )
2011-10-03 16:36:04 +00:00
2012-10-15 03:41:17 +00:00
class ManageAccount ( FormView ) :
2012-10-14 19:31:18 +00:00
template_name = " manage_account.html "
2012-10-15 03:41:17 +00:00
form_class = PlainCCForm
def get_context_data ( self , * * kwargs ) :
context = super ( ManageAccount , self ) . get_context_data ( * * kwargs )
context [ ' STRIPE_PK ' ] = stripelib . STRIPE_PK
return context
2012-10-14 19:31:18 +00:00
2012-10-15 03:41:17 +00:00
def form_valid ( self , form ) :
""" save the token, make an account """
p = PaymentManager ( )
stripe_token = form . cleaned_data [ " stripe_token " ]
# if we get a stripe_token, create a new stripe account for the user
if stripe_token :
try :
p . make_account ( user = self . request . user , host = settings . PAYMENT_PROCESSOR , token = stripe_token )
except baseprocessor . ProcessorError as e :
2012-10-15 04:42:09 +00:00
return render ( self . request , " pledge_card_error.html " , { ' exception ' : e } )
2012-10-15 04:16:56 +00:00
next = self . request . REQUEST . get ( ' next ' , None )
if next :
return HttpResponseRedirect ( next )
else :
return render ( self . request , self . template_name , self . get_context_data ( ) )
2012-10-15 03:41:17 +00:00
2011-09-29 01:36:47 +00:00
def search ( request ) :
2013-03-30 01:11:01 +00:00
q = request . GET . get ( ' q ' , ' ' )
2012-02-05 00:06:53 +00:00
page = int ( request . GET . get ( ' page ' , 1 ) )
results = gluejar_search ( q , user_ip = request . META [ ' REMOTE_ADDR ' ] , page = page )
2013-03-01 17:07:15 +00:00
2013-03-30 01:11:01 +00:00
if q != ' ' and page == 1 :
2013-03-01 17:07:15 +00:00
work_query = Q ( title__icontains = q ) | Q ( editions__authors__name__icontains = q ) | Q ( subjects__name__iexact = q )
campaign_works = models . Work . objects . exclude ( campaigns = None ) . filter ( work_query ) . distinct ( )
else :
2013-03-19 20:43:23 +00:00
campaign_works = None
2011-09-29 06:23:50 +00:00
2011-10-10 22:08:53 +00:00
# flag search result as on wishlist as appropriate
2011-09-30 01:01:28 +00:00
if not request . user . is_anonymous ( ) :
2011-11-14 20:40:33 +00:00
ungluers = userlists . other_users ( request . user , 5 )
else :
2011-11-15 16:47:47 +00:00
ungluers = userlists . other_users ( None , 5 )
2012-02-05 00:06:53 +00:00
2012-01-03 00:07:12 +00:00
works = [ ]
2011-11-15 16:27:32 +00:00
for result in results :
2012-01-31 15:07:52 +00:00
try :
work = models . Identifier . objects . get ( type = ' goog ' , value = result [ ' googlebooks_id ' ] ) . work
works . append ( work )
except models . Identifier . DoesNotExist :
works . append ( result )
2011-09-29 01:54:50 +00:00
context = {
" q " : q ,
2012-01-03 00:07:12 +00:00
" results " : works ,
2013-03-01 17:07:15 +00:00
" ungluers " : ungluers ,
" campaign_works " : campaign_works
2011-09-29 01:54:50 +00:00
}
return render ( request , ' search.html ' , context )
2011-09-29 06:23:50 +00:00
2011-09-29 11:44:03 +00:00
# TODO: perhaps this functionality belongs in the API?
2011-09-29 06:23:50 +00:00
@require_POST
@login_required
2011-10-10 16:57:10 +00:00
@csrf_exempt
2011-09-29 06:23:50 +00:00
def wishlist ( request ) :
2011-10-10 16:57:10 +00:00
googlebooks_id = request . POST . get ( ' googlebooks_id ' , None )
2011-09-29 11:44:03 +00:00
remove_work_id = request . POST . get ( ' remove_work_id ' , None )
2011-12-28 02:39:40 +00:00
add_work_id = request . POST . get ( ' add_work_id ' , None )
2012-01-31 23:15:03 +00:00
2011-10-10 16:57:10 +00:00
if googlebooks_id :
2012-01-31 19:54:48 +00:00
try :
edition = bookloader . add_by_googlebooks_id ( googlebooks_id )
if edition . new :
# add related editions asynchronously
2012-02-16 18:19:36 +00:00
tasks . populate_edition . delay ( edition . isbn_13 )
2012-10-16 15:36:51 +00:00
request . user . wishlist . add_work ( edition . work , ' user ' , notify = True )
2013-02-26 20:30:14 +00:00
return HttpResponse ( ' added googlebooks id ' )
2012-01-31 19:54:48 +00:00
except bookloader . LookupFailure :
logger . warning ( " failed to load googlebooks_id %s " % googlebooks_id )
2013-02-26 20:30:14 +00:00
return HttpResponse ( ' error addin googlebooks id ' )
2012-01-31 19:54:48 +00:00
except Exception , e :
logger . warning ( " Error in wishlist adding %s " % ( e ) )
2013-02-26 20:30:14 +00:00
return HttpResponse ( ' error adding googlebooks id ' )
2011-09-29 11:44:03 +00:00
# TODO: redirect to work page, when it exists
elif remove_work_id :
2012-03-09 21:05:01 +00:00
try :
work = models . Work . objects . get ( id = int ( remove_work_id ) )
except models . Work . DoesNotExist :
try :
work = models . WasWork . objects . get ( was = work_id ) . work
except models . WasWork . DoesNotExist :
raise Http404
2011-12-08 23:22:05 +00:00
request . user . wishlist . remove_work ( work )
2013-02-26 20:30:14 +00:00
return HttpResponse ( ' removed work from wishlist ' )
2011-12-28 02:39:40 +00:00
elif add_work_id :
2011-12-31 18:49:23 +00:00
# if adding from work page, we have may work.id, not googlebooks_id
2012-03-09 21:05:01 +00:00
try :
work = models . Work . objects . get ( pk = add_work_id )
except models . Work . DoesNotExist :
try :
work = models . WasWork . objects . get ( was = work_id ) . work
except models . WasWork . DoesNotExist :
raise Http404
2012-10-16 15:36:51 +00:00
request . user . wishlist . add_work ( work , ' user ' , notify = True )
2013-02-26 20:30:14 +00:00
return HttpResponse ( ' added work to wishlist ' )
2011-10-14 02:16:28 +00:00
2012-03-08 03:06:30 +00:00
class InfoPageView ( TemplateView ) :
def get_template_names ( self , * * kwargs ) :
if self . kwargs [ ' template_name ' ] :
return ( self . kwargs [ ' template_name ' ] )
else :
return ( ' metrics.html ' )
def get_context_data ( self , * * kwargs ) :
users = User . objects
2012-03-07 19:42:16 +00:00
users . today = users . filter ( date_joined__range = ( date_today ( ) , now ( ) ) )
users . days7 = users . filter ( date_joined__range = ( date_today ( ) - timedelta ( days = 7 ) , now ( ) ) )
users . year = users . filter ( date_joined__year = date_today ( ) . year )
users . month = users . year . filter ( date_joined__month = date_today ( ) . month )
2012-03-13 20:54:30 +00:00
users . yesterday = users . filter ( date_joined__range = ( date_today ( ) - timedelta ( days = 1 ) , date_today ( ) ) )
2012-03-13 03:34:10 +00:00
users . gr = users . filter ( profile__goodreads_user_id__isnull = False )
users . lt = users . exclude ( profile__librarything_id = ' ' )
users . fb = users . filter ( profile__facebook_id__isnull = False )
users . tw = users . exclude ( profile__twitter_id = ' ' )
2012-03-08 03:06:30 +00:00
works = models . Work . objects
2012-03-07 19:42:16 +00:00
works . today = works . filter ( created__range = ( date_today ( ) , now ( ) ) )
works . days7 = works . filter ( created__range = ( date_today ( ) - timedelta ( days = 7 ) , now ( ) ) )
works . year = works . filter ( created__year = date_today ( ) . year )
works . month = works . year . filter ( created__month = date_today ( ) . month )
2012-03-13 20:54:30 +00:00
works . yesterday = works . filter ( created__range = ( date_today ( ) - timedelta ( days = 1 ) , date_today ( ) ) )
2012-03-08 03:06:30 +00:00
works . wishedby2 = works . filter ( num_wishes__gte = 2 )
works . wishedby20 = works . filter ( num_wishes__gte = 20 )
works . wishedby5 = works . filter ( num_wishes__gte = 5 )
works . wishedby50 = works . filter ( num_wishes__gte = 50 )
works . wishedby10 = works . filter ( num_wishes__gte = 10 )
works . wishedby100 = works . filter ( num_wishes__gte = 100 )
ebooks = models . Ebook . objects
2012-03-07 19:42:16 +00:00
ebooks . today = ebooks . filter ( created__range = ( date_today ( ) , now ( ) ) )
ebooks . days7 = ebooks . filter ( created__range = ( date_today ( ) - timedelta ( days = 7 ) , now ( ) ) )
ebooks . year = ebooks . filter ( created__year = date_today ( ) . year )
ebooks . month = ebooks . year . filter ( created__month = date_today ( ) . month )
2012-03-13 20:54:30 +00:00
ebooks . yesterday = ebooks . filter ( created__range = ( date_today ( ) - timedelta ( days = 1 ) , date_today ( ) ) )
2012-03-08 03:06:30 +00:00
wishlists = models . Wishlist . objects . exclude ( wishes__isnull = True )
2012-03-07 19:42:16 +00:00
wishlists . today = wishlists . filter ( created__range = ( date_today ( ) , now ( ) ) )
wishlists . days7 = wishlists . filter ( created__range = ( date_today ( ) - timedelta ( days = 7 ) , now ( ) ) )
wishlists . year = wishlists . filter ( created__year = date_today ( ) . year )
wishlists . month = wishlists . year . filter ( created__month = date_today ( ) . month )
2012-03-13 03:34:10 +00:00
if date_today ( ) . day == 1 :
wishlists . yesterday = wishlists . filter ( created__range = ( date_today ( ) - timedelta ( days = 1 ) , date_today ( ) ) )
else :
wishlists . yesterday = wishlists . month . filter ( created__day = date_today ( ) . day - 1 )
2012-12-06 16:42:02 +00:00
2012-12-10 21:01:50 +00:00
transactions = Transaction . objects . filter ( status__in = [ TRANSACTION_STATUS_ACTIVE , TRANSACTION_STATUS_COMPLETE ] )
2012-12-06 16:42:02 +00:00
transactions . sum = transactions . aggregate ( Sum ( ' amount ' ) ) [ ' amount__sum ' ]
transactions . today = transactions . filter ( date_created__range = ( date_today ( ) , now ( ) ) )
transactions . today . sum = transactions . today . aggregate ( Sum ( ' amount ' ) ) [ ' amount__sum ' ]
transactions . days7 = transactions . filter ( date_created__range = ( date_today ( ) - timedelta ( days = 7 ) , now ( ) ) )
transactions . days7 . sum = transactions . days7 . aggregate ( Sum ( ' amount ' ) ) [ ' amount__sum ' ]
transactions . year = transactions . filter ( date_created__year = date_today ( ) . year )
transactions . year . sum = transactions . year . aggregate ( Sum ( ' amount ' ) ) [ ' amount__sum ' ]
transactions . month = transactions . filter ( date_created__month = date_today ( ) . month )
transactions . month . sum = transactions . month . aggregate ( Sum ( ' amount ' ) ) [ ' amount__sum ' ]
transactions . yesterday = transactions . filter ( date_created__range = ( date_today ( ) - timedelta ( days = 1 ) , date_today ( ) ) )
transactions . yesterday . sum = transactions . yesterday . aggregate ( Sum ( ' amount ' ) ) [ ' amount__sum ' ]
2012-03-08 03:06:30 +00:00
return {
' users ' : users ,
' works ' : works ,
' ebooks ' : ebooks ,
' wishlists ' : wishlists ,
2012-12-11 15:53:12 +00:00
' transactions ' : transactions ,
2012-03-08 03:06:30 +00:00
}
2012-07-20 18:29:04 +00:00
class InfoLangView ( TemplateView ) :
def get_template_names ( self , * * kwargs ) :
if self . kwargs [ ' template_name ' ] :
return ( self . kwargs [ ' template_name ' ] )
else :
return ( ' languages.html ' )
def get_context_data ( self , * * kwargs ) :
languages = models . Work . objects . filter ( num_wishes__gte = 1 ) . values ( ' language ' ) . annotate ( lang_count = Count ( ' language ' ) ) . order_by ( ' -lang_count ' )
return {
' wished_languages ' : languages ,
}
2012-03-08 03:06:30 +00:00
2012-01-03 21:17:04 +00:00
class FAQView ( TemplateView ) :
2012-01-31 15:07:52 +00:00
template_name = " faq.html "
def get_context_data ( self , * * kwargs ) :
location = self . kwargs [ " location " ]
sublocation = self . kwargs [ " sublocation " ]
return { ' location ' : location , ' sublocation ' : sublocation }
2011-10-25 01:29:01 +00:00
class GoodreadsDisplayView ( TemplateView ) :
template_name = " goodreads_display.html "
def get_context_data ( self , * * kwargs ) :
context = super ( GoodreadsDisplayView , self ) . get_context_data ( * * kwargs )
session = self . request . session
gr_client = GoodreadsClient ( key = settings . GOODREADS_API_KEY , secret = settings . GOODREADS_API_SECRET )
2011-10-29 22:40:00 +00:00
user = self . request . user
2011-11-01 16:50:05 +00:00
if user . is_authenticated ( ) :
api_key = ApiKey . objects . filter ( user = user ) [ 0 ] . key
context [ ' api_key ' ] = api_key
2011-10-25 01:29:01 +00:00
2011-10-29 22:40:00 +00:00
if user . profile . goodreads_user_id is None :
2011-10-25 01:29:01 +00:00
# calculate the Goodreads authorization URL
( context [ " goodreads_auth_url " ] , request_token ) = gr_client . begin_authorization ( self . request . build_absolute_uri ( reverse ( ' goodreads_cb ' ) ) )
2011-10-29 22:40:00 +00:00
logger . info ( " goodreads_auth_url: %s " % ( context [ " goodreads_auth_url " ] ) )
2011-10-25 01:29:01 +00:00
# store request token in session so that we can redeem it for auth_token if authorization works
session [ ' goodreads_request_token ' ] = request_token [ ' oauth_token ' ]
session [ ' goodreads_request_secret ' ] = request_token [ ' oauth_token_secret ' ]
2011-10-29 22:40:00 +00:00
else :
2011-11-01 00:26:05 +00:00
gr_shelves = gr_client . shelves_list ( user_id = user . profile . goodreads_user_id )
context [ " shelves_info " ] = gr_shelves
gr_shelf_load_form = GoodreadsShelfLoadingForm ( )
# load the shelves into the form
2011-11-10 23:14:33 +00:00
choices = [ ( ' all: %d ' % ( gr_shelves [ " total_book_count " ] ) , ' all ( %d ) ' % ( gr_shelves [ " total_book_count " ] ) ) ] + \
[ ( " %s : %d " % ( s [ " name " ] , s [ " book_count " ] ) , " %s ( %d ) " % ( s [ " name " ] , s [ " book_count " ] ) ) for s in gr_shelves [ " user_shelves " ] ]
2011-11-15 20:51:38 +00:00
gr_shelf_load_form . fields [ ' goodreads_shelf_name_number ' ] . widget = Select ( choices = tuple ( choices ) )
2011-10-25 01:29:01 +00:00
2011-11-01 00:26:05 +00:00
context [ " gr_shelf_load_form " ] = gr_shelf_load_form
2011-11-10 23:14:33 +00:00
# also load any CeleryTasks associated with the user
context [ " celerytasks " ] = models . CeleryTask . objects . filter ( user = user )
2011-10-25 01:29:01 +00:00
return context
2011-10-29 22:40:00 +00:00
2011-11-16 22:16:57 +00:00
@login_required
def goodreads_auth ( request ) :
# calculate the Goodreads authorization URL
gr_client = GoodreadsClient ( key = settings . GOODREADS_API_KEY , secret = settings . GOODREADS_API_SECRET )
( goodreads_auth_url , request_token ) = gr_client . begin_authorization ( request . build_absolute_uri ( reverse ( ' goodreads_cb ' ) ) )
logger . info ( " goodreads_auth_url: %s " % ( goodreads_auth_url ) )
# store request token in session so that we can redeem it for auth_token if authorization works
request . session [ ' goodreads_request_token ' ] = request_token [ ' oauth_token ' ]
request . session [ ' goodreads_request_secret ' ] = request_token [ ' oauth_token_secret ' ]
return HttpResponseRedirect ( goodreads_auth_url )
2011-10-29 22:40:00 +00:00
@login_required
2011-10-25 01:29:01 +00:00
def goodreads_cb ( request ) :
2011-10-29 22:40:00 +00:00
""" handle callback from Goodreads """
2011-10-25 01:29:01 +00:00
session = request . session
authorized_flag = request . GET [ ' authorize ' ] # is it '1'?
request_oauth_token = request . GET [ ' oauth_token ' ]
if authorized_flag == ' 1 ' :
request_token = { ' oauth_token ' : session . get ( ' goodreads_request_token ' ) ,
' oauth_token_secret ' : session . get ( ' goodreads_request_secret ' ) }
gr_client = GoodreadsClient ( key = settings . GOODREADS_API_KEY , secret = settings . GOODREADS_API_SECRET )
access_token = gr_client . complete_authorization ( request_token )
2011-10-29 22:40:00 +00:00
# store the access token in the user profile
profile = request . user . profile
profile . goodreads_auth_token = access_token [ " oauth_token " ]
profile . goodreads_auth_secret = access_token [ " oauth_token_secret " ]
2011-10-25 01:29:01 +00:00
# let's get the userid, username
user = gr_client . auth_user ( )
2011-10-29 22:40:00 +00:00
profile . goodreads_user_id = user [ " userid " ]
profile . goodreads_user_name = user [ " name " ]
profile . goodreads_user_link = user [ " link " ]
profile . save ( ) # is this needed?
2011-10-25 01:29:01 +00:00
# redirect to the Goodreads display page -- should observe some next later
2011-11-16 20:45:33 +00:00
return HttpResponseRedirect ( reverse ( ' home ' ) )
2011-11-01 00:26:05 +00:00
@require_POST
@login_required
@csrf_exempt
def goodreads_flush_assoc ( request ) :
2011-10-29 22:40:00 +00:00
user = request . user
if user . is_authenticated ( ) :
profile = user . profile
profile . goodreads_user_id = None
profile . goodreads_user_name = None
profile . goodreads_user_link = None
profile . goodreads_auth_token = None
profile . goodreads_auth_secret = None
profile . save ( )
2011-11-10 15:36:17 +00:00
logger . info ( ' Goodreads association flushed for user %s ' , user )
2011-11-01 00:26:05 +00:00
return HttpResponseRedirect ( reverse ( ' goodreads_display ' ) )
2011-10-25 01:29:01 +00:00
2011-11-01 00:26:05 +00:00
@require_POST
@login_required
@csrf_exempt
def goodreads_load_shelf ( request ) :
"""
a view to allow user load goodreads shelf into her wishlist
"""
# Should be moved to the API
2011-11-15 20:51:38 +00:00
goodreads_shelf_name_number = request . POST . get ( ' goodreads_shelf_name_number ' , ' all:0 ' )
2011-11-01 00:26:05 +00:00
user = request . user
try :
2011-11-10 23:14:33 +00:00
# parse out shelf name and expected number of books
2011-11-15 20:51:38 +00:00
( shelf_name , expected_number_of_books ) = re . match ( r ' ^(.*):( \ d+)$ ' , goodreads_shelf_name_number ) . groups ( )
2011-11-10 23:14:33 +00:00
expected_number_of_books = int ( expected_number_of_books )
logger . info ( ' Adding task to load shelf %s to user %s with %d books ' , shelf_name , user , expected_number_of_books )
load_task_name = " load_goodreads_shelf_into_wishlist "
load_task = getattr ( tasks , load_task_name )
2012-02-16 18:19:36 +00:00
task_id = load_task . delay ( user . id , shelf_name , expected_number_of_books = expected_number_of_books )
2011-11-10 23:14:33 +00:00
ct = models . CeleryTask ( )
ct . task_id = task_id
ct . function_name = load_task_name
ct . user = user
ct . description = " Loading Goodread shelf %s to user %s with %s books " % ( shelf_name , user , expected_number_of_books )
ct . save ( )
2011-12-26 17:53:28 +00:00
return HttpResponse ( " <span style= ' margin: auto 10px auto 36px;vertical-align: middle;display: inline-block; ' >We ' re on it! <a href= ' JavaScript:window.location.reload() ' >Reload the page</a> to see the books we ' ve snagged so far.</span> " )
2011-11-01 00:26:05 +00:00
except Exception , e :
return HttpResponse ( " Error in loading shelf: %s " % ( e ) )
2011-11-10 15:36:17 +00:00
logger . info ( " Error in loading shelf for user %s : %s " , user , e )
2011-11-01 00:26:05 +00:00
2011-11-17 00:47:29 +00:00
2012-01-24 17:36:45 +00:00
@login_required
def goodreads_calc_shelves ( request ) :
# we should move towards calculating this only if needed (perhaps with Ajax), caching previous results, etc to speed up
# performance
if request . user . profile . goodreads_user_id is not None :
gr_client = GoodreadsClient ( key = settings . GOODREADS_API_KEY , secret = settings . GOODREADS_API_SECRET )
goodreads_shelves = gr_client . shelves_list ( user_id = request . user . profile . goodreads_user_id )
#goodreads_shelf_load_form = GoodreadsShelfLoadingForm()
## load the shelves into the form
#choices = [('all:%d' % (goodreads_shelves["total_book_count"]),'all (%d)' % (goodreads_shelves["total_book_count"]))] + \
# [("%s:%d" % (s["name"], s["book_count"]) ,"%s (%d)" % (s["name"],s["book_count"])) for s in goodreads_shelves["user_shelves"]]
#goodreads_shelf_load_form.fields['goodreads_shelf_name_number'].widget = Select(choices=tuple(choices))
else :
goodreads_shelf_load_form = None
return HttpResponse ( json . dumps ( goodreads_shelves ) , content_type = " application/json " )
2011-11-17 00:47:29 +00:00
@require_POST
@login_required
@csrf_exempt
def librarything_load ( request ) :
"""
a view to allow user load librarything library into her wishlist
"""
# Should be moved to the API
user = request . user
try :
# figure out expected_number_of_books later
lt_username = request . user . profile . librarything_id
2011-11-17 15:40:40 +00:00
logger . info ( ' Adding task to load librarything %s to user %s ' , lt_username , user )
2011-11-17 00:47:29 +00:00
load_task_name = " load_librarything_into_wishlist "
load_task = getattr ( tasks , load_task_name )
2012-02-16 18:19:36 +00:00
task_id = load_task . delay ( user . id , lt_username , None )
2011-11-17 00:47:29 +00:00
ct = models . CeleryTask ( )
ct . task_id = task_id
ct . function_name = load_task_name
ct . user = user
ct . description = " Loading LibraryThing collection of %s to user %s . " % ( lt_username , user )
ct . save ( )
2011-12-31 18:49:23 +00:00
2011-12-26 17:53:28 +00:00
return HttpResponse ( " <span style= ' margin: auto 10px auto 36px;vertical-align: middle;display: inline-block; ' >We ' re on it! <a href= ' JavaScript:window.location.reload() ' >Reload the page</a> to see the books we ' ve snagged so far.</span> " )
2011-11-17 00:47:29 +00:00
except Exception , e :
return HttpResponse ( " Error in loading LibraryThing library: %s " % ( e ) )
logger . info ( " Error in loading LibraryThing for user %s : %s " , user , e )
2011-11-01 00:26:05 +00:00
@require_POST
@login_required
2011-11-01 17:41:39 +00:00
@csrf_exempt
2011-11-01 00:26:05 +00:00
def clear_wishlist ( request ) :
2011-11-01 17:41:39 +00:00
try :
request . user . wishlist . works . clear ( )
2011-11-10 15:36:17 +00:00
logger . info ( " Wishlist for user %s cleared " , request . user )
2011-11-01 17:41:39 +00:00
return HttpResponse ( ' wishlist cleared ' )
except Exception , e :
return HttpResponse ( " Error in clearing wishlist: %s " % ( e ) )
2011-11-10 15:36:17 +00:00
logger . info ( " Error in clearing wishlist for user %s : %s " , request . user , e )
2013-02-26 17:43:54 +00:00
@require_POST
@login_required
def msg ( request ) :
form = MsgForm ( data = request . POST )
if form . is_valid ( ) :
if not request . user . is_staff and request . user not in form . cleaned_data [ ' work ' ] . last_campaign ( ) . managers . all ( ) :
2013-03-05 04:35:43 +00:00
logger . warning ( " unauthorized attempt to send message by %s for %s " % ( request . user , form . cleaned_data [ ' work ' ] ) )
2013-02-26 17:43:54 +00:00
raise Http404
2013-03-05 04:11:50 +00:00
supporter_message . send ( sender = request . user , msg = form . cleaned_data [ " msg " ] , work = form . cleaned_data [ " work " ] , supporter = form . cleaned_data [ " supporter " ] )
2013-02-26 17:43:54 +00:00
return HttpResponse ( " message sent " )
else :
2013-03-05 04:35:43 +00:00
logger . info ( " Invalid form for user %s " , request . user )
2013-02-26 17:43:54 +00:00
raise Http404
2011-11-16 18:20:10 +00:00
class LibraryThingView ( FormView ) :
template_name = " librarything.html "
form_class = LibraryThingForm
def get_context_data ( self , * * kwargs ) :
context = super ( LibraryThingView , self ) . get_context_data ( * * kwargs )
form = kwargs [ ' form ' ]
# get the books for the lt_username in the form
lt_username = self . request . GET . get ( " lt_username " , None )
if lt_username is not None :
lt = librarything . LibraryThing ( username = lt_username )
context . update ( { ' books ' : list ( lt . parse_user_catalog ( view_style = 5 ) ) } )
else :
context . update ( { ' books ' : None } )
2011-11-17 15:40:40 +00:00
# try picking up the LibraryThing api key -- and set to None if not available. Not being used for
# anything crucial at this moment, so a None is ok here
try :
context . update ( { ' lt_api_key ' : settings . LIBRARYTHING_API_KEY } )
except :
pass
2011-11-16 18:20:10 +00:00
return context
def form_valid ( self , form ) :
return super ( LibraryThingView , self ) . form_valid ( form )
2011-11-10 23:14:33 +00:00
@require_POST
@login_required
@csrf_exempt
def clear_celery_tasks ( request ) :
try :
request . user . tasks . clear ( )
logger . info ( " Celery tasks for user %s cleared " , request . user )
return HttpResponse ( ' Celery Tasks List cleared ' )
except Exception , e :
return HttpResponse ( " Error in clearing Celery Tasks: %s " % ( e ) )
logger . info ( " Error in clearing Celery Tasks for user %s : %s " , request . user , e )
2011-11-06 21:46:46 +00:00
2011-11-10 01:31:31 +00:00
def celery_test ( request ) :
return HttpResponse ( " celery_test " )
2011-12-05 05:56:24 +00:00
# routing views that try to redirect to the works page on a 3rd party site
#
# TODO: need to queue up a task to look up IDs if we have to fallback to
# routing based on ISBN or search
def work_librarything ( request , work_id ) :
work = get_object_or_404 ( models . Work , id = work_id )
2011-12-20 04:26:55 +00:00
isbn = work . first_isbn_13 ( )
2011-12-05 05:56:24 +00:00
if work . librarything_id :
url = work . librarything_url
elif isbn :
# TODO: do the redirect here and capture the work id?
2011-12-20 04:26:55 +00:00
url = " http://www.librarything.com/isbn/ %s " % isbn
2011-12-05 05:56:24 +00:00
else :
term = work . title + " " + work . author ( )
2012-03-01 13:53:55 +00:00
q = urlencode ( { ' searchtpe ' : ' work ' , ' term ' : term } )
2011-12-05 05:56:24 +00:00
url = " http://www.librarything.com/search.php? " + q
return HttpResponseRedirect ( url )
def work_openlibrary ( request , work_id ) :
work = get_object_or_404 ( models . Work , id = work_id )
2012-01-17 21:50:19 +00:00
isbns = [ " ISBN: " + i . value for i in work . identifiers . filter ( type = ' isbn ' ) ]
2011-12-06 14:53:53 +00:00
url = None
2011-12-05 05:56:24 +00:00
if work . openlibrary_id :
url = work . openlibrary_url
elif len ( isbns ) > 0 :
isbns = " , " . join ( isbns )
2011-12-06 14:53:53 +00:00
u = ' http://openlibrary.org/api/books?bibkeys= %s &jscmd=data&format=json ' % isbns
2012-03-10 16:03:58 +00:00
try :
j = json . loads ( requests . get ( u ) . content )
# as long as there were some matches get the first one and route to it
if len ( j . keys ( ) ) > 0 :
first = j . keys ( ) [ 0 ]
url = " http://openlibrary.org " + j [ first ] [ ' key ' ]
except ValueError :
# fail at openlibrary
logger . warning ( " failed to get OpenLibrary json at %s " % u )
2011-12-06 14:53:53 +00:00
# fall back to doing a search on openlibrary
if not url :
2012-03-01 13:53:55 +00:00
q = urlencode ( { ' q ' : work . title + " " + work . author ( ) } )
2011-12-05 05:56:24 +00:00
url = " http://openlibrary.org/search? " + q
return HttpResponseRedirect ( url )
def work_goodreads ( request , work_id ) :
work = get_object_or_404 ( models . Work , id = work_id )
2011-12-20 04:26:55 +00:00
isbn = work . first_isbn_13 ( )
2011-12-05 05:56:24 +00:00
if work . goodreads_id :
url = work . goodreads_url
elif isbn :
2011-12-20 04:26:55 +00:00
url = " http://www.goodreads.com/book/isbn/ %s " % isbn
2011-12-05 05:56:24 +00:00
else :
2012-03-01 13:53:55 +00:00
q = urlencode ( { ' query ' : work . title + " " + work . author ( ) } )
2011-12-05 05:56:24 +00:00
url = " http://www.goodreads.com/search? " + q
return HttpResponseRedirect ( url )
2011-12-29 01:43:52 +00:00
2012-01-02 14:39:11 +00:00
@login_required
2012-05-14 02:59:07 +00:00
def emailshare ( request , action ) :
2011-12-31 18:49:23 +00:00
if request . method == ' POST ' :
form = EmailShareForm ( request . POST )
if form . is_valid ( ) :
subject = form . cleaned_data [ ' subject ' ]
message = form . cleaned_data [ ' message ' ]
2012-05-13 20:38:58 +00:00
sender = ' %s via Unglue.it < %s > ' % ( request . user . username , request . user . email )
2011-12-31 18:49:23 +00:00
recipient = form . cleaned_data [ ' recipient ' ]
2012-04-25 02:20:10 +00:00
send_mail_task . delay ( subject , message , sender , [ recipient ] )
2011-12-31 18:49:23 +00:00
try :
next = form . cleaned_data [ ' next ' ]
except :
2013-01-21 17:00:01 +00:00
# if we totally failed to have a next value, we should still redirect somewhere useful
2013-03-09 18:29:03 +00:00
next = ' https://unglue.it '
2011-12-31 18:49:23 +00:00
return HttpResponseRedirect ( next )
2013-01-21 17:00:01 +00:00
else :
work = None
status = None
2012-05-12 15:12:27 +00:00
2011-12-31 18:49:23 +00:00
try :
next = request . GET [ ' next ' ]
2012-05-14 02:59:07 +00:00
work_id = next . split ( ' / ' ) [ - 2 ]
work_id = int ( work_id )
work = models . Work . objects . get ( pk = work_id )
if action == ' pledge ' :
2012-05-12 15:12:27 +00:00
message = render_to_string ( ' emails/i_just_pledged.txt ' , { ' request ' : request , ' work ' : work , ' site ' : Site . objects . get_current ( ) } )
subject = " Help me unglue " + work . title
2012-03-12 17:18:11 +00:00
else :
2012-04-25 02:17:30 +00:00
try :
2012-05-12 15:12:27 +00:00
status = work . last_campaign ( ) . status
2012-04-25 02:17:30 +00:00
except :
status = None
2012-03-26 19:26:47 +00:00
2012-04-25 02:17:30 +00:00
# customize the call to action depending on campaign status
2013-01-16 16:23:28 +00:00
if status == ' SUCCESSFUL ' or work . first_ebook ( ) :
message = render_to_string ( ' emails/read_this.txt ' , { ' request ' : request , ' work ' : work , ' site ' : Site . objects . get_current ( ) } )
subject = ' I think you \' d like this book I \' m reading '
elif status == ' ACTIVE ' :
2012-05-12 15:12:27 +00:00
message = render_to_string ( ' emails/pledge_this.txt ' , { ' request ' : request , ' work ' : work , ' site ' : Site . objects . get_current ( ) } )
2013-01-16 16:23:28 +00:00
subject = ' Please help me give this book to the world '
2012-04-25 02:17:30 +00:00
else :
2012-05-12 15:12:27 +00:00
message = render_to_string ( ' emails/wish_this.txt ' , { ' request ' : request , ' work ' : work , ' site ' : Site . objects . get_current ( ) } )
2013-01-16 16:23:28 +00:00
subject = ' Come see one of my favorite books on Unglue.it '
2012-04-25 17:45:18 +00:00
2012-05-12 15:12:27 +00:00
form = EmailShareForm ( initial = { ' next ' : next , ' subject ' : subject , ' message ' : message } )
2011-12-31 18:49:23 +00:00
except :
2013-01-21 17:00:01 +00:00
pass
if action == ' pledge ' :
message = render_to_string ( ' emails/i_just_pledged.txt ' , { ' request ' : request , ' work ' : work , ' site ' : Site . objects . get_current ( ) } )
subject = " Help me unglue " + work . title
else :
# customize the call to action depending on campaign status
if status == ' ACTIVE ' :
message = render_to_string ( ' emails/pledge_this.txt ' , { ' request ' : request , ' work ' : work , ' site ' : Site . objects . get_current ( ) } )
subject = ' Please help me give this book to the world '
elif work :
message = render_to_string ( ' emails/wish_this.txt ' , { ' request ' : request , ' work ' : work , ' site ' : Site . objects . get_current ( ) } )
subject = ' Come see one of my favorite books on Unglue.it '
else :
# for email shares not bound to a campaign or pledge
message = render_to_string ( ' emails/join_me.txt ' , { ' request ' : request , ' site ' : Site . objects . get_current ( ) } )
subject = " Help me give books to the world "
form = EmailShareForm ( initial = { ' next ' : next , ' subject ' : subject , ' message ' : message } )
2011-12-29 01:43:52 +00:00
2011-12-31 18:49:23 +00:00
return render ( request , " emailshare.html " , { ' form ' : form } )
2012-01-09 20:53:09 +00:00
2013-03-27 16:22:30 +00:00
def ask_rh ( request , campaign_id ) :
campaign = get_object_or_404 ( models . Campaign , id = campaign_id )
return feedback ( request , recipient = campaign . email , template = " ask_rh.html " ,
message_template = " ask_rh.txt " ,
redirect_url = reverse ( ' work ' , args = [ campaign . work . id ] ) ,
extra_context = { ' campaign ' : campaign , ' subject ' : campaign } )
def feedback ( request , recipient = ' support@gluejar.com ' , template = ' feedback.html ' , message_template = ' feedback.txt ' , extra_context = None , redirect_url = None ) :
context = extra_context or { }
context [ ' num1 ' ] = randint ( 0 , 10 )
context [ ' num2 ' ] = randint ( 0 , 10 )
context [ ' answer ' ] = context [ ' num1 ' ] + context [ ' num2 ' ]
2012-01-31 15:07:52 +00:00
2012-01-09 20:53:09 +00:00
if request . method == ' POST ' :
form = FeedbackForm ( request . POST )
if form . is_valid ( ) :
2013-03-27 16:22:30 +00:00
context . update ( form . cleaned_data )
context [ ' request ' ] = request
if extra_context :
context . update ( extra_context )
message = render_to_string ( message_template , context )
send_mail_task . delay ( context [ ' subject ' ] , message , context [ ' sender ' ] , [ recipient ] )
if redirect_url :
return HttpResponseRedirect ( redirect_url )
2012-01-16 00:02:50 +00:00
else :
2013-03-27 16:22:30 +00:00
return render ( request , " thanks.html " , context )
2012-01-09 20:53:09 +00:00
else :
2013-03-27 16:22:30 +00:00
context [ ' num1 ' ] = request . POST [ ' num1 ' ]
context [ ' num2 ' ] = request . POST [ ' num2 ' ]
2012-01-09 20:53:09 +00:00
else :
2012-01-31 15:07:52 +00:00
if request . user . is_authenticated ( ) :
2013-03-27 16:22:30 +00:00
context [ ' sender ' ] = request . user . email ;
2012-01-31 15:07:52 +00:00
try :
2013-03-27 16:22:30 +00:00
context [ ' page ' ] = request . GET [ ' page ' ]
2012-01-31 15:07:52 +00:00
except :
2013-03-27 16:22:30 +00:00
context [ ' page ' ] = ' / '
if not context . has_key ( ' subject ' ) :
context [ ' subject ' ] = " Feedback on page " + context [ ' page ' ]
form = FeedbackForm ( initial = context )
context [ ' form ' ] = form
return render ( request , template , context )
2012-01-09 21:13:49 +00:00
2012-02-03 15:22:53 +00:00
def comment ( request ) :
2012-02-23 20:40:45 +00:00
latest_comments = Comment . objects . all ( ) . order_by ( ' -submit_date ' ) [ : 20 ]
2012-02-05 00:06:53 +00:00
return render ( request , " comments.html " , { ' latest_comments ' : latest_comments } )
2012-04-04 16:15:18 +00:00
def campaign_archive_js ( request ) :
""" proxy for mailchimp js """
response = HttpResponse ( )
r = requests . get ( settings . CAMPAIGN_ARCHIVE_JS )
response . status_code = r . status_code
response . content = r . content
response [ " Content-Type " ] = " text/javascript "
return response
2012-08-15 13:40:37 +00:00
def lockss ( request , work_id ) :
2012-08-29 19:56:14 +00:00
"""
2012-09-18 18:16:06 +00:00
manifest pages for lockss harvester - - individual works
2012-08-29 19:56:14 +00:00
"""
2012-08-24 19:14:32 +00:00
work = safe_get_work ( work_id )
2012-08-27 20:48:07 +00:00
try :
2012-09-12 14:11:49 +00:00
ebooks = work . ebooks ( ) . filter ( edition__unglued = True )
2012-08-27 20:48:07 +00:00
except :
2012-09-12 14:11:49 +00:00
ebooks = None
2012-08-15 13:40:37 +00:00
authors = list ( models . Author . objects . filter ( editions__work = work ) . all ( ) )
2012-09-12 14:11:49 +00:00
return render ( request , " lockss.html " , { ' work ' : work , ' ebooks ' : ebooks , ' authors ' : authors } )
2012-08-24 19:14:32 +00:00
2012-09-18 18:16:06 +00:00
def lockss_manifest ( request , year ) :
"""
manifest pages for lockss harvester - - yearly indices
( lockss needs pages listing all books unglued by year , with
programmatically determinable URLs )
"""
year = int ( year )
start_date = date ( year , 1 , 1 )
end_date = date ( year , 12 , 31 )
try :
ebooks = models . Edition . objects . filter ( unglued = True ) . filter ( created__range = ( start_date , end_date ) )
except :
ebooks = None
return render ( request , " lockss_manifest.html " , { ' ebooks ' : ebooks , ' year ' : year } )
2012-08-24 19:14:32 +00:00
def download ( request , work_id ) :
context = { }
work = safe_get_work ( work_id )
2013-01-16 17:50:20 +00:00
site = Site . objects . get_current ( )
context . update ( { ' work ' : work , ' site ' : site } )
2012-08-24 19:14:32 +00:00
2012-09-10 19:18:40 +00:00
unglued_ebooks = work . ebooks ( ) . filter ( edition__unglued = True )
other_ebooks = work . ebooks ( ) . filter ( edition__unglued = False )
2012-09-26 18:59:13 +00:00
try :
readmill_epub_url = work . ebooks ( ) . filter ( format = ' epub ' ) . exclude ( provider = ' Google Books ' ) [ 0 ] . url
except :
readmill_epub_url = None
2012-08-24 19:14:32 +00:00
context . update ( {
2012-09-10 19:18:40 +00:00
' unglued_ebooks ' : unglued_ebooks ,
2012-09-19 14:25:23 +00:00
' other_ebooks ' : other_ebooks ,
2012-09-26 18:59:13 +00:00
' readmill_epub_url ' : readmill_epub_url ,
2013-03-09 18:29:03 +00:00
' base_url ' : settings . BASE_URL_SECURE
2012-08-24 19:14:32 +00:00
} )
return render ( request , " download.html " , context )
2012-08-27 19:35:29 +00:00
def about ( request , facet ) :
template = " about_ " + facet + " .html "
2012-09-07 20:08:03 +00:00
return render ( request , template )
2013-03-04 22:01:33 +00:00
@login_required
@csrf_exempt
def ml_status ( request ) :
return render ( request , " ml_status.html " )
@require_POST
@login_required
def ml_subscribe ( request ) :
request . user . profile . ml_subscribe ( double_optin = False , send_welcome = True , merge_vars = { " OPTIN_IP " : request . META [ ' REMOTE_ADDR ' ] , " OPTIN_TIME " : now ( ) . isoformat ( ) } )
return HttpResponseRedirect ( reverse ( " notification_notice_settings " ) )
@require_POST
@login_required
def ml_unsubscribe ( request ) :
request . user . profile . ml_unsubscribe ( )
return HttpResponseRedirect ( reverse ( " notification_notice_settings " ) )
2013-04-04 14:15:29 +00:00
2013-04-08 18:16:08 +00:00
def press ( request ) :
2013-04-04 14:15:29 +00:00
latest_items = models . Press . objects . order_by ( ' -date ' ) [ : 3 ]
2013-04-04 15:40:44 +00:00
highlighted_items = models . Press . objects . filter ( highlight = True ) . order_by ( ' -date ' )
all_items = models . Press . objects . exclude ( highlight = True ) . order_by ( ' -date ' )
2013-04-04 14:15:29 +00:00
return render ( request , " press_new.html " , {
' latest_items ' : latest_items ,
' highlighted_items ' : highlighted_items ,
' all_items ' : all_items
} )
2013-04-04 15:09:18 +00:00
def press_submitterator ( request ) :
if not request . user . is_staff :
return render ( request , " admins_only.html " )
else :
2013-04-08 18:16:08 +00:00
title = ' '
2013-04-04 15:09:18 +00:00
if request . method == ' POST ' :
form = PressForm ( request . POST )
if form . is_valid ( ) :
form . save ( )
2013-04-08 18:16:08 +00:00
title = form . cleaned_data [ ' title ' ]
2013-04-04 15:09:18 +00:00
else :
form = PressForm ( )
return render ( request , ' press_submitterator.html ' , {
' form ' : form ,
2013-04-08 18:16:08 +00:00
' title ' : title
2013-04-04 15:09:18 +00:00
} )