Merge branch 'master' of https://github.com/Gluejar/regluit
commit
f7282d4e11
|
@ -62,7 +62,7 @@ class BookLoaderTests(TestCase):
|
|||
models.Identifier(type='isbn', value='9780226032030', work=w, edition=e).save()
|
||||
bookloader.update_edition(e)
|
||||
self.assertEqual(e.work.language, 'en')
|
||||
self.assertEqual(e.title, 'Forbidden journeys')
|
||||
self.assertEqual(e.title, 'Forbidden Journeys')
|
||||
|
||||
def test_double_add(self):
|
||||
bookloader.add_by_isbn('0441012035')
|
||||
|
|
|
@ -1 +1,81 @@
|
|||
# Create your views here.
|
||||
from regluit.core.models import Campaign
|
||||
from django.http import HttpResponse
|
||||
import traceback
|
||||
from django.db import transaction
|
||||
import time
|
||||
|
||||
def test_read(request):
|
||||
|
||||
try:
|
||||
|
||||
row_id = 1
|
||||
|
||||
print "Attempting to read row"
|
||||
|
||||
# A read the waits for the exclusive lock for the row
|
||||
campaign = Campaign.objects.raw("SELECT * FROM core_campaign WHERE id=%d FOR UPDATE" % row_id)[0]
|
||||
|
||||
print "Successfully read row data %d" % campaign.target
|
||||
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
return HttpResponse("Success")
|
||||
|
||||
def test_write(request):
|
||||
|
||||
try:
|
||||
|
||||
row_id = 1
|
||||
campaign = Campaign.objects.get(id=row_id)
|
||||
|
||||
print "Attempting to write row via ordinary ORM"
|
||||
|
||||
#
|
||||
# Modify the data. This will block if any shared lock (Either FOR UPDATE or LOCK IN SHARED MODE is held
|
||||
#
|
||||
campaign.target = campaign.target + 10
|
||||
campaign.save()
|
||||
|
||||
print "Successfully write new row data %d" % campaign.target
|
||||
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
return HttpResponse("Success")
|
||||
|
||||
@transaction.commit_on_success
|
||||
def test_lock(request):
|
||||
|
||||
try:
|
||||
row_id = 1
|
||||
|
||||
print "Attempting to acquire row lock"
|
||||
|
||||
campaign = Campaign.objects.raw("SELECT * FROM core_campaign WHERE id=%d FOR UPDATE" % row_id)[0]
|
||||
|
||||
print "Row lock acquired, modifying data"
|
||||
|
||||
# Modify the data
|
||||
campaign.target = campaign.target + 10
|
||||
campaign.save()
|
||||
|
||||
#
|
||||
# test by sleeping here for 10 seconds.
|
||||
#
|
||||
# The FOR UPDATE request will lock the row exclusively. All write/delete operations require a compatible lock
|
||||
# and will block until this transaction is complete. Some reads will block, but some will not. If we want to
|
||||
# block the read until this transaction is complete, the read should also acquire an exlusive OR a shared lock.
|
||||
#
|
||||
# As soon as the function completes, the transaction will be committed and the lock released.
|
||||
# You can modify the commit_on_success decorator to get different transaction behaviors
|
||||
#
|
||||
print "Thread sleeping for 10 seconds"
|
||||
time.sleep(10)
|
||||
print "Thread sleep complete"
|
||||
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
return HttpResponse("Success")
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<b>UNGLUE IT!</b>
|
||||
<p><b>${{ work.last_campaign.current_total|floatformat:0|intcomma }}</b> raised</p>
|
||||
<p><b>${{ work.last_campaign.target|floatformat:0|intcomma }}</b> needed</p>
|
||||
<p>by {{ deadline|date:"M d, Y" }}</p>
|
||||
<p>by {{ deadline|naturalday:"M d, Y" }}</p>
|
||||
<a href="/pledge/{{workid}}"><div class="read_itbutton pledge"><span>Support</span></div></a>
|
||||
|
||||
{% else %}{% if status == 'INITIALIZED' %}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
We thought you might like to know there are new comments for a book you have commented on.
|
||||
|
||||
{{ comment.user.username }} on {{ comment.content_object.title }}:
|
||||
{{ comment.user.username }} has commented on a book you also commented on, {{ comment.content_object.title }}, as follows.
|
||||
|
||||
{{ comment.comment }}
|
||||
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
{% load humanize %}You have modified a pledge that you had previously made to the campaign to unglue {{ transaction.campaign.work.title }}.
|
||||
{% load humanize %}{% if up_or_down == 'canceled' %}You have canceled a pledge that you had previously made to the campaign to unglue {{ transaction.campaign.work.title }}.
|
||||
|
||||
Your canceled pledge
|
||||
Amount: ${{ transaction.amount|intcomma }}
|
||||
Premium: {% if transaction.premium %}{{ transaction.premium.description }}{% else %}None requested{% endif %}
|
||||
{% else %}You have modified a pledge that you had previously made to the campaign to unglue {{ transaction.campaign.work.title }}.
|
||||
|
||||
Your new pledge summary
|
||||
Amount pledged: ${{ transaction.amount|intcomma }}
|
||||
Premium: {% if transaction.premium %}{{ transaction.premium.description }}{% else %}None requested{% endif %}
|
||||
Premium: {% if transaction.premium %}{{ transaction.premium.description }}{% else %}None requested{% endif %}{% endif %}
|
||||
|
||||
{% if transaction.host|lower == 'amazon' %}{% if status == 'increased' %}
|
||||
{% if transaction.host|lower == 'amazon' %}{% if up_or_down == 'increased' %}
|
||||
You will also receive an email from Amazon confirming this.
|
||||
{% else %}{% if status == 'decreased' %}
|
||||
{% else %}{% if up_or_down == 'decreased' %}
|
||||
Your Amazon Payments account may still show an authorization to Unglue.it for the entire amount of your earlier pledge, but never fear -- if the campaign succeeds, we'll only charge you ${{ transaction.amount|intcomma }}.
|
||||
{% endif %}{% endif %}{% else %}{% endif %}
|
||||
|
||||
|
|
|
@ -6,15 +6,19 @@
|
|||
<a href="{% url work transaction.campaign.work.id %}"><img src="{{ transaction.campaign.work.cover_image_small }}" alt="cover image for {{ title }}" /></a>
|
||||
</div>
|
||||
<div class="comments_graphical">
|
||||
Your pledge for the campaign to unglue {{ title }} has been modified.
|
||||
Your pledge for the campaign to unglue {{ title }} has been {% if up_or_down == 'canceled'%}canceled{% else %}modified{% endif %}.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="comments_textual">
|
||||
{% if up_or_down == 'canceled' %}<div class="comments_textual">
|
||||
Your canceled pledge was as follows:<br />
|
||||
Amount: ${{ transaction.amount|intcomma }}<br />
|
||||
Premium: {% if transaction.premium %}{{ transaction.premium.description }}{% else %}None requested{% endif %}<br />
|
||||
</div>{% else %}<div class="comments_textual">
|
||||
Your new pledge is as follows:<br />
|
||||
Amount: ${{ transaction.amount|intcomma }}<br />
|
||||
Premium: {% if transaction.premium %}{{ transaction.premium.description }}{% else %}None requested{% endif %}<br />
|
||||
Thank you for your continued support of {{ title }}.
|
||||
</div>
|
||||
</div>{% endif %}
|
||||
</div>
|
||||
{% endwith %}
|
|
@ -1 +1 @@
|
|||
Your pledge has been modified for {{ transaction.campaign.work.title}}
|
||||
Your pledge has been {% if up_or_down == 'canceled'%}canceled{% else %}modified{% endif %} for {{ transaction.campaign.work.title}}
|
|
@ -1,6 +1,4 @@
|
|||
We thought you might like to know there's a new comment for a book on your wishlist.
|
||||
|
||||
{{ comment.user.username }} has commented on {{ comment.content_object.title }}:
|
||||
{{ comment.user.username }} has commented on a book on your wishlist, {{ comment.content_object.title }}, as follows.
|
||||
|
||||
{{ comment.comment }}
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
We thought you might like to know that Unglue.it staff or the book's rights holder have news about a book on your wishlist.
|
||||
|
||||
{{ comment.user.username }} has commented on {{ comment.content_object.title }}:
|
||||
{{ comment.user.username }} has official news about a book on your wishlist, {{ comment.content_object.title }}.
|
||||
|
||||
{{ comment.comment }}
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
|
||||
<a id="latest"></a><h2>Latest Press</h2>
|
||||
<div class="pressarticles">
|
||||
<div>
|
||||
<a href="hhttp://mashable.com/2012/06/14/unglueit/">Unglue.it Wants to Make a Creative Commons for Ebooks</a><br />
|
||||
Mashable - June 14, 2012
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://www.huffingtonpost.com/2012/05/21/unglueit-free-ebooks-crowdfunding_n_1532644.html">Unglue.it Makes Free EBooks Through A Unique Crowdfunding Website</a><br />
|
||||
Huffington Post - May 21, 2012
|
||||
|
@ -34,10 +38,6 @@
|
|||
<a href="http://boingboing.net/2012/05/18/raising-money-to-free-classic.html">Raising money to free classic volume on Africa's oral literature</a><br />
|
||||
Boing Boing - May 18, 2012<br />
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://lj.libraryjournal.com/2012/05/publishing/ebook-crowdfunding-platform-unglue-it-launched/">Ebook Crowdfunding Platform Unglue.it Launched</a><br />
|
||||
Library Journal - May 17, 2012
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="overview"></a><h2>Overview</h2>
|
||||
|
@ -73,6 +73,14 @@ Creative Commons offers a variety of other licenses, many of them with even less
|
|||
</dl>
|
||||
<a id="press"></a><h2>Press Coverage</h2>
|
||||
<div class="pressarticles">
|
||||
<div>
|
||||
<a href="hhttp://mashable.com/2012/06/14/unglueit/">Unglue.it Wants to Make a Creative Commons for Ebooks</a><br />
|
||||
Mashable - June 14, 2012
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://goodereader.com/blog/electronic-readers/buzzwords-from-bookexpo/">Buzzwords from BookExpo</a><br />
|
||||
Good EReader - June 07, 2012
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://www.huffingtonpost.com/2012/05/21/unglueit-free-ebooks-crowdfunding_n_1532644.html">Unglue.it Makes Free EBooks Through A Unique Crowdfunding Website</a><br />
|
||||
Huffington Post - May 21, 2012
|
||||
|
@ -254,6 +262,11 @@ Creative Commons offers a variety of other licenses, many of them with even less
|
|||
</div>
|
||||
<a id="video"></a><h2>Video</h2>
|
||||
<div class="pressvideos">
|
||||
<div>
|
||||
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/HxjTW4OBouo?rel=0" frameborder="0" allowfullscreen></iframe><br />
|
||||
<I>June 2012</I><br />
|
||||
Eric Hellman at Book Expo America.
|
||||
</div>
|
||||
<div>
|
||||
<div class="mediaborder">
|
||||
<object width="480" height="270"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="https://secure.vimeo.com/moogaloop.swf?clip_id=39352026&server=secure.vimeo.com&show_title=1&show_byline=0&show_portrait=0&color=00adef&fullscreen=1&autoplay=0&loop=0" /><embed src="https://secure.vimeo.com/moogaloop.swf?clip_id=39352026&server=secure.vimeo.com&show_title=1&show_byline=0&show_portrait=0&color=00adef&fullscreen=1&autoplay=0&loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="480" height="270"></embed></object></div><br />
|
||||
|
|
|
@ -139,13 +139,23 @@ def work(request, work_id, action='display'):
|
|||
|
||||
countdown = ""
|
||||
if work.last_campaign_status() == 'ACTIVE':
|
||||
from math import ceil
|
||||
time_remaining = campaign.deadline - now()
|
||||
|
||||
'''
|
||||
we want to round up on all of these; if it's the 3rd and the
|
||||
campaign ends the 8th, users expect to see 5 days remaining,
|
||||
not 4 (as an artifact of 4 days 11 hours or whatever)
|
||||
time_remaining.whatever is an int, so just adding 1 will do
|
||||
that for us (except in the case where .days exists and both other
|
||||
fields are 0, which is unlikely enough I'm not defending against it)
|
||||
'''
|
||||
if time_remaining.days:
|
||||
countdown = "in %s days" % time_remaining.days
|
||||
countdown = "in %s days" % str(time_remaining.days + 1)
|
||||
elif time_remaining.seconds > 3600:
|
||||
countdown = "in %s hours" % time_remaining.seconds/3600
|
||||
countdown = "in %s hours" % str(time_remaining.seconds/3600 + 1)
|
||||
elif time_remaining.seconds > 60:
|
||||
countdown = "in %s minutes" % time_remaining.seconds/60
|
||||
countdown = "in %s minutes" % str(time_remaining.seconds/60 + 1)
|
||||
else:
|
||||
countdown = "right now"
|
||||
if action == 'preview':
|
||||
|
@ -772,8 +782,6 @@ class PledgeModifyView(FormView):
|
|||
elif status and url is None:
|
||||
# let's use the pledge_complete template for now and maybe look into customizing it.
|
||||
return HttpResponseRedirect("{0}?tid={1}".format(reverse('pledge_complete'), transaction.id))
|
||||
from regluit.payment.signals import pledge_modified
|
||||
pledge_modified.send(sender=self, transaction=transaction, status="increased")
|
||||
else:
|
||||
return HttpResponse("No modification made")
|
||||
|
||||
|
@ -948,6 +956,11 @@ class PledgeCancelView(FormView):
|
|||
# We might want to remove this in a production system
|
||||
if settings.DEBUG:
|
||||
update_status = p.update_preapproval(transaction)
|
||||
# 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))
|
||||
return HttpResponseRedirect(reverse('work', kwargs={'work_id': campaign.work.id}))
|
||||
else:
|
||||
logger.error("Attempt to cancel transaction id {0} failed".format(transaction.id))
|
||||
|
|
|
@ -50,7 +50,6 @@ AMAZON_OPERATION_TYPE_REFUND = 'REFUND'
|
|||
AMAZON_OPERATION_TYPE_CANCEL = 'CANCEL'
|
||||
|
||||
# load FPS_ACCESS_KEY and FPS_SECRET_KEY from the database if possible
|
||||
|
||||
try:
|
||||
from regluit.core.models import Key
|
||||
FPS_ACCESS_KEY = Key.objects.get(name="FPS_ACCESS_KEY").value
|
||||
|
@ -210,6 +209,7 @@ def amazonPaymentReturn(request):
|
|||
approves a preapproval or a pledge. This URL is set via the PAY api.
|
||||
'''
|
||||
try:
|
||||
transaction = None
|
||||
|
||||
# pick up all get and post parameters and display
|
||||
output = "payment complete"
|
||||
|
@ -279,7 +279,7 @@ def amazonPaymentReturn(request):
|
|||
# We may never see an IPN, set the status here
|
||||
logging.error("Amazon payment authorization failed: ")
|
||||
logging.error(request.GET)
|
||||
transaction.status = AMAZON_STATUS_FAILURE
|
||||
transaction.status = TRANSACTION_STATUS_ERROR
|
||||
|
||||
|
||||
elif transaction.type == PAYMENT_TYPE_AUTHORIZATION:
|
||||
|
@ -295,6 +295,14 @@ def amazonPaymentReturn(request):
|
|||
transaction.status = TRANSACTION_STATUS_ACTIVE
|
||||
transaction.approved = True
|
||||
transaction.pay_key = token
|
||||
transaction.save()
|
||||
|
||||
print "Calling CANCEL RELATED"
|
||||
|
||||
# clear out any other active transactions for this user and this campaign
|
||||
from regluit.payment.manager import PaymentManager
|
||||
p = PaymentManager()
|
||||
p.cancel_related_transaction(transaction, status=TRANSACTION_STATUS_ACTIVE, campaign=transaction.campaign)
|
||||
|
||||
else:
|
||||
# We may never see an IPN, set the status here
|
||||
|
@ -308,8 +316,21 @@ def amazonPaymentReturn(request):
|
|||
status = status,
|
||||
transaction=transaction)
|
||||
|
||||
else:
|
||||
# Corrupt transaciton, unknown type
|
||||
transaction.status = TRANSACTION_STATUS_ERROR
|
||||
|
||||
transaction.save()
|
||||
|
||||
if transaction.status == TRANSACTION_STATUS_ERROR:
|
||||
# We failed, redirect to a page to allow the user to try again
|
||||
return_path = "{0}?{1}".format(reverse('pledge_nevermind'),
|
||||
urllib.urlencode({'tid':transaction.id}))
|
||||
return_url = urlparse.urljoin(settings.BASE_URL, return_path)
|
||||
return HttpResponseRedirect(return_url)
|
||||
|
||||
else:
|
||||
# Not a failure, exact status will be updated by IPN
|
||||
# Redirect to our pledge success URL
|
||||
return_path = "{0}?{1}".format(reverse('pledge_complete'),
|
||||
urllib.urlencode({'tid':transaction.id}))
|
||||
|
@ -320,11 +341,22 @@ def amazonPaymentReturn(request):
|
|||
logging.error("Amazon co-branded return-url FAILED with exception:")
|
||||
traceback.print_exc()
|
||||
|
||||
# BUGBUG: check to see whether status is AMAZON_STATUS_ADBANDONED
|
||||
# if so, ultimately figure out the campaign whose transaction is being canceled out.
|
||||
# for the moment, return the user to BASE_URL
|
||||
|
||||
if request.REQUEST.get("status") == AMAZON_STATUS_ADBANDONED:
|
||||
if transaction:
|
||||
|
||||
# We failed, redirect to a page to allow the user to try again
|
||||
return_path = "{0}?{1}".format(reverse('pledge_nevermind'),
|
||||
urllib.urlencode({'tid':transaction.id}))
|
||||
return_url = urlparse.urljoin(settings.BASE_URL, return_path)
|
||||
return HttpResponseRedirect(return_url)
|
||||
|
||||
else:
|
||||
|
||||
#
|
||||
# If we are here, amazon did not give us a caller reference, so we don't know what transaction was cancelled.
|
||||
# Some kind of cleanup is required. This can happen if there is an error in the amazon API or if the user clicks
|
||||
# the cancel button. If the case where the user closes the co-branded window or hits the back button, we will never arrive here.
|
||||
#
|
||||
return HttpResponseRedirect(settings.BASE_URL)
|
||||
|
||||
class AmazonRequest:
|
||||
|
|
|
@ -198,16 +198,36 @@ class PaymentManager( object ):
|
|||
|
||||
for t in transactions:
|
||||
|
||||
# deal with preapprovals
|
||||
if t.date_payment is None:
|
||||
preapproval_status = self.update_preapproval(t)
|
||||
logger.info("transaction: {0}, preapproval_status: {1}".format(t, preapproval_status))
|
||||
if not set(['status', 'currency', 'amount', 'approved']).isdisjoint(set(preapproval_status.keys())):
|
||||
status["preapprovals"].append(preapproval_status)
|
||||
# update payments
|
||||
else:
|
||||
payment_status = self.update_payment(t)
|
||||
if not set(["status", "receivers"]).isdisjoint(payment_status.keys()):
|
||||
status["payments"].append(payment_status)
|
||||
|
||||
# Clear out older, duplicate preapproval transactions
|
||||
cleared_list = []
|
||||
for p in transactions:
|
||||
|
||||
# pick out only the preapprovals
|
||||
if p.date_payment is None and p.type == PAYMENT_TYPE_AUTHORIZATION and p.status == TRANSACTION_STATUS_ACTIVE and p not in cleared_list:
|
||||
|
||||
# keep only the newest transaction for this user and campaign
|
||||
user_transactions_for_campaign = Transaction.objects.filter(user=p.user, status=TRANSACTION_STATUS_ACTIVE, campaign=p.campaign).order_by('-date_authorized')
|
||||
|
||||
if len(user_transactions_for_campaign) > 1:
|
||||
logger.info("Found %d active transactions for campaign" % len(user_transactions_for_campaign))
|
||||
self.cancel_related_transaction(user_transactions_for_campaign[0], status=TRANSACTION_STATUS_ACTIVE, campaign=transactions[0].campaign)
|
||||
|
||||
cleared_list.extend(user_transactions_for_campaign)
|
||||
|
||||
# Note, we may need to call checkstatus again here
|
||||
|
||||
return status
|
||||
|
||||
|
||||
|
@ -629,10 +649,14 @@ class PaymentManager( object ):
|
|||
# that for whatever reason fail. will need other housekeeping to handle those.
|
||||
# sadly this point is not yet late enough in the process -- needs to be moved
|
||||
# until after we are certain.
|
||||
if modification:
|
||||
pledge_modified.send(sender=self, transaction=t, up_or_down="increased")
|
||||
else:
|
||||
|
||||
if not modification:
|
||||
# BUGBUG:
|
||||
# send the notice here for now
|
||||
# this is actually premature since we're only about to send the user off to the payment system to
|
||||
# authorize a charge
|
||||
pledge_created.send(sender=self, transaction=t)
|
||||
|
||||
return t, url
|
||||
|
||||
|
||||
|
@ -642,6 +666,48 @@ class PaymentManager( object ):
|
|||
logger.info("Authorize Error: " + p.error_string())
|
||||
return t, None
|
||||
|
||||
def cancel_related_transaction(self, transaction, status=TRANSACTION_STATUS_ACTIVE, campaign=None):
|
||||
'''
|
||||
Cancels any other similar status transactions for the same campaign. Used with modify code
|
||||
|
||||
Returns the number of transactions successfully canceled
|
||||
'''
|
||||
|
||||
related_transactions = Transaction.objects.filter(status=status, user=transaction.user)
|
||||
|
||||
if len(related_transactions) == 0:
|
||||
return 0
|
||||
|
||||
if campaign:
|
||||
related_transactions = related_transactions.filter(campaign=campaign)
|
||||
|
||||
canceled = 0
|
||||
|
||||
for t in related_transactions:
|
||||
|
||||
if t.id == transaction.id:
|
||||
# keep our transaction
|
||||
continue
|
||||
|
||||
if self.cancel_transaction(t):
|
||||
canceled = canceled + 1
|
||||
# send notice about modification of transaction
|
||||
if transaction.amount > t.amount:
|
||||
# this should be the only one that happens
|
||||
up_or_down = "increased"
|
||||
elif transaction.amount < t.amount:
|
||||
# we shouldn't expect any case in which this happens
|
||||
up_or_down = "decreased"
|
||||
else:
|
||||
# we shouldn't expect any case in which this happens
|
||||
up_or_down = None
|
||||
|
||||
pledge_modified.send(sender=self, transaction=transaction, up_or_down=up_or_down)
|
||||
else:
|
||||
logger.error("Failed to cancel transaction {0} for related transaction {1} ".format(t, transaction))
|
||||
|
||||
return canceled
|
||||
|
||||
def modify_transaction(self, transaction, amount, expiry=None, anonymous=None, premium=None,
|
||||
return_url=None, nevermind_url=None,
|
||||
paymentReason=None):
|
||||
|
@ -701,10 +767,15 @@ class PaymentManager( object ):
|
|||
if t and url:
|
||||
# Need to re-direct to approve the transaction
|
||||
logger.info("New authorization needed, redirection to url %s" % url)
|
||||
self.cancel_transaction(transaction)
|
||||
|
||||
# Do not cancel the transaction here, wait until we get confirmation that the transaction is complete
|
||||
# then cancel all other active transactions for this campaign
|
||||
#self.cancel_transaction(transaction)
|
||||
|
||||
# while it would seem to make sense to send a pledge notification change here
|
||||
# if we do, we will also send notifications when we initiate but do not
|
||||
# successfully complete a pledge modification
|
||||
|
||||
return True, url
|
||||
else:
|
||||
# a problem in authorize
|
||||
|
|
|
@ -316,9 +316,6 @@ ul.navigation li.active a {
|
|||
.listview.icons .booklist-status-label {
|
||||
display: none;
|
||||
}
|
||||
.listview.icons .boolist-ebook span {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
div#content-block-content {
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
|
|
@ -251,12 +251,6 @@ ul.navigation li a:hover, ul.navigation li.active a {
|
|||
.booklist-status-label, {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.boolist-ebook {
|
||||
span {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div#content-block-content {
|
||||
|
|
Loading…
Reference in New Issue