2013-03-26 17:54:03 +00:00
'''
2013-06-03 16:31:39 +00:00
external library imports
2013-03-26 17:54:03 +00:00
'''
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
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
2016-08-15 19:22:32 +00:00
from itertools import chain
2013-03-26 17:54:03 +00:00
from notification import models as notification
2012-01-09 20:53:09 +00:00
from random import randint
2013-03-26 17:54:03 +00:00
from tastypie . models import ApiKey
2016-08-15 19:22:32 +00:00
#django imports
2016-07-24 22:39:36 +00:00
from django . apps import apps
2011-10-20 03:31:16 +00:00
from django . conf import settings
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-06-03 16:31:39 +00:00
from django . contrib . auth . models import User
2016-08-15 19:22:32 +00:00
from django . contrib . auth . views import redirect_to_login
2016-07-21 20:05:57 +00:00
from django_comments . models 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
2016-08-15 19:22:32 +00:00
from django . core . exceptions import ValidationError
2013-07-24 18:52:01 +00:00
from django . core . files . storage import default_storage
2013-05-31 21:15:22 +00:00
from django . core . mail import EmailMessage
2013-07-15 20:35:41 +00:00
from django . core . urlresolvers import reverse , reverse_lazy
2013-06-10 15:57:59 +00:00
from django . core . validators import validate_email
2016-07-24 22:39:36 +00:00
from django . db . models import Q , Count , Sum
2011-11-01 00:26:05 +00:00
from django . forms import Select
2017-11-13 20:30:00 +00:00
from django . forms . models import inlineformset_factory
2013-06-03 16:31:39 +00:00
from django . http import (
HttpResponseRedirect ,
Http404 ,
HttpResponse ,
HttpResponseNotFound
)
2016-08-15 19:22:32 +00:00
from django . shortcuts import render , get_object_or_404
2013-05-03 18:48:36 +00:00
from django . template import TemplateDoesNotExist
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
2017-11-13 20:30:00 +00:00
from django . views . generic . edit import FormView
2011-12-01 18:17:33 +00:00
from django . views . generic . list import ListView
2014-06-24 22:27:40 +00:00
from django . views . generic . base import (
TemplateView ,
)
2013-03-26 17:54:03 +00:00
2016-08-15 19:22:32 +00:00
#regluit imports
2013-06-03 16:31:39 +00:00
from regluit . core import (
tasks ,
models ,
bookloader ,
librarything ,
userlists ,
)
2014-05-08 14:22:35 +00:00
import regluit . core . cc as cc
2013-04-16 20:46:25 +00:00
from regluit . core . bookloader import merge_works , detach_edition
2013-03-26 17:54:03 +00:00
from regluit . core . goodreads import GoodreadsClient
2016-05-10 01:48:23 +00:00
from regluit . core . isbn import ISBN
2013-03-26 17:54:03 +00:00
from regluit . core . search import gluejar_search
2013-03-01 14:46:52 +00:00
from regluit . core . signals import supporter_message
2016-08-15 19:22:32 +00:00
from regluit . core . tasks import send_mail_task , watermark_acq
2013-08-22 18:22:54 +00:00
from regluit . core . parameters import *
2014-12-05 23:36:45 +00:00
from regluit . core . facets import get_facet_object , get_order_by
2013-03-26 17:54:03 +00:00
2013-05-31 19:19:58 +00:00
from regluit . frontend . forms import (
ProfileForm ,
CampaignPledgeForm ,
2013-08-16 19:49:44 +00:00
CampaignPurchaseForm ,
2014-02-20 03:18:23 +00:00
CampaignThanksForm ,
2013-05-31 19:19:58 +00:00
GoodreadsShelfLoadingForm ,
RightsHolderForm ,
UserClaimForm ,
LibraryThingForm ,
getManageCampaignForm ,
CampaignAdminForm ,
EmailShareForm ,
FeedbackForm ,
EbookForm ,
2013-06-17 22:53:21 +00:00
EbookFileForm ,
2013-05-31 19:19:58 +00:00
CustomPremiumForm ,
2013-06-17 22:53:21 +00:00
OfferForm ,
2013-05-31 19:19:58 +00:00
PledgeCancelForm ,
getTransferCreditForm ,
CCForm ,
2014-02-20 03:18:23 +00:00
AnonCCForm ,
2014-09-13 20:19:47 +00:00
AccountCCForm ,
2013-05-31 19:19:58 +00:00
CloneCampaignForm ,
PlainCCForm ,
WorkForm ,
OtherWorkForm ,
MsgForm ,
PressForm ,
2013-07-15 20:35:41 +00:00
KindleEmailForm ,
2014-10-27 23:11:44 +00:00
LibModeForm ,
2014-12-18 16:41:06 +00:00
DateCalculatorForm ,
2014-12-18 18:37:28 +00:00
RegiftForm ,
2015-03-12 15:58:49 +00:00
SubjectSelectForm ,
MapSubjectForm ,
2016-05-26 16:19:33 +00:00
SurveyForm ,
2017-02-13 18:33:26 +00:00
DonationForm ,
2013-05-31 19:19:58 +00:00
)
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
2016-08-15 19:22:32 +00:00
from regluit . payment . models import Transaction , CreditLog
2013-05-31 19:19:58 +00:00
from regluit . payment . parameters import (
TRANSACTION_STATUS_ACTIVE ,
TRANSACTION_STATUS_COMPLETE ,
TRANSACTION_STATUS_CANCELED ,
TRANSACTION_STATUS_INCOMPLETE ,
TRANSACTION_STATUS_NONE ,
TRANSACTION_STATUS_MODIFIED ,
PAYMENT_TYPE_AUTHORIZATION ,
2017-02-13 18:33:26 +00:00
PAYMENT_HOST_NONE ,
COMPANY_TITLE
2013-05-31 19:19:58 +00:00
)
2011-12-19 06:33:13 +00:00
2013-03-26 17:54:03 +00:00
from regluit . utils . localdatetime import now , date_today
2016-07-27 17:02:47 +00:00
from regluit . libraryauth . forms import UserNamePass
2014-12-18 06:07:59 +00:00
from regluit . libraryauth . views import Authenticator , superlogin , login_user
2013-10-02 16:02:08 +00:00
from regluit . libraryauth . models import Library
2014-10-27 15:55:46 +00:00
from regluit . marc . views import qs_marc_records
2017-06-20 15:08:14 +00:00
from questionnaire . models import Landing , Questionnaire
from questionnaire . views import export_summary as answer_summary , export_csv as export_answers
2011-10-25 01:29:01 +00:00
2017-07-26 21:33:38 +00:00
from . bibedit import edit_edition , user_can_edit_work , safe_get_work , get_edition
2017-11-13 20:30:00 +00:00
from . rh_views import RHAgree , rh_admin , claim , rh_tools
2017-07-25 11:29:23 +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 )
2013-12-14 18:24:29 +00:00
def slideshow ( ) :
max = 8
2012-03-08 14:36:59 +00:00
ending = models . Campaign . objects . filter ( status = ' ACTIVE ' ) . order_by ( ' deadline ' )
count = ending . count ( )
j = 0
2016-08-15 19:22:32 +00:00
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
2013-12-14 18:24:29 +00:00
# then fill out the rest of the list with slide works
2012-06-13 12:41:23 +00:00
remainder = max - count
2013-12-14 18:24:29 +00:00
remainder_works = models . Work . objects . filter ( campaigns__status = " SUCCESSFUL " ) . order_by ( ' -campaigns__deadline ' ) [ : remainder ]
2012-06-13 12:41:23 +00:00
worklist . extend ( remainder_works )
2012-03-08 14:36:59 +00:00
else :
2016-08-15 19:22:32 +00:00
# if the active campaign list has more works than we can fit
2012-06-13 12:41:23 +00:00
# in our slideshow, it's the only source we need to draw from
while j < max :
worklist . append ( ending [ j ] . work )
2016-08-15 19:22:32 +00:00
j + = 1
return ( worklist [ : 4 ] , worklist [ 4 : 8 ] )
2011-10-13 16:23:57 +00:00
2013-06-10 13:29:18 +00:00
def process_kindle_email ( request ) :
"""
check for kindle_email in session in case this is a redirect after
download + login / account creation ; add kindle email to profile
"""
user = request . user
if user . is_authenticated ( ) and request . session . has_key ( ' kindle_email ' ) :
user . profile . kindle_email = request . session [ ' kindle_email ' ]
user . profile . save ( )
2013-06-26 13:46:56 +00:00
request . session . pop ( ' kindle_email ' )
2013-06-10 13:29:18 +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 ( ' / ' )
2016-08-15 19:22:32 +00:00
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
2016-08-15 19:22:32 +00:00
2013-02-07 20:25:14 +00:00
return cover_width
2012-03-13 20:57:42 +00:00
2012-05-24 19:29:45 +00:00
def home ( request , landing = False ) :
2015-08-24 14:27:39 +00:00
faves = None
if request . user . is_authenticated ( ) :
2016-08-15 19:22:32 +00:00
next = request . GET . get ( ' next ' , False )
2015-07-09 20:32:52 +00:00
if next :
# should happen only for new users
return HttpResponseRedirect ( next )
2015-08-24 14:27:39 +00:00
else :
wishes = request . user . wishlist . wishes_set . all ( ) . order_by ( ' -created ' ) [ : 4 ]
faves = [ wish . work for wish in wishes ]
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
"""
2014-07-03 19:43:49 +00:00
try :
featured = models . Work . objects . filter ( featured__isnull = False ) . distinct ( ) . order_by ( ' -featured ' ) [ 0 ]
except :
#shouldn't occur except in tests
featured = models . Work . objects . all ( ) [ 0 ]
2016-08-15 19:22:32 +00:00
top_pledge = models . Campaign . objects . filter ( status = " ACTIVE " , type = REWARDS ) . order_by ( ' left ' ) [ : 4 ]
2014-05-22 18:08:15 +00:00
top_b2u = models . Campaign . objects . filter ( status = " ACTIVE " , type = BUY2UNGLUE ) . order_by ( ' -work__num_wishes ' ) [ : 4 ]
2016-08-15 19:22:32 +00:00
top_t4u = models . Campaign . objects . exclude ( id = featured . id ) . filter ( status = " ACTIVE " , type = THANKS ) . order_by ( ' -work__num_wishes ' ) [ : 4 ]
2014-05-22 18:08:15 +00:00
2013-03-28 15:12:55 +00:00
most_wished = models . Work . objects . order_by ( ' -num_wishes ' ) [ : 4 ]
2016-08-15 19:22:32 +00:00
2013-06-05 19:06:07 +00:00
unglued_books = models . Work . objects . filter ( campaigns__status = " SUCCESSFUL " ) . order_by ( ' -campaigns__deadline ' ) [ : 4 ]
2016-08-15 19:22:32 +00:00
2014-07-03 19:43:49 +00:00
cc_books = models . Work . objects . exclude ( id = featured . id ) . filter (
2014-07-01 17:07:07 +00:00
featured__isnull = False ,
) . distinct ( ) . order_by ( ' -featured ' ) [ : 4 ]
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 (
2017-02-13 18:33:26 +00:00
anonymous = False , campaign__isnull = False
2013-10-05 15:41:12 +00:00
) . exclude (
type = 0 #incomplete
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 ]
2014-07-28 22:22:26 +00:00
latest_wishes = models . Wishes . objects . filter ( source = ' user ' ) . order_by (
2013-03-26 17:54:03 +00:00
' -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
)
2016-08-15 19:22:32 +00:00
2013-03-26 17:54:03 +00:00
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
)
2016-08-15 19:22:32 +00:00
2013-03-26 17:54:03 +00:00
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
)
2016-08-15 19:22:32 +00:00
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 (
2016-08-15 19:22:32 +00:00
chain ( latest_comments_tuple , latest_pledges_tuple , latest_wishes_tuple ) ,
2013-03-26 17:54:03 +00:00
key = lambda instance : instance [ 0 ] ,
reverse = True
)
2016-08-15 19:22:32 +00:00
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 ]
2016-08-15 19:22:32 +00:00
2013-06-05 19:05:14 +00:00
return render (
request ,
2016-08-15 19:22:32 +00:00
' home.html ' ,
2013-06-05 19:05:14 +00:00
{
2016-08-15 19:22:32 +00:00
' events ' : events ,
' top_pledge ' : top_pledge ,
' top_b2u ' : top_b2u ,
' top_t4u ' : top_t4u ,
' unglued_books ' : unglued_books ,
2014-03-05 19:02:12 +00:00
' cc_books ' : cc_books ,
' most_wished ' : most_wished ,
2014-07-03 19:43:49 +00:00
' featured ' : featured ,
2015-08-24 14:27:39 +00:00
' faves ' : faves ,
2013-06-05 19:05:14 +00:00
}
)
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/
2016-08-15 19:22:32 +00:00
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 ) :
2016-08-15 19:22:32 +00:00
return render ( request , ' front_matter.html ' , { ' campaign ' : work . last_campaign ( ) } )
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 )
2016-08-15 19:22:32 +00:00
alert = ' '
2014-03-11 21:34:27 +00:00
formset = None
2012-07-07 22:13:05 +00:00
if action == " acks " :
2016-08-15 19:22:32 +00:00
return acks ( request , work )
2014-03-11 21:34:27 +00:00
elif action == " editions " :
2016-08-15 19:22:32 +00:00
EditionFormSet = inlineformset_factory ( models . Work , models . Edition , fields = ( ) , extra = 0 )
2014-11-28 16:12:29 +00:00
if request . method == " POST " and ( request . user . is_staff or ( work . last_campaign ( ) and request . user in work . last_campaign ( ) . managers . all ( ) ) ) :
2014-03-11 21:34:27 +00:00
formset = EditionFormSet ( data = request . POST , instance = work )
if formset . is_valid ( ) :
for form in formset . deleted_forms :
detach_edition ( form . instance )
alert = ' editions have been split '
if request . POST . has_key ( ' select_edition ' ) :
2016-08-15 19:22:32 +00:00
selected_id = request . POST [ ' select_edition ' ]
2014-03-11 21:34:27 +00:00
try :
2016-08-15 19:22:32 +00:00
work . selected_edition = work . editions . get ( id = selected_id )
work . title = work . selected_edition . title
2014-03-11 21:34:27 +00:00
work . save ( )
alert = alert + ' edition selected '
except models . Edition . DoesNotExist :
pass
formset = EditionFormSet ( instance = work )
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 " )
2016-08-15 19:22:32 +00:00
2013-06-10 13:29:18 +00:00
process_kindle_email ( request )
2016-08-15 19:22:32 +00:00
2012-02-28 22:28:33 +00:00
if request . method == ' POST ' and not request . user . is_anonymous ( ) :
activetab = ' 4 '
2014-03-11 21:34:27 +00:00
elif action == ' editions ' :
activetab = ' 4 '
2012-02-28 22:28:33 +00:00
else :
try :
activetab = request . GET [ ' tab ' ]
if activetab not in [ ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' ] :
2016-08-15 19:22:32 +00:00
activetab = ' 1 '
2012-02-28 22:28:33 +00:00
except :
2016-08-15 19:22:32 +00:00
activetab = ' 1 '
2011-11-06 22:44:50 +00:00
campaign = work . last_campaign ( )
2014-03-11 21:34:27 +00:00
editions = work . editions . all ( ) . order_by ( ' -publication_date ' ) [ : 10 ]
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
2016-08-15 19:22:32 +00:00
2013-02-07 20:25:14 +00:00
cover_width_number = 0
2016-08-15 19:22:32 +00:00
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 )
2016-08-15 19:22:32 +00:00
2012-05-14 02:13:45 +00:00
if action == ' preview ' :
work . last_campaign_status = ' ACTIVE '
2016-08-15 19:22:32 +00:00
2011-11-26 22:09:33 +00:00
if not request . user . is_anonymous ( ) :
2016-08-15 19:22:32 +00:00
claimform = UserClaimForm ( request . user , data = { ' claim-work ' : work . pk , ' claim-user ' : request . user . id } , prefix = ' claim ' )
2011-11-26 22:09:33 +00:00
else :
claimform = None
2016-08-15 19:22: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
2016-08-15 19:22:32 +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 ]
2016-08-15 19:22:32 +00:00
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 :
2016-08-15 19:22:32 +00:00
claimstatus = ' disputed '
2012-04-03 19:50:02 +00:00
elif pending_claims_count == 1 :
2016-08-15 19:22:32 +00:00
claimstatus = ' one_pending '
rights_holder_name = pending_claims [ 0 ] . rights_holder . rights_holder_name
2012-04-03 19:50:02 +00:00
else :
2016-08-15 19:22:32 +00:00
claimstatus = ' open '
2012-03-23 15:09:51 +00:00
return render ( request , ' work.html ' , {
2016-08-15 19:22:32 +00:00
' work ' : work ,
2017-10-26 17:03:05 +00:00
' user_can_edit_work ' : user_can_edit_work ( request . user , work ) ,
2016-08-15 19:22:32 +00:00
' premiums ' : premiums ,
' ungluers ' : userlists . supporting_users ( work , 5 ) ,
2012-03-23 15:09:51 +00:00
' 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-08-20 02:54:43 +00:00
' cover_width ' : cover_width_number ,
2014-03-04 20:49:59 +00:00
' action ' : action ,
2014-03-11 21:34:27 +00:00
' formset ' : formset ,
2015-01-14 20:07:54 +00:00
' kwform ' : SubjectSelectForm ( )
2016-08-15 19:22:32 +00:00
} )
2011-11-21 03:23:51 +00:00
2013-06-17 22:53:21 +00:00
def edition_uploads ( request , edition_id ) :
2013-08-27 03:56:01 +00:00
context = { }
2013-06-17 22:53:21 +00:00
if not request . user . is_authenticated ( ) :
return render ( request , " admins_only.html " )
2017-07-25 12:21:26 +00:00
edition = get_edition ( edition_id )
2014-01-15 13:32:55 +00:00
campaign_type = edition . work . last_campaign ( ) . type
2016-08-24 19:41:29 +00:00
if not user_can_edit_work ( request . user , edition . work ) :
return render ( request , " admins_only.html " )
2013-06-17 22:53:21 +00:00
if request . method == ' POST ' :
2014-01-15 13:32:55 +00:00
form = EbookFileForm ( data = request . POST , files = request . FILES , campaign_type = campaign_type )
2013-06-17 22:53:21 +00:00
if form . is_valid ( ) :
2014-01-15 13:32:55 +00:00
logger . info ( " EbookFileForm is_valid " )
2013-06-17 22:53:21 +00:00
form . save ( )
2014-02-06 00:33:55 +00:00
edition . work . last_campaign ( ) . save ( )
2016-08-15 19:22:32 +00:00
context [ ' uploaded ' ] = True
2014-01-15 13:32:55 +00:00
if campaign_type == BUY2UNGLUE :
2014-02-05 22:02:21 +00:00
if edition . work . last_campaign ( ) . status == ' SUCCESSFUL ' :
try :
edition . work . last_campaign ( ) . watermark_success ( )
except Exception as e :
2016-08-15 19:22:32 +00:00
context [ ' upload_error ' ] = e
2014-02-05 22:02:21 +00:00
form . instance . delete ( )
else :
# campaign mangager gets a copy
2016-08-15 19:22:32 +00:00
test_acq = models . Acq . objects . create ( user = request . user , work = edition . work , license = TESTING )
2014-02-05 22:02:21 +00:00
try :
test_acq . get_watermarked ( )
2016-08-15 19:22:32 +00:00
context [ ' watermarked ' ] = test_acq . watermarked
2014-02-05 22:02:21 +00:00
except Exception as e :
2016-08-15 19:22:32 +00:00
context [ ' upload_error ' ] = e
2014-02-05 22:02:21 +00:00
form . instance . delete ( )
2014-01-15 13:32:55 +00:00
if campaign_type == THANKS :
e = form . instance . check_file ( )
if e != None :
logger . error ( e )
2016-08-15 19:22:32 +00:00
context [ ' upload_error ' ] = e
2014-01-15 13:32:55 +00:00
form . instance . delete ( )
2014-09-04 22:33:20 +00:00
else :
tasks . process_ebfs . delay ( edition . work . last_campaign ( ) )
2016-08-24 19:41:29 +00:00
if form . instance . id :
new_ebook = models . Ebook . objects . create (
edition = edition ,
format = form . instance . format ,
url = form . instance . file . url ,
rights = edition . work . last_campaign ( ) . license ,
2016-09-23 18:53:54 +00:00
version_label = form . cleaned_data . get ( ' version_label ' , ' ' ) ,
2016-08-24 19:41:29 +00:00
active = False ,
provider = " Unglue.it " ,
)
form . instance . ebook = new_ebook
2016-09-23 18:53:54 +00:00
form . instance . ebook . set_next_iter ( )
2017-09-06 22:02:40 +00:00
form . instance . save ( )
2016-08-24 19:41:29 +00:00
2014-01-15 13:32:55 +00:00
else :
2016-08-15 19:22:32 +00:00
context [ ' upload_error ' ] = form . errors
form = EbookFileForm ( initial = { ' edition ' : edition , ' format ' : ' epub ' } , campaign_type = campaign_type )
2013-08-27 03:56:01 +00:00
context . update ( {
2016-08-15 19:22:32 +00:00
' form ' : form , ' edition ' : edition ,
2013-06-17 22:53:21 +00:00
' ebook_files ' : models . EbookFile . objects . filter ( edition = edition )
} )
2016-08-15 19:22:32 +00:00
return render ( request , ' edition_uploads.html ' , context )
2013-06-17 22:53:21 +00:00
2015-09-21 20:07:41 +00:00
@login_required
def manage_ebooks ( request , edition_id , by = None ) :
2015-09-21 20:19:31 +00:00
if edition_id :
try :
edition = models . Edition . objects . get ( id = edition_id )
except models . Edition . DoesNotExist :
raise Http404
work = edition . work
else :
raise Http404
2016-08-15 19:22:32 +00:00
# if the work and edition are set, we save the edition and set the work
alert = ' '
2016-08-24 19:41:29 +00:00
admin = user_can_edit_work ( request . user , work )
2015-09-21 20:07:41 +00:00
if request . method == ' POST ' :
2016-08-26 14:28:23 +00:00
ebook_form = EbookForm ( data = request . POST , files = request . FILES , )
if ebook_form . is_valid ( ) :
if ebook_form . cleaned_data . get ( ' file ' , None ) :
new_ebf = models . EbookFile . objects . create (
file = ebook_form . cleaned_data [ ' file ' ] ,
format = ebook_form . cleaned_data [ ' format ' ] ,
edition = edition ,
active = True ,
2017-07-25 12:14:05 +00:00
2016-08-26 14:28:23 +00:00
)
ebook_form . instance . url = new_ebf . file . url
ebook_form . instance . provider = " Unglue.it "
ebook_form . instance . save ( )
new_ebf . ebook = ebook_form . instance
new_ebf . save ( )
2016-08-15 19:22:32 +00:00
else :
2016-08-26 14:28:23 +00:00
ebook_form . save ( )
2016-09-23 18:53:54 +00:00
ebook_form . instance . set_next_iter ( )
2016-08-26 14:28:23 +00:00
edition . work . remove_old_ebooks ( )
alert = ' Thanks for adding an ebook to unglue.it! '
else :
alert = ' your submitted ebook had errors '
2015-09-21 20:07:41 +00:00
else :
2016-08-26 14:28:23 +00:00
ebook_form = EbookForm ( instance = models . Ebook ( user = request . user , edition = edition , provider = ' x ' ) )
2014-03-12 23:32:56 +00:00
try :
2016-08-26 14:28:23 +00:00
show_ebook_form = admin or edition . work . last_campaign ( ) . status not in [ ' ACTIVE ' , ' INITIALIZED ' ]
2014-03-12 23:32:56 +00:00
except :
show_ebook_form = True
2015-09-21 20:07:41 +00:00
return render ( request , ' manage_ebooks.html ' , {
' edition ' : edition , ' admin ' : admin , ' alert ' : alert ,
2016-08-26 14:28:23 +00:00
' ebook_form ' : ebook_form , ' show_ebook_form ' : show_ebook_form ,
2012-05-11 18:13:09 +00:00
} )
2013-12-31 02:51:32 +00:00
def campaign_results ( request , campaign ) :
return render ( request , ' campaign_results.html ' , {
2016-08-15 19:22:32 +00:00
' campaign ' : campaign ,
2013-12-31 02:51:32 +00:00
} )
2016-08-15 19:22:32 +00:00
2016-08-24 19:41:29 +00:00
def manage_campaign ( request , id , ebf = None , action = ' manage ' ) :
2011-11-21 03:23:51 +00:00
campaign = get_object_or_404 ( models . Campaign , id = id )
2016-08-15 19:22:32 +00:00
campaign . not_manager = False
campaign . problems = [ ]
2017-02-13 18:48:17 +00:00
if ( not request . user . is_authenticated ( ) ) or ( not request . user in campaign . managers . all ( ) and not request . user . is_staff ) :
2016-08-15 19:22:32 +00:00
campaign . not_manager = True
2011-11-22 05:28:06 +00:00
return render ( request , ' manage_campaign.html ' , { ' campaign ' : campaign } )
2013-12-31 02:51:32 +00:00
if action == ' results ' :
return campaign_results ( request , campaign )
2012-05-04 13:56:41 +00:00
alerts = [ ]
activetab = ' #1 '
2013-06-17 22:53:21 +00:00
offers = campaign . work . offers . all ( )
for offer in offers :
2016-08-15 19:22:32 +00:00
offer . offer_form = OfferForm ( instance = offer , prefix = ' offer_ %d ' % offer . id )
2012-05-04 13:56:41 +00:00
2012-03-26 19:31:41 +00:00
if request . method == ' POST ' :
if request . POST . has_key ( ' add_premium ' ) :
2016-07-24 22:50:48 +00:00
new_premium_form = CustomPremiumForm ( data = request . POST )
2012-03-26 19:31:41 +00:00
if new_premium_form . is_valid ( ) :
new_premium_form . save ( )
alerts . append ( _ ( ' New premium has been added ' ) )
2016-07-24 22:50:48 +00:00
new_premium_form = CustomPremiumForm ( initial = { ' campaign ' : campaign } )
2012-03-26 19:31:41 +00:00
else :
2016-08-15 19:22:32 +00:00
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 ' ) :
2016-08-15 19:22:32 +00:00
form = getManageCampaignForm ( instance = campaign , data = request . POST )
if form . is_valid ( ) :
form . save ( )
2014-04-09 19:02:25 +00:00
campaign . dollar_per_day = None
2013-08-09 23:00:54 +00:00
campaign . set_dollar_per_day ( )
2016-08-15 19:22:32 +00:00
campaign . work . selected_edition = campaign . edition
if campaign . type in { BUY2UNGLUE , THANKS } :
offers = campaign . work . create_offers ( )
2013-06-17 22:53:21 +00:00
for offer in offers :
2016-08-15 19:22:32 +00:00
offer . offer_form = OfferForm ( instance = offer , prefix = ' offer_ %d ' % offer . id )
2012-06-22 03:10:50 +00:00
campaign . update_left ( )
2014-03-12 22:03:50 +00:00
if campaign . type is THANKS :
campaign . work . description = form . cleaned_data [ ' work_description ' ]
2014-09-04 22:33:20 +00:00
tasks . process_ebfs . delay ( campaign )
2014-04-29 18:51:49 +00:00
campaign . work . save ( )
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 ' ) )
2017-11-28 01:12:42 +00:00
new_premium_form = CustomPremiumForm ( initial = { ' campaign ' : campaign } )
2012-03-26 19:31:41 +00:00
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 ( )
2016-08-15 19:22:32 +00:00
alerts . append ( _ ( ' Premium %s has been inactivated ' % premium_to_stop ) )
2012-05-01 14:56:19 +00:00
form = getManageCampaignForm ( instance = campaign )
2016-07-24 22:50:48 +00:00
new_premium_form = CustomPremiumForm ( initial = { ' campaign ' : campaign } )
2013-06-17 22:53:21 +00:00
elif request . POST . has_key ( ' change_offer ' ) :
for offer in offers :
if request . POST . has_key ( ' offer_ %d -work ' % offer . id ) :
2016-08-15 19:22:32 +00:00
offer . offer_form = OfferForm ( instance = offer , data = request . POST , prefix = ' offer_ %d ' % offer . id )
2013-06-17 22:53:21 +00:00
if offer . offer_form . is_valid ( ) :
offer . offer_form . save ( )
2014-02-25 19:29:54 +00:00
offer . active = True
offer . save ( )
2013-06-17 22:53:21 +00:00
alerts . append ( _ ( ' Offer has been changed ' ) )
else :
2016-08-15 19:22:32 +00:00
alerts . append ( _ ( ' Offer has not been changed ' ) )
2013-06-17 22:53:21 +00:00
form = getManageCampaignForm ( instance = campaign )
new_premium_form = CustomPremiumForm ( data = { ' campaign ' : campaign } )
activetab = ' #2 '
2011-11-22 05:28:06 +00:00
else :
2016-03-29 17:06:23 +00:00
if action == ' makemobi ' :
2016-08-24 19:41:29 +00:00
ebookfile = get_object_or_404 ( models . EbookFile , id = ebf )
tasks . make_mobi . delay ( ebookfile )
2016-03-29 17:06:23 +00:00
return HttpResponseRedirect ( reverse ( ' mademobi ' , args = [ campaign . id ] ) )
2016-08-15 19:22:32 +00:00
elif action == ' mademobi ' :
2016-03-29 17:06:23 +00:00
alerts . append ( ' A MOBI file is being generated ' )
2014-03-12 22:03:50 +00:00
form = getManageCampaignForm ( instance = campaign , initial = { ' work_description ' : campaign . work . description } )
2016-07-24 22:50:48 +00:00
new_premium_form = CustomPremiumForm ( initial = { ' campaign ' : campaign } )
2016-08-15 19:22:32 +00:00
2012-03-26 19:31:41 +00:00
return render ( request , ' manage_campaign.html ' , {
2016-08-15 19:22:32 +00:00
' 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 ,
2013-06-17 22:53:21 +00:00
' work ' : campaign . work ,
2012-05-04 13:56:41 +00:00
' activetab ' : activetab ,
2016-03-29 17:06:23 +00:00
' offers ' : offers ,
' action ' : action ,
2012-03-26 19:31:41 +00:00
} )
2016-08-15 19:22:32 +00:00
2011-11-22 01:12:13 +00:00
def googlebooks ( request , googlebooks_id ) :
2016-08-15 19:22:32 +00:00
try :
edition = models . Identifier . objects . get ( type = ' goog ' , value = googlebooks_id ) . edition
2012-01-09 18:55:22 +00:00
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 )
2017-10-26 17:03:05 +00:00
if request . user . is_authenticated ( ) :
request . user . profile . works . add ( edition . work )
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 " )
2017-10-28 22:33:58 +00:00
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 ( )
2014-12-14 15:28:58 +00:00
subjects = subjects
if request . GET . get ( ' subset ' ) == ' free ' :
subjects = models . Subject . objects . filter ( works__is_free = True ) . annotate ( Count ( ' works__is_free ' ) )
if request . GET . get ( ' order ' ) == ' count ' :
subjects = subjects . order_by ( ' -works__is_free__count ' )
else :
subjects = subjects . order_by ( ' name ' )
2011-11-15 02:13:39 +00:00
else :
2014-12-14 15:28:58 +00:00
subjects = models . Subject . objects . all ( ) . annotate ( Count ( ' works ' ) )
if request . GET . get ( ' order ' ) == ' count ' :
subjects = subjects . order_by ( ' -works__count ' )
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
2015-03-12 15:58:49 +00:00
class MapSubjectView ( FormView ) :
2015-03-19 17:34:26 +00:00
"""
Allows a staffer to add given subject to all works with given the onto_subject keyword .
e . g . , subject = " Language " onto_subject = " English language "
"""
2016-08-15 19:22:32 +00:00
template_name = " map_subject.html "
2015-03-12 15:58:49 +00:00
form_class = MapSubjectForm
2016-08-15 19:22:32 +00:00
2015-03-12 15:58:49 +00:00
def dispatch ( self , request , * args , * * kwargs ) :
if not request . user . is_staff :
return render ( request , " admins_only.html " )
else :
return super ( MapSubjectView , self ) . dispatch ( request , * args , * * kwargs )
2016-08-15 19:22:32 +00:00
2015-03-12 15:58:49 +00:00
def form_valid ( self , form ) :
2016-08-15 19:22:32 +00:00
context = self . get_context_data ( )
context [ ' subject ' ] = form . cleaned_data [ ' subject ' ]
context [ ' onto_subject ' ] = form . cleaned_data [ ' onto_subject ' ]
2015-03-12 15:58:49 +00:00
if self . request . POST . has_key ( ' confirm_map_subject ' ) :
initial_count = context [ ' onto_subject ' ] . works . all ( ) . count ( )
initial_free_count = context [ ' onto_subject ' ] . works . filter ( is_free = True ) . count ( )
context [ ' onto_subject ' ] . works . add ( * list ( context [ ' subject ' ] . works . all ( ) ) )
2016-08-15 19:22:32 +00:00
context [ ' map_complete ' ] = True
2015-03-12 15:58:49 +00:00
context [ ' form ' ] = MapSubjectForm ( initial = form . cleaned_data )
context [ ' added ' ] = context [ ' onto_subject ' ] . works . all ( ) . count ( ) - initial_count
context [ ' added_free ' ] = context [ ' onto_subject ' ] . works . filter ( is_free = True ) . count ( ) - initial_free_count
else :
2016-08-15 19:22:32 +00:00
context [ ' form ' ] = MapSubjectForm ( initial = form . cleaned_data )
2015-03-12 15:58:49 +00:00
return render ( self . request , self . template_name , context )
2012-07-21 20:26:16 +00:00
class FilterableListView ( ListView ) :
2014-10-27 15:55:46 +00:00
send_marc = False
2012-07-21 20:26:16 +00:00
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 ( )
2016-08-15 19:22:32 +00:00
2012-07-21 20:26:16 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( FilterableListView , self ) . get_context_data ( * * kwargs )
if self . request . GET . has_key ( ' pub_lang ' ) :
2016-08-15 19:22:32 +00:00
context [ ' pub_lang ' ] = self . request . GET [ ' pub_lang ' ]
2012-07-21 20:26:16 +00:00
else :
2016-08-15 19:22:32 +00:00
context [ ' pub_lang ' ] = ' '
context [ ' show_langs ' ] = True
context [ ' WISHED_LANGS ' ] = settings . WISHED_LANGS
2012-07-21 20:26:16 +00:00
return context
2016-08-15 19:22:32 +00:00
2014-10-27 15:55:46 +00:00
def render_to_response ( self , context , * * response_kwargs ) :
if self . send_marc :
return qs_marc_records ( self . request , qs = self . object_list )
else :
2016-08-15 19:22:32 +00:00
return super ( FilterableListView , self ) . render_to_response ( context , * * response_kwargs )
2014-11-18 18:33:17 +00:00
2016-08-15 19:22:32 +00:00
recommended_user = User . objects . filter ( username = settings . UNGLUEIT_RECOMMENDED_USERNAME )
2011-12-03 00:29:23 +00:00
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 "
2016-08-15 19:22:32 +00:00
max_works = 100000
2012-07-21 20:26:16 +00:00
def get_queryset_all ( self ) :
2014-11-18 18:33:17 +00:00
facet = self . kwargs . get ( ' facet ' , None )
2011-12-03 00:29:23 +00:00
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 ' )
2016-08-15 19:22:32 +00:00
2011-12-03 00:29:23 +00:00
def get_context_data ( self , * * kwargs ) :
2016-08-15 19:22:32 +00:00
context = super ( WorkListView , self ) . get_context_data ( * * kwargs )
qs = self . get_queryset ( )
context [ ' ungluers ' ] = userlists . work_list_users ( qs , 5 )
context [ ' facet ' ] = self . kwargs . get ( ' facet ' , ' ' )
works_unglued = qs . filter ( is_free = True ) . distinct ( ) | qs . filter ( campaigns__status = ' SUCCESSFUL ' ) . distinct ( )
context [ ' works_unglued ' ] = works_unglued [ : self . max_works ]
context [ ' works_active ' ] = qs . filter ( campaigns__status = ' ACTIVE ' ) . distinct ( ) [ : self . max_works ]
context [ ' works_wished ' ] = qs . filter ( is_free = False ) . exclude ( campaigns__status = ' ACTIVE ' ) . exclude ( campaigns__status = ' SUCCESSFUL ' ) . distinct ( ) [ : self . max_works ]
counts = { }
counts [ ' unglued ' ] = context [ ' works_unglued ' ] . count ( )
counts [ ' unglueing ' ] = context [ ' works_active ' ] . count ( )
counts [ ' wished ' ] = context [ ' works_wished ' ] . count ( )
context [ ' counts ' ] = counts
if counts [ ' unglueing ' ] :
context [ ' activetab ' ] = " #2 "
elif counts [ ' unglued ' ] :
context [ ' activetab ' ] = " #1 "
else :
context [ ' activetab ' ] = " #3 "
return context
2012-01-15 21:48:26 +00:00
2014-11-18 18:33:17 +00:00
class FacetedView ( FilterableListView ) :
template_name = " faceted_list.html "
def get_queryset_all ( self ) :
2014-11-21 02:11:15 +00:00
if not hasattr ( self , ' vertex ' ) :
facet_path = self . kwargs . get ( ' path ' , ' ' )
2014-12-05 23:36:45 +00:00
self . vertex = get_facet_object ( facet_path )
2016-08-15 19:22:32 +00:00
2014-11-18 21:54:19 +00:00
order_by = self . request . GET . get ( ' order_by ' , ' newest ' )
2015-01-26 19:46:37 +00:00
#special cases
if order_by == ' subjects ' :
return self . vertex . get_query_set ( ) . annotate ( kws = Count ( ' subjects ' ) ) . order_by ( ' kws ' )
2014-11-18 21:54:19 +00:00
return self . vertex . get_query_set ( ) . distinct ( ) . order_by ( * get_order_by ( order_by ) )
2014-11-18 18:33:17 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( FacetedView , self ) . get_context_data ( * * kwargs )
facet = self . kwargs . get ( ' facet ' , ' all ' )
2016-08-15 19:22:32 +00:00
qs = self . get_queryset ( )
2014-12-11 04:27:49 +00:00
if self . request . GET . has_key ( ' setkw ' ) and self . request . user . is_staff :
setkw = self . request . GET [ ' setkw ' ]
try :
context [ ' setkw ' ] = models . Subject . objects . get ( name = setkw )
except models . Subject . DoesNotExist :
pass
2014-11-18 18:33:17 +00:00
context [ ' activetab ' ] = " #1 "
context [ ' tab_override ' ] = ' tabs-1 '
2014-12-02 21:09:30 +00:00
context [ ' path ' ] = self . vertex . get_facet_path ( ) . replace ( ' // ' , ' / ' ) . strip ( ' / ' )
2014-11-21 02:11:15 +00:00
context [ ' vertex ' ] = self . vertex
2014-11-19 02:54:47 +00:00
context [ ' order_by ' ] = self . request . GET . get ( ' order_by ' , ' newest ' )
2015-04-11 12:25:41 +00:00
context [ ' view_as ' ] = self . request . GET . get ( ' view_as ' , None )
2014-11-18 18:33:17 +00:00
return context
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +00:00
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 ( )
2016-08-15 19:22:32 +00:00
2013-03-26 18:53:48 +00:00
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
2016-08-15 19:22:32 +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 ) :
2016-08-15 19:22:32 +00:00
context = super ( ByPubView , self ) . get_context_data ( * * kwargs )
context [ ' pubname ' ] = self . publisher_name
context [ ' publisher ' ] = self . publisher
context [ ' facet ' ] = self . kwargs . get ( ' facet ' , ' all ' )
2014-10-27 15:55:46 +00:00
2016-08-15 19:22:32 +00:00
return context
2013-03-05 21:18:54 +00:00
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 "
2016-08-15 19:22:32 +00:00
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 ' ) :
2014-12-14 15:00:10 +00:00
return models . Work . objects . filter ( is_free = True ) . 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 (
2014-12-14 15:00:10 +00:00
is_free = True ,
2014-05-08 14:22:35 +00:00
editions__ebooks__rights__in = cc . LICENSE_LIST
2013-12-26 00:37:54 +00:00
) . exclude ( campaigns__status = " SUCCESSFUL " ) . 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 (
2014-12-14 15:00:10 +00:00
is_free = True ,
2013-02-04 18:32:21 +00:00
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 )
2016-08-15 19:22:32 +00:00
qs = self . get_queryset ( )
context [ ' ungluers ' ] = userlists . work_list_users ( qs , 5 )
2013-02-04 15:09:08 +00:00
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
2014-05-22 18:08:15 +00:00
FACET_LABELS = {
' b2u ' : " Buy to Unglue " ,
' t4u ' : " Thanks for Ungluing " ,
' pledge ' : " Pledge to Unglue " ,
' unglued ' : " Successful " ,
}
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
2016-08-15 19:22:32 +00:00
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 ' ) :
2016-08-15 19:22:32 +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 ' )
2013-06-05 19:08:29 +00:00
elif ( facet == ' soon ' ) :
return models . Campaign . objects . filter ( status = ' INITIALIZED ' ) . order_by ( ' -work__num_wishes ' )
2014-04-30 00:03:33 +00:00
elif ( facet == ' b2u ' ) :
return models . Campaign . objects . filter ( status = ' ACTIVE ' , type = BUY2UNGLUE ) . annotate ( pledges = Count ( ' transaction ' ) ) . order_by ( ' -pledges ' )
elif ( facet == ' t4u ' ) :
return models . Campaign . objects . filter ( status = ' ACTIVE ' , type = THANKS ) . annotate ( pledges = Count ( ' transaction ' ) ) . order_by ( ' -pledges ' )
elif ( facet == ' pledge ' ) :
return models . Campaign . objects . filter ( status = ' ACTIVE ' , type = REWARDS ) . annotate ( pledges = Count ( ' transaction ' ) ) . order_by ( ' -pledges ' )
2014-05-22 18:08:15 +00:00
elif ( facet == ' unglued ' ) :
return models . Campaign . objects . filter ( status = ' SUCCESSFUL ' ) . annotate ( pledges = Count ( ' transaction ' ) ) . order_by ( ' -pledges ' )
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 ) :
2016-08-15 19:22:32 +00:00
context = super ( CampaignListView , self ) . get_context_data ( * * kwargs )
qs = self . get_queryset ( )
context [ ' ungluers ' ] = userlists . campaign_list_users ( qs , 5 )
facet = self . kwargs [ ' facet ' ]
context [ ' facet ' ] = facet
context [ ' facet_label ' ] = FACET_LABELS . get ( facet , ' Active ' )
return context
2012-08-07 18:12:50 +00:00
2012-12-13 03:35:35 +00:00
class MergeView ( FormView ) :
2016-08-15 19:22:32 +00:00
template_name = " merge.html "
work = None
2012-12-13 03:35:35 +00:00
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 )
2016-08-15 19:22:32 +00:00
2012-12-13 03:35:35 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( MergeView , self ) . get_context_data ( * * kwargs )
2016-08-15 19:22:32 +00:00
context [ ' work ' ] = self . work
2012-12-13 03:35:35 +00:00
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
2016-08-15 19:22:32 +00:00
2012-12-13 03:35:35 +00:00
def get_form_kwargs ( self ) :
2013-09-05 20:14:51 +00:00
self . work = safe_get_work ( self . kwargs [ " work_id " ] )
2016-08-15 19:22:32 +00:00
form_kwargs = { ' work ' : self . work }
2012-12-13 03:35:35 +00:00
if self . request . method == ' POST ' :
form_kwargs . update ( { ' data ' : self . request . POST } )
return form_kwargs
def form_valid ( self , form ) :
2016-08-15 19:22:32 +00:00
other_work = form . cleaned_data [ ' other_work ' ]
context = self . get_context_data ( )
2012-12-13 03:35:35 +00:00
if self . request . POST . has_key ( ' confirm_merge_works ' ) :
2016-08-15 19:22:32 +00:00
context [ ' old_work_id ' ] = other_work . id
2017-09-04 20:10:24 +00:00
self . work = merge_works ( self . work , other_work , self . request . user )
2016-08-15 19:22:32 +00:00
context [ ' merge_complete ' ] = True
2012-12-13 03:35:35 +00:00
else :
2016-08-15 19:22:32 +00:00
context [ ' form ' ] = WorkForm ( initial = { ' other_work ' : other_work } )
context [ ' other_work ' ] = other_work
2012-12-13 03:35:35 +00:00
return render ( self . request , self . template_name , context )
2013-12-13 20:15:35 +00:00
class GiftView ( TemplateView ) :
template_name = " gift.html "
2016-08-15 19:22:32 +00:00
def get ( self , request , * args , * * kwargs ) :
2012-08-14 01:00:28 +00:00
context = self . get_context_data ( )
2016-08-15 19:22:32 +00:00
context [ ' transfer_form ' ] = getTransferCreditForm ( self . request . user . credit . available )
2012-08-14 01:00:28 +00:00
return self . render_to_response ( context )
2016-08-15 19:22:32 +00:00
def post ( self , request , * args , * * kwargs ) :
2012-08-14 01:00:28 +00:00
context = self . get_context_data ( )
2016-08-15 19:22:32 +00:00
transfer_form = getTransferCreditForm ( self . request . user . credit . available , data = self . request . POST )
2012-08-14 01:00:28 +00:00
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. '
2016-08-15 19:22:32 +00:00
context [ ' recipient ' ] = transfer_form . cleaned_data [ ' recipient ' ]
2012-08-14 01:00:28 +00:00
context [ ' transfer_amount ' ] = transfer_form . cleaned_data [ ' amount ' ]
2016-08-15 19:22:32 +00:00
context [ ' transfer_form ' ] = getTransferCreditForm ( self . request . user . credit . available )
2012-08-14 01:00:28 +00:00
else :
#unsuccessful transfer
context [ ' transfer_message ' ] = ' Your transfer was not successful. '
2016-08-15 19:22:32 +00:00
context [ ' transfer_form ' ] = transfer_form
2012-08-14 01:00:28 +00:00
else :
#not valid
2016-08-15 19:22:32 +00:00
context [ ' transfer_form ' ] = transfer_form
2012-08-14 01:00:28 +00:00
return self . render_to_response ( context )
2016-08-15 19:22:32 +00:00
2012-08-07 18:12:50 +00:00
def get_context_data ( self , * args , * * kwargs ) :
2016-07-08 14:57:01 +00:00
context = { ' user ' : self . request . user }
2012-08-07 18:12:50 +00:00
return context
2016-08-15 19:22:32 +00:00
2011-11-28 23:39:06 +00:00
class PledgeView ( FormView ) :
2013-08-16 19:49:44 +00:00
action = " pledge "
2016-08-15 19:22:32 +00:00
template_name = " pledge.html "
2011-11-28 23:39:06 +00:00
form_class = CampaignPledgeForm
2012-08-31 07:16:04 +00:00
transaction = None
campaign = None
work = None
premiums = None
2013-09-09 13:54:16 +00:00
data = { }
2016-08-15 19:22:32 +00:00
2012-09-07 20:13:53 +00:00
def get_preapproval_amount ( self ) :
2016-07-25 15:32:04 +00:00
preapproval_amount = self . request . GET . get ( ' preapproval_amount ' , self . request . POST . get ( ' preapproval_amount ' , None ) )
2012-09-07 20:13:53 +00:00
if preapproval_amount :
return preapproval_amount
2016-07-25 15:32:04 +00:00
premium_id = self . request . GET . get ( ' premium_id ' , self . request . POST . get ( ' premium_id ' , None ) )
2012-09-07 20:13:53 +00:00
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 :
2016-08-15 19:22:32 +00:00
if preapproval_amount :
preapproval_amount = preapproval_amount if preapproval_amount > self . transaction . amount else self . transaction . amount
2012-09-07 21:11:25 +00:00
else :
preapproval_amount = self . transaction . amount
2012-09-07 20:13:53 +00:00
return preapproval_amount
2016-08-15 19:22:32 +00:00
2012-08-31 07:16:04 +00:00
def get_form_kwargs ( self ) :
2016-08-15 19:22:32 +00:00
2012-05-13 19:18:48 +00:00
assert self . request . user . is_authenticated ( )
2013-09-05 20:14:51 +00:00
self . work = safe_get_work ( self . kwargs [ " work_id " ] )
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +00:00
assert self . campaign . status == ' ACTIVE '
2012-08-31 07:16:04 +00:00
except Exception , e :
2013-08-20 02:54:43 +00:00
# this used to raise an exception, but that seemed pointless. This now has the effect of preventing any pledges.
return { }
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 )
2016-07-25 15:32:04 +00:00
premium_id = self . request . GET . get ( ' premium_id ' , self . request . POST . get ( ' premium_id ' , 150 ) )
2012-08-31 07:16:04 +00:00
if transactions . count ( ) == 0 :
2016-08-15 19:22:32 +00:00
ack_name = self . request . user . profile . ack_name
ack_dedication = ' '
anonymous = self . request . user . profile . anon_pref
2012-08-31 07:16:04 +00:00
else :
2016-08-15 19:22:32 +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
2013-08-18 19:21:55 +00:00
if self . transaction . extra :
ack_name = self . transaction . extra . get ( ' ack_name ' , self . request . user . profile . ack_name )
ack_dedication = self . transaction . extra . get ( ' ack_dedication ' , ' ' )
2012-10-23 13:37:00 +00:00
else :
ack_name = self . request . user . profile . ack_name
2013-08-18 19:21:55 +00:00
ack_dedication = ' '
2016-08-15 19:22:32 +00:00
anonymous = self . transaction . anonymous
2012-09-07 20:13:53 +00:00
2016-08-15 19:22:32 +00:00
self . data = { ' preapproval_amount ' : self . get_preapproval_amount ( ) , ' premium_id ' : premium_id ,
2012-09-07 21:11:25 +00:00
' 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 }
2016-08-15 19:22:32 +00:00
2012-08-31 07:16:04 +00:00
def get_context_data ( self , * * kwargs ) :
""" set up the pledge page """
2016-08-15 19:22:32 +00:00
2012-08-31 07:16:04 +00:00
context = super ( PledgeView , self ) . get_context_data ( * * kwargs )
2016-08-15 19:22:32 +00:00
2012-05-25 22:44:28 +00:00
context . update ( {
2012-08-31 07:16:04 +00:00
' work ' : self . work ,
2016-08-15 19:22:32 +00:00
' campaign ' : self . campaign ,
' premiums ' : self . premiums ,
' premium_id ' : self . data . get ( ' premium_id ' , None ) ,
' faqmenu ' : ' modify ' if self . transaction else ' pledge ' ,
2012-08-31 07:16:04 +00:00
' 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
} )
2016-08-15 19:22:32 +00:00
2011-11-28 23:39:06 +00:00
return context
2016-08-15 19:22:32 +00:00
2011-11-28 23:39:06 +00:00
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
2016-08-15 19:22:32 +00:00
2012-08-31 07:16:04 +00:00
p = PaymentManager ( )
if self . transaction :
# modifying the transaction...
2016-08-15 19:22:32 +00:00
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 %s for %s " % ( self . action , self . campaign . name ) ,
pledge_extra = form . trans_extra
2012-08-31 07:16:04 +00:00
)
logger . info ( " status: {0} , url: {1} " . format ( status , url ) )
2016-08-15 19:22:32 +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 :
2016-08-15 19:22:32 +00:00
t , url = p . process_transaction ( ' USD ' , form . amount ( ) ,
host = PAYMENT_HOST_NONE ,
campaign = self . campaign ,
2012-08-31 07:16:04 +00:00
user = self . request . user ,
2016-08-15 19:22:32 +00:00
paymentReason = " Unglue.it Pledge for {0} " . format ( self . campaign . name ) ,
2013-08-16 19:49:44 +00:00
pledge_extra = form . trans_extra
2016-08-15 19:22:32 +00:00
)
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
2016-08-15 19:22:32 +00:00
class PurchaseView ( PledgeView ) :
template_name = " purchase.html "
2013-08-16 19:49:44 +00:00
form_class = CampaignPurchaseForm
action = " purchase "
2013-08-27 22:03:35 +00:00
offer_id = None
2013-08-16 19:49:44 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( PledgeView , self ) . get_context_data ( * * kwargs )
context . update ( {
' work ' : self . work ,
2016-08-15 19:22:32 +00:00
' campaign ' : self . campaign ,
' faqmenu ' : ' purchase ' ,
2013-08-16 19:49:44 +00:00
' transaction ' : self . transaction ,
' tid ' : self . transaction . id if self . transaction else None ,
2013-08-27 22:03:35 +00:00
' cover_width ' : cover_width ( self . work ) ,
' offer_id ' : self . offer_id ,
2013-10-15 02:51:48 +00:00
' user_license ' : self . work . get_user_license ( self . request . user ) ,
2014-12-15 05:56:08 +00:00
' give ' : self . give
2013-08-16 19:49:44 +00:00
} )
2016-08-15 19:22:32 +00:00
2013-08-16 19:49:44 +00:00
return context
2013-08-20 02:54:43 +00:00
def get_form_kwargs ( self ) :
assert self . request . user . is_authenticated ( )
2013-09-05 20:14:51 +00:00
self . work = safe_get_work ( self . kwargs [ " work_id " ] )
2016-08-15 19:22:32 +00:00
2013-08-20 02:54:43 +00:00
# if there is no campaign or if campaign is not active, we should raise an error
try :
self . campaign = self . work . last_campaign ( )
# Campaign must be ACTIVE
2016-08-15 19:22:32 +00:00
assert self . campaign . status == ' ACTIVE '
2013-08-20 02:54:43 +00:00
except Exception , e :
# this used to raise an exception, but that seemed pointless. This now has the effect of preventing any pledges.
return { }
self . data = {
' preapproval_amount ' : self . get_preapproval_amount ( ) ,
2013-08-27 22:03:35 +00:00
' anonymous ' : self . request . user . profile . anon_pref ,
2015-04-15 22:31:46 +00:00
' offer_id ' : self . offer_id ,
2013-08-20 02:54:43 +00:00
}
if self . request . method == ' POST ' :
2016-07-12 13:00:32 +00:00
data = self . request . POST . dict ( )
data . update ( self . data )
self . data = data
2014-12-16 19:18:51 +00:00
self . data [ ' give ' ] = self . give
2013-08-20 02:54:43 +00:00
if not self . request . POST . has_key ( ' anonymous ' ) :
del self . data [ ' anonymous ' ]
return { ' data ' : self . data }
else :
return { ' initial ' : self . data }
def get_preapproval_amount ( self ) :
2016-07-25 15:32:04 +00:00
self . offer_id = self . request . GET . get ( ' offer_id ' , self . request . POST . get ( ' offer_id ' , None ) )
2014-12-18 06:07:59 +00:00
self . give = self . offer_id . startswith ( ' give ' ) if self . offer_id else False
2014-12-16 19:18:51 +00:00
if self . give :
self . offer_id = self . offer_id [ 4 : ]
2014-02-21 18:16:55 +00:00
if not self . offer_id and self . work . last_campaign ( ) and self . work . last_campaign ( ) . individual_offer :
2013-10-11 21:50:54 +00:00
self . offer_id = self . work . last_campaign ( ) . individual_offer . id
2013-08-22 20:12:27 +00:00
preapproval_amount = None
2013-08-27 22:03:35 +00:00
if self . offer_id != None :
2013-08-20 02:54:43 +00:00
try :
2013-08-27 22:03:35 +00:00
preapproval_amount = D ( models . Offer . objects . get ( id = self . offer_id ) . price )
2013-08-20 02:54:43 +00:00
except :
preapproval_amount = None
return preapproval_amount
def form_valid ( self , form ) :
p = PaymentManager ( )
2016-08-15 19:22:32 +00:00
t , url = p . process_transaction ( ' USD ' , form . amount ( ) ,
host = PAYMENT_HOST_NONE ,
campaign = self . campaign ,
2013-08-20 02:54:43 +00:00
user = self . request . user ,
2016-08-15 19:22:32 +00:00
paymentReason = " Unglue.it Purchase for {0} " . format ( self . campaign . name ) ,
2013-08-20 02:54:43 +00:00
pledge_extra = form . trans_extra
2016-08-15 19:22:32 +00:00
)
2013-08-20 02:54:43 +00:00
if 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. " )
2016-08-15 19:22:32 +00:00
2017-02-13 18:33:26 +00:00
class NewDonationView ( FormView ) :
template_name = " fund_the_pledge.html "
form_class = DonationForm
def form_valid ( self , form ) :
p = PaymentManager ( )
t , url = p . process_transaction ( ' USD ' , form . cleaned_data [ " amount " ] ,
user = self . request . user ,
paymentReason = " Donation to {} " . format ( COMPANY_TITLE ) ,
)
if url :
return HttpResponseRedirect ( url )
else :
logger . error ( " Attempt to produce transaction id {0} failed " . format ( t . id ) )
return HttpResponse ( " Our attempt to set up your donation failed. We have logged this problem. " )
2013-08-20 02:52:22 +00:00
class FundView ( FormView ) :
2016-08-15 19:22:32 +00:00
template_name = " fund_the_pledge.html "
2012-09-06 05:01:17 +00:00
transaction = None
2013-08-20 02:54:43 +00:00
action = None
2016-08-15 19:22:32 +00:00
2014-02-20 03:18:23 +00:00
def get_form_class ( self ) :
if self . request . user . is_anonymous ( ) :
return AnonCCForm
2014-09-13 20:19:47 +00:00
elif self . request . user . profile . account :
return AccountCCForm
2014-02-20 03:18:23 +00:00
else :
return CCForm
2012-03-19 23:32:37 +00:00
2012-09-06 05:01:17 +00:00
def get_form_kwargs ( self ) :
2013-08-20 02:52:22 +00:00
kwargs = super ( FundView , self ) . get_form_kwargs ( )
2017-02-13 18:33:26 +00:00
if kwargs . has_key ( ' data ' ) :
data = kwargs [ ' data ' ] . copy ( )
kwargs [ ' data ' ] = data
else :
data = { }
kwargs [ ' initial ' ] = data
2017-07-25 12:14:05 +00:00
t_id = self . kwargs [ " t_id " ]
2012-09-06 05:01:17 +00:00
if self . transaction is None :
2017-02-13 18:33:26 +00:00
self . transaction = get_object_or_404 ( Transaction , id = t_id )
2012-10-13 17:45:46 +00:00
2017-02-13 18:33:26 +00:00
if not self . transaction . campaign :
self . action = ' donation '
elif self . transaction . campaign . type == REWARDS :
2014-02-20 03:18:23 +00:00
self . action = ' pledge '
elif self . transaction . campaign . type == THANKS :
self . action = ' contribution '
else :
self . action = ' purchase '
2013-08-20 02:54:43 +00:00
2016-08-15 19:22:32 +00:00
2012-09-10 20:17:30 +00:00
data . update (
2013-12-15 05:31:06 +00:00
{ ' preapproval_amount ' : self . transaction . needed_amount ,
2017-02-13 18:33:26 +00:00
' username ' : self . request . user . username if self . request . user . is_authenticated ( ) else None ,
2017-10-28 22:33:58 +00:00
' work_id ' : self . transaction . campaign . work_id if self . transaction . campaign else None ,
2017-02-13 18:33:26 +00:00
' title ' : self . transaction . campaign . work . title if self . transaction . campaign else COMPANY_TITLE }
2016-08-15 19:22:32 +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 ) :
2013-08-20 02:52:22 +00:00
context = super ( FundView , self ) . get_context_data ( * * kwargs )
2016-08-15 19:22:32 +00:00
context [ ' modified ' ] = self . transaction . status == TRANSACTION_STATUS_MODIFIED
context [ ' preapproval_amount ' ] = self . transaction . max_amount
2013-12-15 05:31:06 +00:00
context [ ' needed ' ] = self . transaction . needed_amount
2016-08-15 19:22:32 +00:00
context [ ' transaction ' ] = self . transaction
2012-09-11 22:17:37 +00:00
context [ ' STRIPE_PK ' ] = stripelib . STRIPE_PK
2013-08-20 02:54:43 +00:00
context [ ' action ' ] = self . action
2012-03-19 23:32:37 +00:00
return context
2016-08-15 19:22:32 +00:00
2012-03-19 23:32:37 +00:00
def form_valid ( self , form ) :
2012-09-22 00:40:33 +00:00
p = PaymentManager ( )
2014-09-13 20:19:47 +00:00
stripe_token = form . cleaned_data . get ( " stripe_token " , None )
2012-10-13 17:45:46 +00:00
self . transaction . host = settings . PAYMENT_PROCESSOR
2016-08-15 19:22:32 +00:00
return_url = " %s ?tid= %s " % ( reverse ( ' pledge_complete ' ) , self . transaction . id )
2014-02-20 03:18:23 +00:00
2017-02-13 18:33:26 +00:00
if not self . transaction . campaign :
if self . request . user . is_authenticated ( ) :
self . transaction . user = self . request . user
# if there's an email address, put it in the receipt column, so far unused.
self . transaction . receipt = form . cleaned_data . get ( " email " , None )
t , url = p . charge ( self . transaction , return_url = return_url , token = stripe_token )
2017-07-25 12:14:05 +00:00
2017-02-13 18:33:26 +00:00
elif self . transaction . campaign . type == THANKS and self . transaction . user == None :
2014-02-20 03:18:23 +00:00
#anonymous user, just charge the card!
2014-05-05 16:21:44 +00:00
if self . request . user . is_authenticated ( ) :
self . transaction . user = self . request . user
2014-02-20 03:18:23 +00:00
# if there's an email address, put it in the receipt column, so far unused.
2016-08-15 19:22:32 +00:00
self . transaction . receipt = form . cleaned_data . get ( " email " , None )
t , url = p . charge ( self . transaction , return_url = return_url , token = stripe_token )
2014-02-20 03:18:23 +00:00
elif self . request . user . is_anonymous ( ) :
#somehow the user lost their login
return HttpResponseRedirect ( reverse ( ' superlogin ' ) )
elif self . transaction . user . id != self . request . user . id :
# other sort of strange trouble!
2016-08-15 19:22:32 +00:00
return render ( self . request , " pledge_user_error.html " , { ' transaction ' : self . transaction , ' action ' : self . action } )
2013-08-20 02:54:43 +00:00
else :
2014-02-20 03:18:23 +00:00
# if the user has active account, use it. Otherwise...
if not self . request . user . profile . account :
2016-08-15 19:22:32 +00:00
2014-02-20 03:18:23 +00:00
# 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 :
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 } )
# with the Account in hand, now do the transaction
if self . action == ' pledge ' :
2016-08-15 19:22:32 +00:00
t , url = p . authorize ( self . transaction , return_url = return_url )
2014-02-20 03:18:23 +00:00
else :
2016-08-15 19:22:32 +00:00
t , url = p . charge ( self . transaction , return_url = return_url )
2013-12-15 05:31:06 +00:00
# redirecting user to pledge_complete/payment_complete on successful preapproval (in the case of stripe)
2012-09-25 18:52:56 +00:00
if url is not None :
return HttpResponseRedirect ( url )
2012-10-13 04:46:34 +00:00
else :
2016-08-15 19:22:32 +00:00
return render ( self . request , " pledge_card_error.html " , { ' transaction ' : self . transaction } )
2013-12-13 20:15:35 +00:00
class GiftCredit ( TemplateView ) :
2016-08-15 19:22:32 +00:00
template_name = " gift_credit.html "
2012-07-10 20:36:32 +00:00
2012-09-06 05:01:17 +00:00
def get_context_data ( self , * * kwargs ) :
2013-12-13 20:15:35 +00:00
context = super ( GiftCredit , self ) . get_context_data ( * * kwargs )
2016-08-15 19:22:32 +00:00
context [ ' faqmenu ' ] = " gift "
2012-09-06 05:01:17 +00:00
try :
2016-08-15 19:22:32 +00:00
envelope = signing . loads ( kwargs [ ' token ' ] )
context [ ' envelope ' ] = envelope
2012-09-06 05:01:17 +00:00
except signing . BadSignature :
2016-08-15 19:22:32 +00:00
self . template_name = " gift_error.html "
2012-09-06 05:01:17 +00:00
return context
try :
work = models . Work . objects . get ( id = envelope [ ' work_id ' ] )
2016-08-15 19:22:32 +00:00
campaign = work . last_campaign ( )
2012-09-06 05:01:17 +00:00
except models . Work . DoesNotExist :
campaign = None
2016-08-15 19:22:32 +00:00
context [ ' work ' ] = work
2012-09-06 05:01:17 +00:00
try :
user = User . objects . get ( username = envelope [ ' username ' ] )
except User . DoesNotExist :
2016-08-15 19:22:32 +00:00
self . template_name = " gift_user_error.html "
context [ ' error ' ] = ' user does not exist '
2012-09-06 05:01:17 +00:00
return context
if user != self . request . user :
2016-08-15 19:22:32 +00:00
self . template_name = " gift_user_error.html "
context [ ' error ' ] = ' wrong user logged in '
2012-09-06 05:01:17 +00:00
return context
try :
# check token not used
CreditLog . objects . get ( sent = envelope [ ' sent ' ] )
2016-08-15 19:22:32 +00:00
context [ ' error ' ] = ' credit already registered '
2012-09-06 05:01:17 +00:00
return context
except CreditLog . DoesNotExist :
#not used yet!
2016-08-15 19:22:32 +00:00
amount = envelope [ ' amount ' ] + envelope [ ' cents ' ] / D ( 100 )
CreditLog . objects . create ( user = user , amount = amount , action = ' deposit ' , sent = envelope [ ' sent ' ] )
ts = Transaction . objects . filter ( user = user , campaign = campaign , status = TRANSACTION_STATUS_NONE ) . order_by ( ' -pk ' )
2012-09-06 20:55:32 +00:00
if ts . count ( ) == 0 :
2016-08-15 19:22:32 +00:00
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 :
2016-08-15 19:22:32 +00:00
t = ts [ 0 ]
credit_transaction ( t , user , amount )
2012-09-06 05:01:17 +00:00
for t in ts [ 1 : ] :
2016-08-15 19:22:32 +00:00
t . status = TRANSACTION_STATUS_CANCELED
2012-09-06 05:01:17 +00:00
t . save ( )
2016-08-15 19:22:32 +00:00
context [ ' transaction ' ] = t
2012-09-06 05:01:17 +00:00
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
2016-08-15 19:22:32 +00:00
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
"""
2016-08-15 19:22:32 +00:00
template_name = " pledge_recharge.html "
2012-07-10 20:36:32 +00:00
def get_context_data ( self , * * kwargs ) :
2016-08-15 19:22:32 +00:00
2012-07-12 02:51:36 +00:00
context = super ( PledgeRechargeView , self ) . get_context_data ( * * kwargs )
2016-08-15 19:22: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
2016-08-15 19:22:32 +00:00
2013-09-05 20:14:51 +00:00
work = safe_get_work ( self . kwargs [ " work_id " ] )
2012-07-13 17:17:51 +00:00
campaign = work . last_campaign ( )
2016-08-15 19:22:32 +00:00
2012-07-13 17:17:51 +00:00
if campaign is None :
return Http404
2016-08-15 19:22:32 +00:00
2012-07-13 17:17:51 +00:00
transaction = campaign . transaction_to_recharge ( user )
2016-08-15 19:22:32 +00:00
2012-07-13 17:17:51 +00:00
# calculate a URL to do a preapproval -- in the future, we may want to do a straight up payment
2016-08-15 19:22:32 +00:00
2012-07-13 22:55:41 +00:00
return_url = None
nevermind_url = None
2016-08-15 19:22:32 +00:00
2012-07-13 22:55:41 +00:00
if transaction is not None :
2016-08-15 19:22:32 +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 )
2016-08-15 19:22:32 +00:00
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
2016-08-15 19:22:32 +00:00
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
2016-08-15 19:22:32 +00:00
2012-07-10 20:36:32 +00:00
2013-08-20 02:52:22 +00:00
class FundCompleteView ( TemplateView ) :
""" A callback for Payment to tell unglue.it that a payment transaction has completed successfully.
2016-08-15 19:22:32 +00:00
2012-01-11 01:15:39 +00:00
Possible things to implement :
2016-08-15 19:22:32 +00:00
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
2016-08-15 19:22:32 +00:00
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
"""
2016-08-15 19:22:32 +00:00
template_name = " pledge_complete.html "
2014-02-20 03:18:23 +00:00
def get ( self , request , * args , * * kwargs ) :
context = self . get_context_data ( * * kwargs )
2016-08-15 19:22:32 +00:00
2014-07-22 20:27:55 +00:00
if self . transaction :
2017-02-13 18:33:26 +00:00
if not self . transaction . campaign :
2017-07-25 12:14:05 +00:00
return self . render_to_response ( context )
2014-07-22 20:27:55 +00:00
if self . transaction . campaign . type == THANKS :
return DownloadView . as_view ( ) ( request , work = self . transaction . campaign . work )
2016-08-15 19:22:32 +00:00
2014-02-21 18:16:55 +00:00
else :
2017-02-13 18:48:17 +00:00
if request . user . is_authenticated ( ) :
2014-07-22 20:27:55 +00:00
if self . user_is_ok ( ) :
return self . render_to_response ( context )
else :
2017-10-28 22:33:58 +00:00
return HttpResponseRedirect ( reverse ( ' work ' , kwargs = { ' work_id ' : self . transaction . campaign . work_id } ) )
2014-07-22 20:27:55 +00:00
else :
return redirect_to_login ( request . get_full_path ( ) )
else :
return HttpResponseRedirect ( reverse ( ' home ' ) )
2016-08-15 19:22:32 +00:00
2014-07-22 20:27:55 +00:00
def user_is_ok ( self ) :
if not self . transaction :
2016-08-15 19:22:32 +00:00
return False
2017-02-13 18:33:26 +00:00
if ( not self . transaction . campaign or self . transaction . campaign . type == THANKS ) and self . transaction . user == None :
2014-07-22 20:27:55 +00:00
# to handle anonymous donors- leakage not an issue
return True
2016-08-15 19:22:32 +00:00
else :
2017-10-28 22:33:58 +00:00
return self . request . user . id == self . transaction . user_id
2016-08-15 19:22:32 +00:00
2014-02-20 03:18:23 +00:00
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
2013-08-20 02:52:22 +00:00
context = super ( FundCompleteView , self ) . get_context_data ( )
2014-07-22 20:27:55 +00:00
self . transaction = None
2016-08-15 19:22:32 +00:00
2014-07-22 20:27:55 +00:00
# pull out the transaction id and try to get the corresponding Transaction
2016-08-15 19:22:32 +00:00
transaction_id = self . request . POST . get ( " tid " , self . request . GET . get ( " tid " , None ) )
2014-07-22 20:27:55 +00:00
if not transaction_id :
2014-07-22 00:37:28 +00:00
return context
2014-07-22 20:27:55 +00:00
try :
self . transaction = Transaction . objects . get ( id = transaction_id )
2014-07-23 17:07:49 +00:00
except ( ValueError , Transaction . DoesNotExist ) :
2014-07-22 20:27:55 +00:00
self . transaction = None
2016-08-15 19:22:32 +00:00
2014-07-22 20:27:55 +00:00
if not self . transaction :
2014-07-22 00:37:28 +00:00
return context
2016-08-15 19:22:32 +00:00
2012-01-11 01:15:39 +00:00
# work and campaign in question
try :
2014-07-22 20:27:55 +00:00
campaign = self . transaction . campaign
2012-01-11 01:15:39 +00:00
work = campaign . work
except Exception , e :
campaign = None
work = None
2016-08-15 19:22:32 +00:00
2014-07-22 00:37:28 +00:00
# # we need to check whether the user tied to the transaction is indeed the authenticated user.
2016-08-15 19:22:32 +00:00
2014-07-22 20:27:55 +00:00
if not self . user_is_ok ( ) :
2014-07-22 00:37:28 +00:00
return context
2016-08-15 19:22:32 +00:00
2014-12-18 18:37:28 +00:00
gift = self . transaction . extra . has_key ( ' give_to ' )
2014-12-18 16:41:06 +00:00
if not gift :
# add the work corresponding to the Transaction on the user's wishlist if it's not already on the wishlist
if self . transaction . user is not None and ( campaign is not None ) and ( work is not None ) :
self . transaction . user . wishlist . add_work ( work , ' pledging ' , notify = True )
2014-05-05 14:15:05 +00:00
#put info into session for download page to pick up.
2016-08-15 19:22:32 +00:00
self . request . session [ ' amount ' ] = int ( self . transaction . amount * 100 )
2014-12-18 16:41:06 +00:00
if self . transaction . receipt :
2016-08-15 19:22:32 +00:00
self . request . session [ ' receipt ' ] = self . transaction . receipt
2014-07-22 20:27:55 +00:00
context [ " transaction " ] = self . transaction
2012-01-11 01:15:39 +00:00
context [ " work " ] = work
context [ " campaign " ] = campaign
2012-02-21 14:24:23 +00:00
context [ " faqmenu " ] = " complete "
2012-05-14 20:56:36 +00:00
context [ " site " ] = Site . objects . get_current ( )
2016-08-15 19:22:32 +00:00
return context
2012-09-07 21:48:48 +00:00
2013-08-20 02:52:22 +00:00
class PledgeModifiedView ( FundCompleteView ) :
2012-09-07 21:48:48 +00:00
def get_context_data ( self ) :
context = super ( PledgeModifiedView , self ) . get_context_data ( )
2016-08-15 19:22:32 +00:00
context [ ' modified ' ] = True
2012-09-07 21:48:48 +00:00
return context
2016-08-15 19:22:32 +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 """
2016-08-15 19:22:32 +00:00
template_name = " pledge_cancel.html "
2012-05-21 14:56:18 +00:00
form_class = PledgeCancelForm
2016-08-15 19:22:32 +00:00
2012-05-21 14:56:18 +00:00
def get_context_data ( self , * * kwargs ) :
context = super ( PledgeCancelView , self ) . get_context_data ( * * kwargs )
2016-08-15 19:22:32 +00:00
2012-05-23 14:22:48 +00:00
# initialize error to be None
context [ " error " ] = None
2016-08-15 19:22:32 +00:00
2012-05-21 14:56:18 +00:00
# the following should be true since PledgeCancelView.as_view is wrapped in login_required
2016-08-15 19:22:32 +00:00
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
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +00:00
2012-05-21 14:56:18 +00:00
work = campaign . work
transactions = campaign . transactions ( ) . filter ( user = user , status = TRANSACTION_STATUS_ACTIVE )
2016-08-15 19:22:32 +00:00
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
2016-08-15 19:22:32 +00:00
2012-05-23 14:22:48 +00:00
# we've located the transaction, work, and campaign referenced in the view
2016-08-15 19:22:32 +00:00
2012-05-18 23:59:48 +00:00
context [ " transaction " ] = transaction
context [ " work " ] = work
context [ " campaign " ] = campaign
context [ " faqmenu " ] = " cancel "
2016-08-15 19:22:32 +00:00
2012-05-18 23:59:48 +00:00
return context
2016-08-15 19:22:32 +00:00
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
2016-08-15 19:22:32 +00:00
2012-05-23 14:22:48 +00:00
logger . info ( " arrived at pledge_cancel form_valid " )
# pull campaign_id from form, not from URI as we do from GET
2016-08-15 19:22:32 +00:00
campaign_id = self . request . POST . get ( ' campaign_id ' , self . request . GET . 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. " )
2016-08-15 19:22:32 +00:00
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 ) )
2017-10-28 22:33:58 +00:00
return HttpResponseRedirect ( reverse ( ' work ' , kwargs = { ' work_id ' : campaign . work_id } ) )
2012-05-23 16:12:21 +00:00
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 ) )
2016-08-15 19:22:32 +00:00
return HttpResponse ( " Sorry, something went wrong in canceling your campaign pledge. We have logged this error. " )
2016-10-05 19:36:20 +00:00
def works_user_can_admin ( user ) :
return models . Work . objects . filter (
Q ( claim__user = user ) | Q ( claim__rights_holder__owner = user )
)
2017-05-02 21:10:06 +00:00
def works_user_can_admin_filter ( request , work_id ) :
2016-10-05 19:36:20 +00:00
def work_survey_filter ( answers ) :
works = works_user_can_admin ( request . user )
if work_id == ' 0 ' and request . user . is_staff :
return answers
elif work_id :
work = safe_get_work ( work_id )
if user_can_edit_work ( request . user , work ) :
return answers . filter ( run__run_info_histories__landing__works = work )
else :
return answers . none ( )
else :
return answers . filter ( run__run_info_histories__landing__works__in = works )
2017-05-02 21:10:06 +00:00
return work_survey_filter
def export_surveys ( request , qid , work_id ) :
2016-10-05 19:36:20 +00:00
def extra_entries ( subject , run ) :
2017-05-19 17:46:12 +00:00
landing = completed = None
2016-10-05 19:36:20 +00:00
try :
landing = run . run_info_histories . all ( ) [ 0 ] . landing
2017-05-19 17:46:12 +00:00
completed = run . run_info_histories . all ( ) [ 0 ] . completed
2016-10-05 19:36:20 +00:00
except IndexError :
try :
landing = run . run_infos . all ( ) [ 0 ] . landing
2017-05-19 17:46:12 +00:00
completed = run . run_infos . all ( ) [ 0 ] . created
2016-10-05 19:36:20 +00:00
except IndexError :
label = wid = " error "
if landing :
label = landing . label
wid = landing . object_id
2017-05-19 17:46:12 +00:00
return [ wid , subject . ip_address , run . id , completed , label ]
2016-10-05 19:36:20 +00:00
if not request . user . is_authenticated ( ) :
return HttpResponseRedirect ( reverse ( ' surveys ' ) )
2017-05-19 17:46:12 +00:00
extra_headings = [ u ' work id ' , u ' subject ip address ' , u ' run id ' , u ' date completed ' , u ' landing label ' ]
2016-10-05 19:36:20 +00:00
return export_answers ( request , qid ,
2017-05-02 21:10:06 +00:00
answer_filter = works_user_can_admin_filter ( request , work_id ) ,
2016-10-05 19:36:20 +00:00
extra_entries = extra_entries ,
extra_headings = extra_headings ,
filecode = work_id )
2017-05-02 21:10:06 +00:00
def surveys_summary ( request , qid , work_id ) :
if not request . user . is_authenticated ( ) :
return HttpResponseRedirect ( reverse ( ' surveys ' ) )
return answer_summary (
2017-06-08 21:35:48 +00:00
request ,
2017-05-02 21:10:06 +00:00
qid ,
answer_filter = works_user_can_admin_filter ( request , work_id ) ,
)
2017-07-25 12:14:05 +00:00
2017-10-22 01:18:32 +00:00
2016-05-26 16:19:33 +00:00
def new_survey ( request , work_id ) :
if not request . user . is_authenticated ( ) :
return HttpResponseRedirect ( reverse ( ' surveys ' ) )
2016-10-05 19:36:20 +00:00
my_works = works_user_can_admin ( request . user )
2016-05-26 16:19:33 +00:00
if work_id :
2016-10-05 19:36:20 +00:00
work = safe_get_work ( work_id )
2016-05-26 16:19:33 +00:00
for my_work in my_works :
2016-08-15 19:22:32 +00:00
if my_work == work :
form = SurveyForm ( )
2016-05-26 16:19:33 +00:00
break
else :
return HttpResponseRedirect ( reverse ( ' surveys ' ) )
else :
work = None
form = SurveyForm ( )
2016-08-15 19:22:32 +00:00
if request . method == ' POST ' :
form = SurveyForm ( data = request . POST )
2016-05-26 16:19:33 +00:00
if form . is_valid ( ) :
if not work and form . work :
for my_work in my_works :
2017-10-28 22:33:58 +00:00
print ' {} {} ' . format ( my_work . id , form . work_id )
2016-08-15 19:22:32 +00:00
if my_work == form . work :
2016-05-26 16:19:33 +00:00
work = form . work
break
else :
print ' not mine '
return HttpResponseRedirect ( reverse ( ' surveys ' ) )
print " create landing "
landing = Landing . objects . create ( label = form . cleaned_data [ ' label ' ] , questionnaire = form . cleaned_data [ ' survey ' ] , content_object = work )
return HttpResponseRedirect ( reverse ( ' surveys ' ) )
return render ( request , " manage_survey.html " , { " work " : work , " form " : form } )
def surveys ( request ) :
if not request . user . is_authenticated ( ) :
return render ( request , " surveys.html " )
2016-10-05 19:36:20 +00:00
works = works_user_can_admin ( request . user )
work_ids = [ work . id for work in works ]
2016-10-17 17:37:22 +00:00
surveys = Questionnaire . objects . filter ( landings__object_id__in = work_ids ) . distinct ( )
2016-10-05 19:36:20 +00:00
return render ( request , " surveys.html " , { " works " : works , " surveys " : surveys } )
2016-08-15 19:22:32 +00:00
2011-12-20 22:42:06 +00:00
def campaign_admin ( request ) :
if not request . user . is_authenticated ( ) :
2016-08-15 19:22:32 +00:00
return render ( request , " admins_only.html " )
2011-12-20 22:42:06 +00:00
if not request . user . is_staff :
return render ( request , " admins_only.html " )
2016-08-15 19:22:32 +00:00
2011-12-20 22:42:06 +00:00
context = { }
2016-08-15 19:22:32 +00:00
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')
2016-08-15 19:22:32 +00:00
2012-04-25 17:55:30 +00:00
campaigns_with_active_transactions = models . Campaign . objects . filter ( transaction__status = TRANSACTION_STATUS_ACTIVE )
2016-08-15 19:22:32 +00:00
2011-12-21 22:32:08 +00:00
# pull out Campaigns with Transactions that are INCOMPLETE
2016-08-15 19:22:32 +00:00
2012-04-25 17:55:30 +00:00
campaigns_with_incomplete_transactions = models . Campaign . objects . filter ( transaction__status = TRANSACTION_STATUS_INCOMPLETE )
2016-08-15 19:22:32 +00:00
2011-12-21 22:32:08 +00:00
# show all Campaigns with Transactions that are COMPLETED
2016-08-15 19:22:32 +00:00
2012-05-04 14:30:05 +00:00
campaigns_with_completed_transactions = models . Campaign . objects . filter ( transaction__status = TRANSACTION_STATUS_COMPLETE )
2016-08-15 19:22:32 +00:00
2011-12-21 22:32:08 +00:00
# show Campaigns with Transactions that are CANCELED
2016-08-15 19:22:32 +00:00
2012-04-25 20:10:53 +00:00
campaigns_with_canceled_transactions = models . Campaign . objects . filter ( transaction__status = TRANSACTION_STATUS_CANCELED )
2016-08-15 19:22:32 +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 )
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +00:00
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 " ] :
2016-08-15 19:22:32 +00:00
info = " , " . join ( [ " %s : %s " % ( k , v ) for ( k , v ) in t . items ( ) ] )
2011-12-23 01:34:24 +00:00
check_status_results + = " <p>Payment updated: %s </p> " % ( info )
2016-08-15 19:22:32 +00:00
2011-12-23 01:34:24 +00:00
else :
2016-08-15 19:22:32 +00:00
check_status_results + = " <p>No payments needed updating</p> "
2011-12-23 01:34:24 +00:00
command_status = _ ( " Transactions updated based on PaymentDetails and PreapprovalDetails " )
2011-12-21 22:32:08 +00:00
except Exception , e :
check_status_results = e
2016-08-15 19:22:32 +00:00
elif ' execute_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 . 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 :
2016-08-15 19:22:32 +00:00
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 :
2016-08-15 19:22:32 +00:00
command_status = " Error in canceling transactions for campaign %s " % ( str ( e ) )
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 ( )
2016-08-15 19:22:32 +00:00
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
2013-10-17 16:44:47 +00:00
def supporter ( request , supporter_username , template_name , extra_context = { } ) :
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_unglued = [ ]
works_active = [ ]
works_wished = [ ]
2012-12-31 18:46:23 +00:00
works_on_wishlist = wishlist . works . all ( )
2016-08-15 19:22:32 +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 ( )
2014-12-14 15:00:10 +00:00
works_otherwise_available = works_on_wishlist . filter ( is_free = True ) . distinct ( )
2012-12-31 18:46:23 +00:00
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 ( )
2016-08-15 19:22:32 +00:00
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 ' )
2016-08-15 19:22:32 +00:00
2013-12-14 18:24:29 +00:00
slidelist = [ ]
2012-03-07 18:23:34 +00:00
# badge counts
backed = works_unglued . count ( )
backing = works_active . count ( )
wished = works_wished . count ( )
2016-08-15 19:22:32 +00:00
else :
2012-03-07 18:23:34 +00:00
backed = 0
backing = 0
wished = 0
2013-12-14 18:24:29 +00:00
slidelist = slideshow ( )
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 "
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +00:00
profile_obj = request . user . profile
2011-11-17 00:47:29 +00:00
2016-08-15 19:22:32 +00:00
if request . method == ' POST ' :
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 ' ] :
2016-08-15 19:22:32 +00:00
profile_obj . facebook_id = 0
2013-03-18 18:56:27 +00:00
if profile_obj . avatar_source == models . FACEBOOK :
2014-11-07 19:47:12 +00:00
profile_obj . avatar_source = models . UNGLUEITAR
2011-11-14 18:23:14 +00:00
if profile_form . cleaned_data [ ' clear_twitter ' ] :
2016-08-15 19:22:32 +00:00
profile_obj . twitter_id = " "
2013-03-18 18:56:27 +00:00
if profile_obj . avatar_source == models . TWITTER :
2014-11-07 19:47:12 +00:00
profile_obj . avatar_source = models . UNGLUEITAR
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 :
2016-08-15 19:22:32 +00:00
profile_form = ProfileForm ( instance = profile_obj )
2011-10-19 16:55:48 +00:00
else :
profile_form = ' '
2011-11-17 00:47:29 +00:00
2013-06-10 13:29:18 +00:00
process_kindle_email ( request )
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 ,
2013-12-14 18:24:29 +00:00
" slidelist " : slidelist ,
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 ,
2016-08-15 19:22:32 +00:00
" ungluers " : userlists . other_users ( supporter , 5 ) ,
2013-10-08 19:37:22 +00:00
" activetab " : activetab ,
2011-10-19 07:13:29 +00:00
}
2013-10-17 16:44:47 +00:00
context . update ( extra_context )
2011-11-03 20:28:53 +00:00
return render ( request , template_name , context )
2011-10-03 16:36:04 +00:00
2016-08-15 19:22:32 +00:00
def library ( request , library_name ) :
context = { }
2013-10-17 16:44:47 +00:00
try :
# determine if the supporter is a library
2016-08-15 19:22:32 +00:00
authenticator = Authenticator ( request , library_name )
2013-10-17 16:44:47 +00:00
context [ ' authenticator ' ] = authenticator
2013-10-18 16:36:55 +00:00
context [ ' library ' ] = library = authenticator . library
2013-10-17 16:44:47 +00:00
except Library . DoesNotExist :
raise Http404
2016-08-15 19:22:32 +00:00
works_active = models . Work . objects . filter ( acqs__user = library . user , acqs__license = LIBRARY ) . distinct ( )
if works_active . count ( ) > 0 :
2013-11-01 18:33:52 +00:00
context [ ' works_active ' ] = works_active
context [ ' activetab ' ] = " #2 "
2016-08-15 19:22:32 +00:00
context [ ' ungluers ' ] = userlists . library_users ( library , 5 )
return supporter ( request , library_name , template_name = ' libraryauth/library.html ' , extra_context = context )
2013-10-17 16:44:47 +00:00
2012-10-15 03:41:17 +00:00
class ManageAccount ( FormView ) :
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +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 } )
2016-07-25 15:32:04 +00:00
next = self . request . GET . get ( ' next ' , self . request . POST . get ( ' next ' , None ) )
2012-10-15 04:16:56 +00:00
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 ' , ' ' )
2016-06-20 17:08:23 +00:00
ty = request . GET . get ( ' ty ' , ' g ' ) # ge= 'general, au= 'author'
2016-08-15 19:22:32 +00:00
request . session [ ' q ' ] = q
2016-06-20 17:16:37 +00:00
try :
page = int ( request . GET . get ( ' page ' , 1 ) )
except ValueError :
# garbage in page
page = 1
2015-06-07 22:55:49 +00:00
gbo = request . GET . get ( ' gbo ' , ' n ' ) # gbo is flag for google books only
2016-08-15 19:22:32 +00:00
our_stuff = Q ( is_free = True ) | Q ( campaigns__isnull = False )
if q != ' ' and page == 1 and not gbo == ' y ' :
2016-05-10 01:48:23 +00:00
isbnq = ISBN ( q )
if isbnq . valid :
work_query = Q ( identifiers__value = str ( isbnq ) , identifiers__type = " isbn " )
2016-08-15 19:22:32 +00:00
elif ty == ' au ' :
work_query = Q ( editions__authors__name = q )
2016-05-10 01:48:23 +00:00
else :
work_query = Q ( title__icontains = q ) | Q ( editions__authors__name__icontains = q ) | Q ( subjects__name__iexact = q )
2015-02-12 14:46:58 +00:00
campaign_works = models . Work . objects . filter ( our_stuff ) . filter ( work_query ) . distinct ( )
2015-06-07 22:55:49 +00:00
for work in campaign_works :
results = models . Work . objects . none ( )
break
else :
results = gluejar_search ( q , user_ip = request . META [ ' REMOTE_ADDR ' ] , page = 1 )
gbo = ' y '
2013-03-01 17:07:15 +00:00
else :
2015-06-07 22:55:49 +00:00
if gbo == ' n ' :
2016-08-15 19:22:32 +00:00
page = page - 1 # because page=1 is the unglue.it results
2015-06-07 22:55:49 +00:00
results = gluejar_search ( q , user_ip = request . META [ ' REMOTE_ADDR ' ] , page = page )
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
2016-08-15 19:22:32 +00:00
works = [ ]
2011-11-15 16:27:32 +00:00
for result in results :
2012-01-31 15:07:52 +00:00
try :
2016-08-15 19:22:32 +00:00
work = models . Identifier . objects . get ( type = ' goog ' , value = result [ ' googlebooks_id ' ] ) . work
2012-01-31 15:07:52 +00:00
works . append ( work )
2016-08-15 19:22:32 +00:00
except models . Identifier . DoesNotExist :
2012-01-31 15:07:52 +00:00
works . append ( result )
2011-09-29 01:54:50 +00:00
context = {
" q " : q ,
2015-06-07 22:55:49 +00:00
" gbo " : gbo ,
2016-06-06 17:49:22 +00:00
" ty " : ty ,
2012-01-03 00:07:12 +00:00
" results " : works ,
2013-03-01 17:07:15 +00:00
" 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 )
2014-12-11 04:27:49 +00:00
setkw = request . POST . get ( ' setkw ' , None )
if setkw and request . user . is_staff :
try :
subject = models . Subject . objects . get ( name = setkw )
except models . Subject . DoesNotExist :
return HttpResponse ( ' invalid subject ' )
if remove_work_id :
work = safe_get_work ( int ( remove_work_id ) )
work . subjects . remove ( subject )
return HttpResponse ( ' removed work from ' + setkw )
elif add_work_id :
2016-08-15 19:22:32 +00:00
work = safe_get_work ( add_work_id )
2014-12-11 04:27:49 +00:00
work . subjects . add ( subject )
return HttpResponse ( ' added work to ' + setkw )
2016-08-15 19:22:32 +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 )
2016-08-15 19:22:32 +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-06-05 15:06:07 +00:00
return HttpResponse ( ' error adding googlebooks id ' )
2012-01-31 19:54:48 +00:00
except Exception , e :
2016-08-15 19:22:32 +00:00
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 :
2013-09-05 20:14:51 +00:00
work = safe_get_work ( int ( remove_work_id ) )
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
2016-08-15 19:22:32 +00:00
work = safe_get_work ( add_work_id )
request . user . wishlist . add_work ( work , ' user ' , notify = True )
2013-02-26 20:30:14 +00:00
return HttpResponse ( ' added work to wishlist ' )
2015-01-13 01:24:32 +00:00
@require_POST
@login_required
def kw_edit ( request , work_id ) :
work = safe_get_work ( work_id )
remove_kw = request . POST . get ( ' remove_kw ' , None )
2015-01-14 20:07:54 +00:00
add_form = request . POST . get ( ' kw_add ' , False ) # signal to process form
2016-07-14 16:25:18 +00:00
if user_can_edit_work ( request . user , work ) :
2015-01-13 01:24:32 +00:00
if remove_kw :
try :
subject = models . Subject . objects . get ( name = remove_kw )
except models . Subject . DoesNotExist :
return HttpResponse ( ' invalid subject ' )
work . subjects . remove ( subject )
2016-08-15 19:22:32 +00:00
return HttpResponse ( ' removed ' + remove_kw )
2015-01-14 20:07:54 +00:00
elif add_form :
2016-08-15 19:22:32 +00:00
form = SubjectSelectForm ( data = request . POST )
2015-01-14 20:07:54 +00:00
if form . is_valid ( ) :
add_kw = form . cleaned_data [ ' add_kw ' ]
try :
subject = models . Subject . objects . get ( name = add_kw )
except models . Subject . DoesNotExist :
return HttpResponse ( ' invalid subject ' )
work . subjects . add ( subject )
2016-08-15 19:22:32 +00:00
return HttpResponse ( add_kw . name )
2015-01-14 20:07:54 +00:00
else :
2016-08-15 19:22:32 +00:00
return HttpResponse ( ' xxbadform ' )
2015-01-14 20:07:54 +00:00
else :
return HttpResponse ( str ( add_form ) )
return HttpResponse ( str ( add_form ) )
2015-01-13 01:24:32 +00:00
2016-08-15 19:22:32 +00:00
2012-03-08 03:06:30 +00:00
class InfoPageView ( TemplateView ) :
2016-08-15 19:22:32 +00:00
2017-06-12 16:05:49 +00:00
template_name = ' metrics.html '
2012-03-08 03:06:30 +00:00
def get_template_names ( self , * * kwargs ) :
if self . kwargs [ ' template_name ' ] :
2017-06-12 16:05:49 +00:00
return [ self . kwargs [ ' template_name ' ] , self . template_name ]
2012-03-08 03:06:30 +00:00
else :
2017-06-12 16:05:49 +00:00
return [ self . template_name ]
2016-08-15 19:22:32 +00:00
2012-03-08 03:06:30 +00:00
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 = ' ' )
2014-11-19 21:03:21 +00:00
users . libtools = users . filter ( libpref__isnull = False )
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 )
2015-03-31 17:50:39 +00:00
works . free = works . filter ( is_free = True )
2012-03-08 03:06:30 +00:00
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 ( ) ) )
2014-11-19 21:03:21 +00:00
ebooks . downloads = ebooks . aggregate ( total = Sum ( ' download_count ' ) ) [ ' total ' ]
ebooks . pdfdownloads = ebooks . filter ( format = ' pdf ' ) . aggregate ( total = Sum ( ' download_count ' ) ) [ ' total ' ]
ebooks . epubdownloads = ebooks . filter ( format = ' epub ' ) . aggregate ( total = Sum ( ' download_count ' ) ) [ ' total ' ]
ebooks . mobidownloads = ebooks . filter ( format = ' mobi ' ) . aggregate ( total = Sum ( ' download_count ' ) ) [ ' total ' ]
2014-02-25 19:47:16 +00:00
ebookfiles = models . EbookFile . objects
ebookfiles . today = ebookfiles . filter ( created__range = ( date_today ( ) , now ( ) ) )
ebookfiles . days7 = ebookfiles . filter ( created__range = ( date_today ( ) - timedelta ( days = 7 ) , now ( ) ) )
ebookfiles . year = ebookfiles . filter ( created__year = date_today ( ) . year )
ebookfiles . month = ebookfiles . year . filter ( created__month = date_today ( ) . month )
ebookfiles . yesterday = ebookfiles . filter ( created__range = ( date_today ( ) - timedelta ( days = 1 ) , date_today ( ) ) )
2016-08-15 19:22:32 +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 )
2016-08-15 19:22:32 +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 ' ]
2015-03-31 17:51:22 +00:00
transactions . month = transactions . year . filter ( date_created__month = date_today ( ) . month )
2012-12-06 16:42:02 +00:00
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 ' ]
2016-07-24 22:39:36 +00:00
marc = apps . get_model ( ' marc ' , ' MARCRecord ' ) . objects
2014-11-19 21:03:21 +00:00
marc . today = marc . filter ( created__range = ( date_today ( ) , now ( ) ) )
marc . days7 = marc . filter ( created__range = ( date_today ( ) - timedelta ( days = 7 ) , now ( ) ) )
marc . year = marc . filter ( created__year = date_today ( ) . year )
marc . month = marc . year . filter ( created__month = date_today ( ) . month )
2016-08-15 19:22:32 +00:00
marc . yesterday = marc . filter ( created__range = ( date_today ( ) - timedelta ( days = 1 ) , date_today ( ) ) )
2012-03-08 03:06:30 +00:00
return {
2016-08-15 19:22:32 +00:00
' users ' : users ,
2012-03-08 03:06:30 +00:00
' works ' : works ,
' ebooks ' : ebooks ,
2014-02-25 19:47:16 +00:00
' ebookfiles ' : ebookfiles ,
2012-03-08 03:06:30 +00:00
' wishlists ' : wishlists ,
2012-12-11 15:53:12 +00:00
' transactions ' : transactions ,
2014-11-19 21:03:21 +00:00
' marc ' : marc ,
2012-03-08 03:06:30 +00:00
}
2017-06-12 16:05:49 +00:00
class InfoLangView ( InfoPageView ) :
2016-08-15 19:22:32 +00:00
2017-06-12 16:05:49 +00:00
template_name = ' languages.html '
2016-08-15 19:22:32 +00:00
2012-07-20 18:29:04 +00:00
def get_context_data ( self , * * kwargs ) :
2016-08-15 19:22:32 +00:00
languages = models . Work . objects . filter ( num_wishes__gte = 1 ) . values ( ' language ' ) . annotate ( lang_count = Count ( ' language ' ) ) . order_by ( ' -lang_count ' )
2012-07-20 18:29:04 +00:00
return {
2016-08-15 19:22:32 +00:00
' wished_languages ' : languages ,
2012-07-20 18:29:04 +00:00
}
2016-08-15 19:22:32 +00:00
2013-11-03 04:27:52 +00:00
class FAQView ( FormView ) :
template_name = " faq.html "
2013-10-04 02:54:25 +00:00
form_class = DateCalculatorForm
def form_valid ( self , form ) :
2016-08-15 19:22:32 +00:00
form . instance . status = ' DEMO '
form . instance . type = BUY2UNGLUE
2013-10-04 02:54:25 +00:00
form . instance . set_dollar_per_day ( )
2014-04-09 18:32:25 +00:00
form . instance . update_left ( )
2016-08-15 19:22:32 +00:00
form . instance . _current_total = form . cleaned_data [ ' revenue ' ]
2013-10-04 02:54:25 +00:00
return self . render_to_response ( self . get_context_data ( form = form ) )
2016-08-15 19:22:32 +00:00
2013-10-04 02:54:25 +00:00
def get_initial ( self ) :
2016-08-15 19:22:32 +00:00
return { ' target ' : 10000 , ' cc_date_initial ' : date_today ( ) + timedelta ( days = 1461 ) , ' revenue ' : 0 , ' type ' : BUY2UNGLUE , ' status ' : ' DEMO ' }
2013-10-04 02:54:25 +00:00
2013-11-03 04:07:52 +00:00
def get_context_data ( self , * * kwargs ) :
2016-08-15 19:22:32 +00:00
cd = super ( FAQView , self ) . get_context_data ( * * kwargs )
2013-11-03 04:07:52 +00:00
cd . update ( {
2016-08-15 19:22:32 +00:00
' location ' : self . kwargs [ " location " ] ,
2013-11-03 04:07:52 +00:00
' sublocation ' : self . kwargs [ " sublocation " ] ,
} )
return cd
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 )
2016-08-15 19:22:32 +00:00
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
2016-08-15 19:22:32 +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 " ] ) ) ] + \
2016-08-15 19:22:32 +00:00
[ ( " %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 ) )
2016-08-15 19:22:32 +00:00
2011-11-01 00:26:05 +00:00
context [ " gr_shelf_load_form " ] = gr_shelf_load_form
2016-08-15 19:22:32 +00:00
2011-11-10 23:14:33 +00:00
# also load any CeleryTasks associated with the user
context [ " celerytasks " ] = models . CeleryTask . objects . filter ( user = user )
2016-08-15 19:22:32 +00:00
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 ' ]
2016-08-15 19:22:32 +00:00
2011-11-16 22:16:57 +00:00
return HttpResponseRedirect ( goodreads_auth_url )
2016-08-15 19:22:32 +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 """
2016-08-15 19:22:32 +00:00
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 )
2016-08-15 19:22:32 +00:00
2011-10-25 01:29:01 +00:00
access_token = gr_client . complete_authorization ( request_token )
2016-08-15 19:22:32 +00:00
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 " ]
2016-08-15 19:22:32 +00:00
2011-10-25 01:29:01 +00:00
# let's get the userid, username
user = gr_client . auth_user ( )
2016-08-15 19:22:32 +00:00
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 " ]
2016-08-15 19:22:32 +00:00
2011-10-29 22:40:00 +00:00
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
2016-08-15 19:22:32 +00:00
@csrf_exempt
2011-11-01 00:26:05 +00:00
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 ' ) )
2016-08-15 19:22:32 +00:00
2011-11-01 00:26:05 +00:00
@require_POST
2016-08-15 19:22:32 +00:00
@login_required
2011-11-01 00:26:05 +00:00
@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 )
2016-08-15 19:22:32 +00:00
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 ( )
2016-08-15 19:22:32 +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> " )
2016-08-15 19:22:32 +00:00
except Exception , e :
2011-11-01 00:26:05 +00:00
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
2016-08-15 19:22:32 +00:00
2012-01-24 17:36:45 +00:00
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"]))] + \
2016-08-15 19:22:32 +00:00
# [("%s:%d" % (s["name"], s["book_count"]) ,"%s (%d)" % (s["name"], s["book_count"])) for s in goodreads_shelves["user_shelves"]]
2012-01-24 17:36:45 +00:00
#goodreads_shelf_load_form.fields['goodreads_shelf_name_number'].widget = Select(choices=tuple(choices))
else :
goodreads_shelf_load_form = None
2016-08-15 19:22:32 +00:00
2012-01-24 17:36:45 +00:00
return HttpResponse ( json . dumps ( goodreads_shelves ) , content_type = " application/json " )
2016-08-15 19:22:32 +00:00
2012-01-24 17:36:45 +00:00
2011-11-17 00:47:29 +00:00
@require_POST
2016-08-15 19:22:32 +00:00
@login_required
2011-11-17 00:47:29 +00:00
@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
2016-08-15 19:22:32 +00:00
try :
2011-11-17 00:47:29 +00:00
# figure out expected_number_of_books later
2016-08-15 19:22:32 +00:00
2011-11-17 00:47:29 +00:00
lt_username = request . user . profile . librarything_id
2016-08-15 19:22:32 +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 )
2016-08-15 19:22:32 +00:00
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 ( )
2016-08-15 19:22:32 +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> " )
2016-08-15 19:22:32 +00:00
except Exception , e :
2011-11-17 00:47:29 +00:00
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
2016-08-15 19:22:32 +00:00
@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 :
2011-11-10 15:36:17 +00:00
logger . info ( " Error in clearing wishlist for user %s : %s " , request . user , e )
2016-08-15 19:22:32 +00:00
return HttpResponse ( " Error in clearing wishlist: %s " % ( e ) )
2013-02-26 17:43:54 +00:00
@require_POST
2016-08-15 19:22:32 +00:00
@login_required
2013-02-26 17:43:54 +00:00
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 ( ) :
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +00:00
2011-11-16 18:20:10 +00:00
class LibraryThingView ( FormView ) :
2016-08-15 19:22:32 +00:00
template_name = " librarything.html "
2011-11-16 18:20:10 +00:00
form_class = LibraryThingForm
2016-08-15 19:22:32 +00:00
2011-11-16 18:20:10 +00:00
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
2016-08-15 19:22:32 +00:00
lt_username = self . request . GET . get ( " lt_username " , None )
2011-11-16 18:20:10 +00:00
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 } )
2016-08-15 19:22:32 +00:00
2011-11-16 18:20:10 +00:00
return context
2016-08-15 19:22:32 +00:00
def form_valid ( self , form ) :
2011-11-16 18:20:10 +00:00
return super ( LibraryThingView , self ) . form_valid ( form )
2016-08-15 19:22:32 +00:00
2011-11-10 23:14:33 +00:00
@require_POST
2016-08-15 19:22:32 +00:00
@login_required
2011-11-10 23:14:33 +00:00
@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 :
2016-08-15 19:22:32 +00:00
logger . info ( " Error in clearing Celery Tasks for user %s : %s " , request . user , e )
2011-11-10 23:14:33 +00:00
return HttpResponse ( " Error in clearing Celery Tasks: %s " % ( 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
#
2016-08-15 19:22:32 +00:00
# TODO: need to queue up a task to look up IDs if we have to fallback to
2011-12-05 05:56:24 +00:00
# routing based on ISBN or search
def work_librarything ( request , work_id ) :
2013-09-05 20:14:51 +00:00
work = safe_get_work ( 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?
2017-07-27 14:33:13 +00:00
url = " https://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 } )
2017-07-27 14:33:13 +00:00
url = " https://www.librarything.com/search.php? " + q
2011-12-05 05:56:24 +00:00
return HttpResponseRedirect ( url )
def work_openlibrary ( request , work_id ) :
2013-09-05 20:14:51 +00:00
work = safe_get_work ( 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 )
2017-07-27 14:33:13 +00:00
u = ' https://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 ]
2017-07-27 14:33:13 +00:00
url = " https://openlibrary.org " + j [ first ] [ ' key ' ]
2012-03-10 16:03:58 +00:00
except ValueError :
# fail at openlibrary
2016-08-15 19:22:32 +00:00
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 ( ) } )
2017-07-27 14:33:13 +00:00
url = " https://openlibrary.org/search? " + q
2011-12-05 05:56:24 +00:00
return HttpResponseRedirect ( url )
def work_goodreads ( request , work_id ) :
2013-09-05 20:14:51 +00:00
work = safe_get_work ( 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 :
2017-07-27 14:33:13 +00:00
url = " https://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 ( ) } )
2017-07-27 14:33:13 +00:00
url = " https://www.goodreads.com/search? " + q
2011-12-05 05:56:24 +00:00
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 ' :
2016-08-15 19:22:32 +00:00
form = EmailShareForm ( request . POST )
2011-12-31 18:49:23 +00:00
if form . is_valid ( ) :
subject = form . cleaned_data [ ' subject ' ]
message = form . cleaned_data [ ' message ' ]
2016-08-15 19:22:32 +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 )
2016-08-15 19:22:32 +00:00
else :
2013-01-21 17:00:01 +00:00
work = None
status = None
2016-08-15 19:22:32 +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 )
2014-02-21 19:12:20 +00:00
if not action :
status = work . last_campaign ( ) . status
2011-12-31 18:49:23 +00:00
except :
2013-01-21 17:00:01 +00:00
pass
2016-08-15 19:22:32 +00:00
context = { ' request ' : request , ' work ' : work , ' site ' : Site . objects . get_current ( ) , ' action ' : action }
2014-02-21 19:12:20 +00:00
if work and action :
message = render_to_string ( ' emails/i_just_pledged.txt ' , context )
2013-01-21 17:00:01 +00:00
subject = " Help me unglue " + work . title
2016-08-15 19:22:32 +00:00
else :
2013-01-21 17:00:01 +00:00
# customize the call to action depending on campaign status
if status == ' ACTIVE ' :
2014-02-21 19:12:20 +00:00
message = render_to_string ( ' emails/pledge_this.txt ' , context )
2013-01-21 17:00:01 +00:00
subject = ' Please help me give this book to the world '
elif work :
2014-02-21 19:12:20 +00:00
message = render_to_string ( ' emails/wish_this.txt ' , context )
subject = ' This is one of my favorite books on Unglue.it '
2013-01-21 17:00:01 +00:00
else :
# for email shares not bound to a campaign or pledge
2014-02-21 19:12:20 +00:00
message = render_to_string ( ' emails/join_me.txt ' , context )
2013-01-21 17:00:01 +00:00
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
2016-08-15 19:22:32 +00:00
return render ( request , " emailshare.html " , { ' form ' : form } )
2013-03-27 16:22:30 +00:00
def ask_rh ( request , campaign_id ) :
campaign = get_object_or_404 ( models . Campaign , id = campaign_id )
2016-08-15 19:22:32 +00:00
return feedback ( request , recipient = campaign . email , template = " ask_rh.html " ,
message_template = " ask_rh.txt " ,
2017-10-28 22:33:58 +00:00
redirect_url = reverse ( ' work ' , args = [ campaign . work_id ] ) ,
2016-08-15 19:22:32 +00:00
extra_context = { ' campaign ' : campaign , ' subject ' : campaign } )
2017-11-18 21:34:56 +00:00
def feedback ( request , recipient = ' unglueit@ebookfoundation.org ' , template = ' feedback.html ' , message_template = ' feedback.txt ' , extra_context = None , redirect_url = None ) :
2013-03-27 16:22:30 +00:00
context = extra_context or { }
2016-08-15 19:22:32 +00:00
context [ ' num1 ' ] = randint ( 0 , 10 )
context [ ' num2 ' ] = randint ( 0 , 10 )
2013-03-27 16:22:30 +00:00
context [ ' answer ' ] = context [ ' num1 ' ] + context [ ' num2 ' ]
2016-08-15 19:22:32 +00:00
2012-01-09 20:53:09 +00:00
if request . method == ' POST ' :
2016-08-15 19:22:32 +00:00
form = FeedbackForm ( request . POST )
2012-01-09 20:53:09 +00:00
if form . is_valid ( ) :
2013-03-27 16:22:30 +00:00
context . update ( form . cleaned_data )
2016-08-15 19:22:32 +00:00
context [ ' request ' ] = request
2013-03-27 16:22:30 +00:00
if extra_context :
context . update ( extra_context )
2016-08-15 19:22:32 +00:00
message = render_to_string ( message_template , context )
2013-03-27 16:22:30 +00:00
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 :
2016-08-15 19:22:32 +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 ' ]
2016-08-15 19:22:32 +00:00
2012-01-09 20:53:09 +00:00
else :
2012-01-31 15:07:52 +00:00
if request . user . is_authenticated ( ) :
2016-08-15 19:22:32 +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
2016-08-15 19:22:32 +00:00
return render ( request , template , context )
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
2016-09-23 17:16:26 +00:00
authors = work . authors ( )
2016-08-15 19:22:32 +00:00
2012-09-12 14:11:49 +00:00
return render ( request , " lockss.html " , { ' work ' : work , ' ebooks ' : ebooks , ' authors ' : authors } )
2016-08-15 19:22:32 +00:00
2012-09-18 18:16:06 +00:00
def lockss_manifest ( request , year ) :
"""
manifest pages for lockss harvester - - yearly indices
2016-08-15 19:22:32 +00:00
( lockss needs pages listing all books unglued by year , with
2012-09-18 18:16:06 +00:00
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
2016-08-15 19:22:32 +00:00
2012-09-18 18:16:06 +00:00
return render ( request , " lockss_manifest.html " , { ' ebooks ' : ebooks , ' year ' : year } )
2013-06-27 17:10:33 +00:00
2014-02-20 03:18:23 +00:00
class DownloadView ( PurchaseView ) :
2016-08-15 19:22:32 +00:00
template_name = " download.html "
form_class = CampaignThanksForm
2014-02-20 03:18:23 +00:00
def show_beg ( self ) :
if not self . campaign or self . campaign . type != THANKS :
return False
elif self . user_license and self . user_license . thanked :
2016-07-25 15:32:04 +00:00
return self . request . GET . has_key ( ' offer_id ' ) or self . request . POST . has_key ( ' offer_id ' )
2014-03-19 02:30:21 +00:00
elif self . lib_thanked :
return False
2014-03-04 20:49:59 +00:00
elif self . campaign . status != ' ACTIVE ' :
2016-07-25 15:32:04 +00:00
return self . request . GET . has_key ( ' testmode ' ) or self . request . POST . has_key ( ' testmode ' )
2016-08-15 19:22:32 +00:00
else :
2014-02-20 03:18:23 +00:00
return True
2016-08-15 19:22:32 +00:00
2014-02-20 03:18:23 +00:00
def form_valid ( self , form ) :
p = PaymentManager ( )
2016-08-15 19:22:32 +00:00
t , url = p . process_transaction ( ' USD ' , form . cleaned_data [ " preapproval_amount " ] ,
host = PAYMENT_HOST_NONE ,
campaign = self . campaign ,
user = self . request . user ,
paymentReason = " Unglue.it Contribution for {0} " . format ( self . campaign . name ) ,
pledge_extra = form . trans_extra ,
)
2014-02-20 03:18:23 +00:00
if url :
return HttpResponseRedirect ( url )
else :
logger . error ( " Attempt to produce transaction id {0} failed " . format ( t . id ) )
return HttpResponse ( " Our attempt to set up your contribution failed. We have logged this problem. " )
def get_form_kwargs ( self ) :
if self . kwargs . has_key ( ' work ' ) :
self . work = self . kwargs [ " work " ]
2016-08-15 19:22:32 +00:00
self . show_beg = lambda : False
2014-02-20 03:18:23 +00:00
else :
self . work = safe_get_work ( self . kwargs [ " work_id " ] )
self . campaign = self . work . last_campaign ( )
self . user_license = self . work . get_user_license ( self . request . user )
2014-03-19 02:30:21 +00:00
self . lib_thanked = self . work . lib_thanked ( self . request . user )
2014-02-20 03:18:23 +00:00
self . data = {
' preapproval_amount ' : self . get_preapproval_amount ( ) ,
' anonymous ' : True if self . request . user . is_anonymous ( ) else self . request . user . profile . anon_pref ,
}
if self . request . method == ' POST ' :
self . data . update ( self . request . POST . dict ( ) )
if not self . request . POST . has_key ( ' anonymous ' ) :
del self . data [ ' anonymous ' ]
return { ' data ' : self . data }
else :
return { ' initial ' : self . data }
def get_context_data ( self , * * kwargs ) :
context = super ( FormView , self ) . get_context_data ( * * kwargs )
# adapt funtion view to class view
2016-08-15 19:22:32 +00:00
work = self . work
2014-02-20 03:18:23 +00:00
request = self . request
site = Site . objects . get_current ( )
unglued_ebooks = work . ebooks ( ) . filter ( edition__unglued = True )
other_ebooks = work . ebooks ( ) . filter ( edition__unglued = False )
2014-05-23 02:38:42 +00:00
xfer_url = kindle_url = None
2016-08-15 19:22:32 +00:00
acq = None
2014-02-20 03:18:23 +00:00
formats = { } # a dict of format name and url
for ebook in work . ebooks ( ) . all ( ) :
2016-08-15 19:22:32 +00:00
formats [ ebook . format ] = reverse ( ' download_ebook ' , args = [ ebook . id ] )
if request . user . is_authenticated ( ) :
2014-07-28 22:22:26 +00:00
#add a fave
request . user . wishlist . add_work ( work , ' download ' )
2016-08-15 19:22:32 +00:00
all_acqs = request . user . acqs . filter ( work = work ) . order_by ( ' -created ' )
2014-02-20 03:18:23 +00:00
for an_acq in all_acqs :
if not an_acq . expired :
2014-05-05 14:15:29 +00:00
# skip for THANKS
if an_acq . license == THANKED :
acq = None
break
2014-02-20 03:18:23 +00:00
# prepare this acq for download
if not an_acq . watermarked or an_acq . watermarked . expired :
if not an_acq . on_reserve :
watermark_acq . delay ( an_acq )
acq = an_acq
2016-08-15 19:22:32 +00:00
formats [ ' epub ' ] = reverse ( ' download_acq ' , kwargs = { ' nonce ' : acq . nonce , ' format ' : ' epub ' } )
formats [ ' mobi ' ] = reverse ( ' download_acq ' , kwargs = { ' nonce ' : acq . nonce , ' format ' : ' mobi ' } )
2014-05-20 16:19:34 +00:00
xfer_url = settings . BASE_URL_SECURE + formats [ ' epub ' ]
2014-05-23 02:35:29 +00:00
kindle_url = settings . BASE_URL_SECURE + formats [ ' mobi ' ]
2014-02-20 03:18:23 +00:00
can_kindle = True
break
2016-08-15 19:22:32 +00:00
2014-02-20 03:18:23 +00:00
if not acq :
# google ebooks have a captcha which breaks some of our services
non_google_ebooks = work . ebooks ( ) . exclude ( provider = ' Google Books ' )
2016-08-15 19:22:32 +00:00
#send to kindle
2013-09-06 02:54:11 +00:00
try :
2015-03-06 03:30:03 +00:00
kindle_ebook = non_google_ebooks . filter ( format = ' mobi ' ) [ 0 ]
can_kindle = kindle_ebook . kindle_sendable ( )
2013-09-06 02:54:11 +00:00
except IndexError :
2014-02-20 03:18:23 +00:00
try :
2015-03-06 03:30:03 +00:00
kindle_ebook = non_google_ebooks . filter ( format = ' pdf ' ) [ 0 ]
can_kindle = kindle_ebook . kindle_sendable ( )
2014-02-20 03:18:23 +00:00
except IndexError :
can_kindle = False
2014-05-20 16:19:34 +00:00
# configure the xfer url
2014-02-20 03:18:23 +00:00
try :
2014-05-20 16:19:34 +00:00
xfer_epub_ebook = non_google_ebooks . filter ( format = ' epub ' ) [ 0 ]
2016-08-15 19:22:32 +00:00
xfer_url = settings . BASE_URL_SECURE + reverse ( ' download_ebook ' , args = [ xfer_epub_ebook . id ] )
2014-02-20 03:18:23 +00:00
except :
2014-05-20 16:19:34 +00:00
xfer_url = None
2016-08-15 19:22:32 +00:00
agent = request . META . get ( ' HTTP_USER_AGENT ' , ' ' )
2014-02-20 03:18:23 +00:00
iOS = ' iPad ' in agent or ' iPhone ' in agent or ' iPod ' in agent
iOS_app = iOS and not ' Safari ' in agent
android = ' Android ' in agent
desktop = not iOS and not android
context . update ( {
' unglued_ebooks ' : unglued_ebooks ,
' other_ebooks ' : other_ebooks ,
' formats ' : formats ,
2014-05-20 16:19:34 +00:00
' xfer_url ' : xfer_url ,
2014-05-23 02:35:29 +00:00
' kindle_url ' : kindle_url ,
2014-05-20 16:19:34 +00:00
' dropbox_key ' : settings . DROPBOX_KEY ,
2014-02-20 03:18:23 +00:00
' can_kindle ' : can_kindle ,
' base_url ' : settings . BASE_URL_SECURE ,
' iOS ' : iOS ,
' iOS_app ' : iOS_app ,
2014-02-24 22:18:05 +00:00
' iphone ' : ' iPhone ' in agent ,
2014-02-20 03:18:23 +00:00
' android ' : android ,
' desktop ' : desktop ,
2015-03-06 03:26:25 +00:00
' mac_ibooks ' : ' Mac OS X 10.9 ' in agent or ' Mac OS X 10_9 ' in agent or ' Mac OS X 10.10 ' in agent or ' Mac OS X 10_10 ' in agent ,
2014-02-20 03:18:23 +00:00
' acq ' : acq ,
' show_beg ' : self . show_beg ,
' preapproval_amount ' : self . get_preapproval_amount ( ) ,
2016-08-15 19:22:32 +00:00
' work ' : work ,
2014-02-20 03:18:23 +00:00
' site ' : site ,
' action ' : " Contribution " ,
' user_license ' : self . user_license ,
2014-03-19 02:30:21 +00:00
' lib_thanked ' : self . lib_thanked ,
2016-05-10 18:27:24 +00:00
' amount ' : D ( self . request . session . pop ( ' amount ' ) / 100 ) if self . request . session . has_key ( ' amount ' ) else None ,
2016-07-25 15:32:04 +00:00
' testmode ' : self . request . GET . has_key ( ' testmode ' ) or self . request . POST . has_key ( ' testmode ' ) ,
' source ' : self . request . GET . get ( ' source ' , self . request . POST . get ( ' source ' , ' ' ) ) ,
2014-09-04 22:33:20 +00:00
2014-02-20 03:18:23 +00:00
} )
return context
2013-10-15 20:18:30 +00:00
2014-07-01 18:09:21 +00:00
@login_required
def feature ( request , work_id ) :
if not request . user . is_staff :
return render ( request , " admins_only.html " )
else :
work = safe_get_work ( work_id )
2015-02-17 22:06:10 +00:00
if work . is_free :
2014-07-01 18:09:21 +00:00
work . featured = now ( )
work . save ( )
2016-08-15 19:22:32 +00:00
return HttpResponseRedirect ( reverse ( ' landing ' , args = [ ] ) )
2014-07-01 18:09:21 +00:00
else :
return HttpResponse ( ' can \' t feature an work without an ebook ' )
2013-10-18 19:35:48 +00:00
@login_required
2013-10-15 20:18:30 +00:00
def borrow ( request , work_id ) :
2013-10-18 19:35:48 +00:00
work = safe_get_work ( work_id )
library = request . GET . get ( ' library ' , ' ' )
2013-11-08 17:13:34 +00:00
libuser = None
acq = None
if library :
try :
libuser = User . objects . get ( username = library )
except User . DoesNotExist :
libuser = None
if libuser :
2013-11-12 22:28:07 +00:00
acq = work . get_user_license ( libuser ) . borrowable_acq
2013-11-08 17:13:34 +00:00
if not libuser or not acq :
2016-08-15 19:22:32 +00:00
acq = work . get_lib_license ( request . user ) . borrowable_acq
2013-10-18 19:35:48 +00:00
if acq :
borrowed = acq . borrow ( request . user )
2014-03-20 13:23:17 +00:00
return DownloadView . as_view ( ) ( request , work = work )
2013-10-18 19:35:48 +00:00
else :
# shouldn't happen
return work ( request , work_id )
2013-11-08 17:13:34 +00:00
@login_required
def reserve ( request , work_id ) :
work = safe_get_work ( work_id )
lib = request . GET . get ( ' library ' , ' ' )
library = None
try :
library = Library . objects . get ( user__username = lib )
except Library . DoesNotExist :
try :
library = work . get_lib_license ( request . user ) . next_acq . library
except :
library = None
2016-08-15 19:22:32 +00:00
models . Hold . objects . get_or_create ( library = library , work = work , user = request . user )
return PurchaseView . as_view ( ) ( request , work_id = work_id )
2013-09-06 02:54:11 +00:00
def download_ebook ( request , ebook_id ) :
2016-08-15 19:22:32 +00:00
ebook = get_object_or_404 ( models . Ebook , id = ebook_id )
2013-09-06 02:54:11 +00:00
ebook . increment ( )
logger . info ( " ebook: {0} , user_ip: {1} " . format ( ebook_id , request . META [ ' REMOTE_ADDR ' ] ) )
return HttpResponseRedirect ( ebook . url )
2013-06-27 17:10:33 +00:00
def download_purchased ( request , work_id ) :
2017-02-13 18:48:17 +00:00
if request . user . is_anonymous ( ) :
2013-06-27 17:10:33 +00:00
HttpResponseRedirect ( ' /accounts/login/download/ ' )
2014-04-07 16:17:21 +00:00
return DownloadView . as_view ( ) ( request , work_id = work_id )
2013-09-06 02:54:11 +00:00
2013-11-14 19:48:16 +00:00
def download_campaign ( request , work_id , format ) :
work = safe_get_work ( work_id )
2016-04-26 17:54:55 +00:00
2016-08-15 19:22:32 +00:00
# Raise 404 unless there is a SUCCESSFUL BUY2UNGLUE campaign associated with work
2016-04-26 17:54:55 +00:00
try :
campaign = work . campaigns . get ( status = ' SUCCESSFUL ' , type = BUY2UNGLUE )
2017-11-28 01:12:42 +00:00
except models . Campaign . DoesNotExist as e :
2013-11-14 19:48:16 +00:00
raise Http404
2016-04-26 17:54:55 +00:00
2016-08-15 19:22:32 +00:00
ebfs = models . EbookFile . objects . filter ( edition__work = campaign . work , format = format ) . exclude ( file = ' ' ) . order_by ( ' -created ' )
2016-04-26 17:54:55 +00:00
logger . info ( ebfs . count ( ) )
2016-08-15 19:22:32 +00:00
# return the link to the most recently created EbookFile (if any) with specified format for the campaign
2016-04-26 17:54:55 +00:00
for ebf in ebfs :
logger . info ( ebf . file . url )
return HttpResponseRedirect ( ebf . file . url )
2013-11-14 19:48:16 +00:00
2016-04-26 18:24:46 +00:00
# if ebfs.count() is 0
raise Http404
2013-11-14 19:48:16 +00:00
2013-09-06 02:54:11 +00:00
def download_acq ( request , nonce , format ) :
2016-08-15 19:22:32 +00:00
acq = get_object_or_404 ( models . Acq , nonce = nonce )
2013-10-17 02:53:47 +00:00
if acq . on_reserve :
acq . borrow ( )
2013-09-06 02:54:11 +00:00
if format == ' epub ' :
2016-08-15 19:22:32 +00:00
return HttpResponseRedirect ( acq . get_epub_url ( ) )
2013-09-06 02:54:11 +00:00
else :
2016-08-15 19:22:32 +00:00
return HttpResponseRedirect ( acq . get_mobi_url ( ) )
2012-08-27 19:35:29 +00:00
def about ( request , facet ) :
template = " about_ " + facet + " .html "
2013-05-03 18:48:36 +00:00
try :
return render ( request , template )
except TemplateDoesNotExist :
2017-11-18 21:35:19 +00:00
return render ( request , " about_main.html " )
2012-09-07 20:08:03 +00:00
2014-12-18 06:07:59 +00:00
def receive_gift ( request , nonce ) :
try :
gift = models . Gift . objects . get ( acq__nonce = nonce )
except models . Gift . DoesNotExist :
2016-08-15 19:22:32 +00:00
return render ( request , ' gift_error.html ' , )
2014-12-18 23:10:04 +00:00
context = { ' gift ' : gift , " site " : Site . objects . get_current ( ) }
2014-12-18 06:07:59 +00:00
work = gift . acq . work
context [ ' work ' ] = work
2014-12-18 16:41:06 +00:00
# put nonce in session so we know that a user has redeemed a Gift
request . session [ ' gift_nonce ' ] = nonce
2014-12-18 06:07:59 +00:00
if gift . used :
2015-03-18 02:11:55 +00:00
if request . user . is_authenticated ( ) :
#check that user hasn't redeemed the gift themselves
2017-10-28 22:33:58 +00:00
if ( gift . acq . user_id == request . user . id ) and not gift . acq . expired :
2016-08-15 19:22:32 +00:00
return HttpResponseRedirect ( reverse ( ' display_gift ' , args = [ gift . id , ' existing ' ] ) )
return render ( request , ' gift_error.html ' , context )
2015-03-18 02:11:55 +00:00
if request . user . is_authenticated ( ) :
2014-12-18 06:07:59 +00:00
user_license = work . get_user_license ( request . user )
if user_license and user_license . purchased :
2014-12-20 17:47:15 +00:00
# check if previously purchased- there would be two user licenses if so.
2014-12-22 23:08:13 +00:00
if user_license . is_duplicate or request . user . id == gift . giver . id :
2014-12-20 17:47:15 +00:00
# regift
if request . method == ' POST ' :
2016-08-15 19:22:32 +00:00
form = RegiftForm ( data = request . POST )
2014-12-20 17:47:15 +00:00
if form . is_valid ( ) :
giftee = models . Gift . giftee ( form . cleaned_data [ ' give_to ' ] , request . user . username )
new_acq = models . Acq . objects . create ( user = giftee , work = gift . acq . work , license = gift . acq . license )
new_gift = models . Gift . objects . create ( acq = new_acq , message = form . cleaned_data [ ' give_message ' ] , giver = request . user , to = form . cleaned_data [ ' give_to ' ] )
context [ ' gift ' ] = new_gift
gift . acq . expire_in ( 0 )
gift . use ( )
notification . send ( [ giftee ] , " purchase_gift " , context , True )
return render ( request , ' gift_duplicate.html ' , context )
2016-08-15 19:22:32 +00:00
context [ ' form ' ] = RegiftForm ( )
2014-12-20 17:47:15 +00:00
return render ( request , ' gift_duplicate.html ' , context )
else :
# new book!
2016-08-15 19:22:32 +00:00
gift . use ( )
2014-12-20 17:47:15 +00:00
request . user . wishlist . add_work ( gift . acq . work , ' gift ' )
2016-08-15 19:22:32 +00:00
return HttpResponseRedirect ( reverse ( ' display_gift ' , args = [ gift . id , ' existing ' ] ) )
2014-12-18 06:07:59 +00:00
else :
# we'll just leave the old user inactive.
gift . acq . user = request . user
gift . acq . save ( )
2016-08-15 19:22:32 +00:00
gift . use ( )
2014-12-18 06:07:59 +00:00
request . user . wishlist . add_work ( gift . acq . work , ' gift ' )
2016-08-15 19:22:32 +00:00
return HttpResponseRedirect ( reverse ( ' display_gift ' , args = [ gift . id , ' existing ' ] ) )
2014-12-22 19:21:40 +00:00
if ( gift . acq . created - gift . acq . user . date_joined ) > timedelta ( minutes = 1 ) or gift . used :
2014-12-18 06:07:59 +00:00
# giftee is established user (or gift has been used), ask them to log in
return superlogin ( request , extra_context = context , template_name = ' gift_login.html ' )
else :
2014-12-22 19:24:49 +00:00
# giftee is a new user, log them in
2014-12-18 06:07:59 +00:00
gift . use ( )
gift . acq . user . wishlist . add_work ( gift . acq . work , ' gift ' )
login_user ( request , gift . acq . user )
2016-08-15 19:22:32 +00:00
return HttpResponseRedirect ( reverse ( ' display_gift ' , args = [ gift . id , ' newuser ' ] ) )
@login_required
def display_gift ( request , gift_id , message ) :
2014-12-18 06:07:59 +00:00
try :
gift = models . Gift . objects . get ( id = gift_id )
except models . Gift . DoesNotExist :
2016-08-15 19:22:32 +00:00
return render ( request , ' gift_error.html ' , )
2017-10-28 22:33:58 +00:00
if request . user . id != gift . acq . user_id :
2014-12-18 06:07:59 +00:00
return HttpResponse ( " this is not your gift " )
2014-12-18 16:41:06 +00:00
redeemed_gift = request . session . get ( ' gift_nonce ' , None ) == gift . acq . nonce
2014-12-20 17:47:15 +00:00
context = { ' gift ' : gift , ' work ' : gift . acq . work , ' message ' : message }
2014-12-18 16:41:06 +00:00
if request . method == ' POST ' and redeemed_gift :
2016-08-15 19:22:32 +00:00
form = UserNamePass ( data = request . POST )
2014-12-18 16:41:06 +00:00
form . oldusername = request . user . username
context [ ' form ' ] = form
if form . is_valid ( ) :
request . user . username = form . cleaned_data [ ' username ' ]
request . user . set_password ( form . cleaned_data [ ' password1 ' ] )
request . user . save ( )
context . pop ( ' form ' )
context [ ' passmessage ' ] = " changed userpass "
return render ( request , ' gift_welcome.html ' , context )
else :
if redeemed_gift :
2016-08-15 19:22:32 +00:00
form = UserNamePass ( initial = { ' username ' : request . user . username } )
2014-12-18 16:41:06 +00:00
form . oldusername = request . user . username
context [ ' form ' ] = form
return render ( request , ' gift_welcome.html ' , context )
2016-08-15 19:22:32 +00:00
@login_required
@csrf_exempt
2013-03-04 22:01:33 +00:00
def ml_status ( request ) :
return render ( request , " ml_status.html " )
@require_POST
2016-08-15 19:22:32 +00:00
@login_required
2013-03-04 22:01:33 +00:00
def ml_subscribe ( request ) :
2016-08-15 19:22:32 +00:00
request . user . profile . ml_subscribe (
double_optin = False ,
send_welcome = True ,
merge_vars = { " OPTIN_IP " : request . META [ ' REMOTE_ADDR ' ] , " OPTIN_TIME " : now ( ) . isoformat ( ) }
)
2013-03-04 22:01:33 +00:00
return HttpResponseRedirect ( reverse ( " notification_notice_settings " ) )
@require_POST
2016-08-15 19:22:32 +00:00
@login_required
2013-03-04 22:01:33 +00:00
def ml_unsubscribe ( request ) :
request . user . profile . ml_unsubscribe ( )
return HttpResponseRedirect ( reverse ( " notification_notice_settings " ) )
2016-08-15 19:22:32 +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
} )
2016-08-15 19:22:32 +00:00
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 ( )
2016-08-15 19:22:32 +00:00
2013-04-04 15:09:18 +00:00
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
} )
2013-05-31 15:34:51 +00:00
2013-05-31 19:19:58 +00:00
@login_required
2013-09-06 02:54:11 +00:00
def kindle_config ( request , work_id = None ) :
2013-09-09 19:48:27 +00:00
if work_id :
work = safe_get_work ( work_id )
else :
work = None
2013-06-25 20:01:08 +00:00
template = " kindle_config.html "
2013-05-31 19:19:58 +00:00
if request . method == ' POST ' :
form = KindleEmailForm ( request . POST )
if form . is_valid ( ) :
request . user . profile . kindle_email = form . cleaned_data [ ' kindle_email ' ]
request . user . profile . save ( )
2013-06-25 20:01:08 +00:00
template = " kindle_change_successful.html "
2013-05-31 19:19:58 +00:00
else :
2016-08-15 19:22:32 +00:00
form = KindleEmailForm ( )
2015-03-05 22:35:55 +00:00
return render ( request , template , {
2016-08-15 19:22:32 +00:00
' form ' : form ,
' work ' : work ,
2015-03-05 22:35:55 +00:00
' ok_email ' : request . user . profile . kindle_email and ( ' kindle ' in request . user . profile . kindle_email ) ,
} )
2013-06-05 15:06:07 +00:00
2013-05-31 21:15:22 +00:00
@require_POST
@csrf_exempt
2013-09-06 02:54:11 +00:00
def send_to_kindle ( request , work_id , javascript = ' 0 ' ) :
2013-06-25 05:11:43 +00:00
# make sure to gracefully communicate with both js and non-js (kindle!) users
2014-02-08 23:32:11 +00:00
def local_response ( request , javascript , context , message ) :
context [ ' message ' ] = message
2013-06-05 15:06:07 +00:00
if javascript == ' 1 ' :
2016-08-15 19:22:32 +00:00
return render ( request , ' kindle_response_message.html ' , context )
2013-06-05 15:06:07 +00:00
else :
2014-02-08 23:32:11 +00:00
return render ( request , ' kindle_response_graceful_degradation.html ' , context )
2016-08-15 19:22:32 +00:00
work = safe_get_work ( work_id )
context = { ' work ' : work }
2013-09-06 02:54:11 +00:00
acq = None
2016-08-15 19:22:32 +00:00
if request . user . is_authenticated ( ) :
all_acqs = request . user . acqs . filter ( work = work ) . order_by ( ' -created ' )
2014-05-05 16:21:59 +00:00
for an_acq in all_acqs :
if not an_acq . expired :
# skip for THANKS
if an_acq . license == THANKED :
acq = None
break
# prepare this acq for download
if not an_acq . watermarked or an_acq . watermarked . expired :
if not an_acq . on_reserve :
watermark_acq . delay ( an_acq )
acq = an_acq
break
2016-08-15 19:22:32 +00:00
2013-09-06 02:54:11 +00:00
if acq :
2015-07-09 19:08:16 +00:00
ebook = acq . ebook ( )
2015-03-03 22:39:23 +00:00
title = acq . work . kindle_safe_title ( )
2013-09-06 02:54:11 +00:00
else :
non_google_ebooks = work . ebooks ( ) . exclude ( provider = ' Google Books ' )
try :
ebook = non_google_ebooks . filter ( format = ' mobi ' ) [ 0 ]
except IndexError :
try :
ebook = non_google_ebooks . filter ( format = ' pdf ' ) [ 0 ]
except IndexError :
raise Http404
2013-06-10 15:57:59 +00:00
2013-09-06 02:54:11 +00:00
# don't forget to increment the download counter!
ebook . increment ( )
logger . info ( ' ebook: {0} , user_ip: {1} ' . format ( work_id , request . META [ ' REMOTE_ADDR ' ] ) )
2015-03-03 22:39:23 +00:00
title = ebook . edition . work . kindle_safe_title ( )
2015-07-02 02:06:33 +00:00
context [ ' ebook ' ] = ebook
2013-06-10 15:57:59 +00:00
if request . POST . has_key ( ' kindle_email ' ) :
kindle_email = request . POST [ ' kindle_email ' ]
try :
validate_email ( kindle_email )
except ValidationError :
2014-02-08 23:32:11 +00:00
return local_response ( request , javascript , context , 3 )
2013-06-10 15:57:59 +00:00
request . session [ ' kindle_email ' ] = kindle_email
2013-06-24 17:53:28 +00:00
elif request . user . is_authenticated ( ) :
2016-08-15 19:22:32 +00:00
kindle_email = request . user . profile . kindle_email
2014-02-08 23:32:11 +00:00
context [ ' kindle_email ' ] = kindle_email
2013-05-31 21:15:22 +00:00
2016-08-15 19:22:32 +00:00
2013-07-05 12:43:02 +00:00
"""
2017-07-27 14:33:13 +00:00
Amazon SES has a 10 MB size limit ( https : / / aws . amazon . com / ses / faqs / #49) in messages sent
2013-07-05 12:43:02 +00:00
to determine whether the file will meet this limit , we probably need to compare the
size of the mime - encoded file to 10 MB . ( and it ' s unclear exactly what the Amazon FAQ means precisely by
2017-07-27 14:33:13 +00:00
MB either : https : / / en . wikipedia . org / wiki / Megabyte ) http : / / www . velocityreviews . com / forums / t335208 - how - to - get - size - of - email - attachment . html might help
2013-07-05 12:43:02 +00:00
for the moment , we will hardwire a 749229 limit in filesize :
* assume conservative size of megabyte , 1000000 B
* leave 1 KB for headers
* mime encoding will add 33 % to filesize
This won ' t perfectly measure size of email, but should be safe, and is much faster than doing the check after download.
"""
2015-07-02 02:07:04 +00:00
try :
2016-05-09 22:32:38 +00:00
filehandle = ebook . get_archive ( )
2015-07-02 02:07:04 +00:00
except IOError :
# problems connection to the ebook source
logger . error ( " couldn ' t connect error: %s " , ebook . url )
return local_response ( request , javascript , context , 5 )
2015-07-02 02:06:33 +00:00
if not ebook . filesize :
2016-05-09 22:32:38 +00:00
return local_response ( request , javascript , context , 4 )
2015-07-02 02:06:33 +00:00
if ebook . filesize > models . send_to_kindle_limit :
2013-09-06 02:54:11 +00:00
logger . info ( ' ebook %s is too large to be emailed ' % work . id )
2014-02-08 23:32:11 +00:00
return local_response ( request , javascript , context , 0 )
2016-08-15 19:22:32 +00:00
2013-06-03 21:18:42 +00:00
try :
2013-06-24 19:42:51 +00:00
email = EmailMessage ( from_email = ' notices@gluejar.com ' ,
2013-06-07 14:19:06 +00:00
to = [ kindle_email ] )
2015-07-02 02:06:33 +00:00
email . attach ( title + ' . ' + ebook . format , filehandle . read ( ) )
2013-06-03 21:18:42 +00:00
email . send ( )
2013-06-04 14:22:11 +00:00
except :
2015-06-03 03:45:30 +00:00
logger . error ( ' Unexpected error: %s ' , sys . exc_info ( ) )
2014-02-08 23:32:11 +00:00
return local_response ( request , javascript , context , 1 )
2013-06-05 15:06:07 +00:00
2013-06-10 15:57:59 +00:00
if request . POST . has_key ( ' kindle_email ' ) and not request . user . is_authenticated ( ) :
2013-06-10 13:29:18 +00:00
return HttpResponseRedirect ( reverse ( ' superlogin ' ) )
2014-02-08 23:32:11 +00:00
return local_response ( request , javascript , context , 2 )
2016-08-15 19:22:32 +00:00
2014-10-27 15:55:46 +00:00
def userlist_marc ( request , userlist = None ) :
2013-07-29 21:59:52 +00:00
if userlist :
2016-08-15 19:22:32 +00:00
user = get_object_or_404 ( User , username = userlist )
2014-10-27 15:55:46 +00:00
return qs_marc_records ( request , qs = user . wishlist . works . all ( ) )
2013-07-29 21:59:52 +00:00
else :
2014-10-27 15:55:46 +00:00
return qs_marc_records ( request , qs = request . user . wishlist . works . all ( ) )
2016-08-15 19:22:32 +00:00
return render ( request , ' marc.html ' , { ' userlist ' : [ ] } )
2014-10-27 15:55:46 +00:00
def work_marc ( request , work_id ) :
work = safe_get_work ( work_id )
return qs_marc_records ( request , qs = [ work ] )
2013-07-15 20:35:41 +00:00
2016-08-15 19:22:32 +00:00
2014-10-27 23:11:44 +00:00
class LibModeView ( FormView ) :
2013-07-23 16:23:04 +00:00
template_name = ' marc_config.html '
2014-10-27 23:11:44 +00:00
form_class = LibModeForm
2013-07-23 16:23:04 +00:00
success_url = reverse_lazy ( ' marc ' )
2016-08-15 19:22:32 +00:00
2013-07-23 16:23:04 +00:00
def form_valid ( self , form ) :
2016-08-15 19:22:32 +00:00
enable = form . data . has_key ( ' enable ' )
2014-10-27 15:55:46 +00:00
if enable :
try :
libpref = self . request . user . libpref
except :
libpref = models . Libpref ( user = self . request . user )
libpref . save ( )
messages . success ( self . request , " Tools are enabled. " )
else :
try :
self . request . user . libpref . delete ( )
except :
pass
2016-08-15 19:22:32 +00:00
messages . success ( self . request , " Tools are disabled. " )
2013-07-23 16:23:04 +00:00
if reverse ( ' marc_config ' , args = [ ] ) in self . request . META [ ' HTTP_REFERER ' ] :
return HttpResponseRedirect ( reverse ( ' marc_config ' , args = [ ] ) )
else :
2014-10-27 23:11:44 +00:00
return super ( LibModeView , self ) . form_valid ( form )
2014-06-20 20:53:25 +00:00
2016-08-15 19:22:32 +00:00