Merge branch 'relaunch' of github.com:Gluejar/regluit into relaunch

pull/1/head
Andromeda Yelton 2012-09-28 10:40:56 -04:00
commit 839a864149
6 changed files with 133 additions and 40 deletions

View File

@ -210,6 +210,47 @@ class Campaign(models.Model):
except:
return u"Campaign %s (no associated work)" % self.name
def clone(self):
"""use a previous UNSUCCESSFUL campaign's data as the basis for a new campaign"""
if self.clonable():
old_managers= self.managers.all()
# copy custom premiums
new_premiums= self.premiums.filter(type='CU')
# setting pk to None will insert new copy http://stackoverflow.com/a/4736172/7782
self.pk = None
self.status = 'INITIALIZED'
# set deadline far in future -- presumably RH will set deadline to proper value before campaign launched
self.deadline = date_today() + timedelta(days=int(settings.UNGLUEIT_LONGEST_DEADLINE))
# allow created, activated dates to be autoset by db
self.created = None
self.name = 'copy of %s' % self.name
self.activated = None
self.update_left()
self.save()
self.managers=old_managers
# clone associated premiums
for premium in new_premiums:
premium.pk=None
premium.created = None
premium.campaign = self
premium.save()
return self
else:
return None
def clonable(self):
"""campaign clonable if it's UNSUCCESSFUL and is the last campaign associated with a Work"""
if self.status == 'UNSUCCESSFUL' and self.work.last_campaign().id==self.id:
return True
else:
return False
@property
def launchable(self):
may_launch=True
@ -341,7 +382,9 @@ class Campaign(models.Model):
@property
def supporters_count(self):
# avoid transmitting the whole list if you don't need to; let the db do the count.
return self.transactions().filter(status=TRANSACTION_STATUS_ACTIVE).values_list('user', flat=True).distinct().count()
active = self.transactions().filter(status=TRANSACTION_STATUS_ACTIVE).values_list('user', flat=True).distinct().count()
complete = self.transactions().filter(status=TRANSACTION_STATUS_COMPLETE).values_list('user', flat=True).distinct().count()
return active+complete
def transaction_to_recharge(self, user):
"""given a user, return the transaction to be recharged if there is one -- None otherwise"""

View File

@ -14,7 +14,7 @@ from django.contrib.sites.models import Site
from django.http import Http404
from regluit.payment.models import Transaction
from regluit.core.models import Campaign, Work, UnglueitError, Edition, RightsHolder, Claim, Key, Ebook
from regluit.core.models import Campaign, Work, UnglueitError, Edition, RightsHolder, Claim, Key, Ebook, Premium
from regluit.core import bookloader, models, search, goodreads, librarything
from regluit.core import isbn
from regluit.payment.parameters import PAYMENT_TYPE_AUTHORIZATION
@ -388,6 +388,8 @@ class CampaignTests(TestCase):
w = Work()
w.save()
w2 = Work()
w2.save()
# INITIALIZED
c1 = Campaign(target=D('1000.00'),deadline=datetime(2013,1,1),work=w)
c1.save()
@ -402,6 +404,8 @@ class CampaignTests(TestCase):
rh.save()
cl = Claim(rights_holder = rh, work = w, user = u, status = 'active')
cl.save()
cl2 = Claim(rights_holder = rh, work = w2, user = u, status = 'active')
cl2.save()
c2.activate()
self.assertEqual(c2.status, 'ACTIVE')
# SUSPENDED
@ -414,14 +418,25 @@ class CampaignTests(TestCase):
# should not let me suspend a campaign that hasn't been initialized
self.assertRaises(UnglueitError, c1.suspend, "for testing")
# UNSUCCESSFUL
c3 = Campaign(target=D('1000.00'),deadline=now() - timedelta(days=1),work=w)
c3 = Campaign(target=D('1000.00'),deadline=now() - timedelta(days=1),work=w2)
c3.save()
c3.activate()
self.assertEqual(c3.status, 'ACTIVE')
# at this point, since the deadline has passed, the status should change and be UNSUCCESSFUL
self.assertTrue(c3.update_status())
self.assertEqual(c3.status, 'UNSUCCESSFUL')
# premiums
pr1= Premium(type='CU', campaign=c3, amount=10, description='botsnack', limit=1)
pr1.save()
self.assertEqual(pr1.premium_remaining,1)
#cloning (note we changed c3 to w2 to make it clonable)
c7= c3.clone()
self.assertEqual(c7.status, 'INITIALIZED')
self.assertEqual(c7.premiums.all()[0].description , 'botsnack')
# SUCCESSFUL
c4 = Campaign(target=D('1000.00'),deadline=now() - timedelta(days=1),work=w)
c4.save()

View File

@ -164,6 +164,9 @@ class UserData(forms.Form):
return username
raise forms.ValidationError(_("Your username is already "+username))
class CloneCampaignForm(forms.Form):
campaign_id = forms.IntegerField(required = True, widget = forms.HiddenInput)
class OpenCampaignForm(forms.ModelForm):
managers = AutoCompleteSelectMultipleField(
OwnerLookup,

View File

@ -208,8 +208,9 @@ Please fix the following before launching your campaign:
{{ form.deadline.errors }}<span style="display: none">{{ form.deadline }}</span>
{% endifnotequal %}
<h3>Email address</h3>
<p>Enter the email address we should contact you at for issues relating to managing this campaign.</p>
<h3>e-mail contact address</h3>
<p>Enter the email address where notifications about this campaign should be sent. If your campaign succeeds, this email needs to work if you want to get paid!</p>
<p>{{ form.paypal_receiver.errors }}{{ form.paypal_receiver }}</p>

View File

@ -20,21 +20,33 @@
Any questions not covered here? Please email us at <a href="mailto:rights@gluejar.com">rights@gluejar.com</a>.
</div></div>
{% if request.user.campaigns.all %}
{% if campaigns %}
<h2>Campaigns You Manage</h2>
<dl>
{% for campaign in request.user.campaigns.all %}
{% for campaign in campaigns %}
<dt>Work: <a href="{% url work work_id=campaign.work.id %}">{{campaign.work.title }}</a></dt>
<dd>
<div class="work_campaigns clearfix">
<div class="campaign_info">
Campaign: {{ campaign.name }}<br />
Campaign status: {{ campaign.status }} <br />
Created: {{ campaign.created }}
</div>
<div>
<a href="{% url manage_campaign campaign.id %}" class="manage">Manage This Campaign</a>
Created: {{ campaign.created }}<br />
${{ campaign.current_total }} pledged of ${{ campaign.target }}, {{ campaign.supporters_count }} supporters
</div>
{% if campaign.status = 'ACTIVE' or campaign.status = 'INITIALIZED' %}
<div>
<a href="{% url manage_campaign campaign.id %}" class="manage">Manage This Campaign</a>
</div>
{% endif %}
{% if campaign.clone_form %}
<div>
<form method="POST" action="#">
{% csrf_token %}
{{ campaign.clone_form }}{{ campaign.clone_form.errors }}
<input type="submit" name="clone" value="Clone this Campaign">
</form>
</div>
{% endif %}
</div>
</dd>
{% endfor %}
@ -51,7 +63,7 @@ Any questions not covered here? Please email us at <a href="mailto:rights@gluej
<br />Date of Claim : {{ claim.created }}
<br />Status of Claim: {{ claim.get_status_display }}
{% if claim.can_open_new %}
<h3>Open a campaign for this work</h3>
<h3>Open a blank campaign for this work</h3>
<form method="POST" action="#">
{% csrf_token %}
<p>Name the Campaign: {{ claim.campaign_form.name }}{{ claim.campaign_form.name.errors }}</p>
@ -67,20 +79,30 @@ Any questions not covered here? Please email us at <a href="mailto:rights@gluej
<h3>Campaigns for this work</h3>
{% for campaign in claim.campaigns %}
<div class="work_campaigns clearfix">
<div class="campaign_info">
Name: Your campaign, "{{ campaign.name }}", is {{ campaign.status }}<br />
Created: {{ campaign.created }}<br />
Manager(s): {% for user in campaign.managers.all %} <a href="{% url supporter user.username %}">{{ user.username }} </a> {% endfor %}
<form method="POST" action="#">{% csrf_token %}
Add/Remove Managers: {{ campaign.edit_managers_form.managers }}{{ campaign.edit_managers_form.managers.errors }}
<input type="submit" name="edit_managers_{{campaign.id}}" value="Save Managers">
</form>
</div>
{% if request.user in campaign.managers.all %}
<div>
<a href="{% url manage_campaign campaign.id %}" class="manage">Manage This Campaign</a>
</div>
{% endif %}
{% if campaign.status = 'ACTIVE' or campaign.status = 'INITIALIZED' %}
<div class="campaign_info">
Name: Your campaign, "{{ campaign.name }}", is {{ campaign.status }}<br />
Created: {{ campaign.created }}<br />
Manager(s): {% for user in campaign.managers.all %} <a href="{% url supporter user.username %}">{{ user.username }} </a> {% endfor %}
<form method="POST" action="#">{% csrf_token %}
Add/Remove Managers: {{ campaign.edit_managers_form.managers }}{{ campaign.edit_managers_form.managers.errors }}
<input type="submit" name="edit_managers_{{campaign.id}}" value="Save Managers">
</form>
</div>
{% if request.user in campaign.managers.all %}
<div>
<a href="{% url manage_campaign campaign.id %}" class="manage">Manage This Campaign</a>
</div>
{% endif %}
{% else %}
<div class="campaign_info">
Name: Your campaign, "{{ campaign.name }}", is {{ campaign.status }}<br />
Created: {{ campaign.created }}<br />
Manager(s): {% for user in campaign.managers.all %} <a href="{% url supporter user.username %}">{{ user.username }} </a> {% endfor %}
<br />
${{ campaign.current_total }} pledged of ${{ campaign.target }}, {{ campaign.supporters_count }} supporters
</div>
{% endif %}
</div>
{% endfor %}
{% endif %}
@ -138,20 +160,19 @@ Any questions not covered here? Please email us at <a href="mailto:rights@gluej
</li>
</ol>
<h2>Rightsholder social media tools</h2>
Needs to be written. What would you find helpful in a social media toolkit? <a href="/feedback">Send us feedback.</a>
<h2>Rewards</h2>
<p>Campaigns have rewards as a way to thank supporters. unglue.it includes a standard set of rewards in all campaigns. You are encouraged to add additional sweeteners to motivate people to contribute.</p>
<p>Campaigns can have rewards as a way to motivate and thank supporters. You are strongly encouraged to add rewards - they are given special prominence on the campaign page.</p>
<p>Here are the standard rewards:</p>
<p>What should you add as rewards? Anything you think you can reasonably deliver that will get supporters excited about the book. For example: other books, whether electronic or physical; artwork or multimedia relating to the book, its author, or its themes; in-person or online chats with the author; memorabilia.</p>
<h2>Acknowledgements</h2>
<p>Here are the standard acknowledgements. These automatically combine with your rewards. For example, if you offer a $30 reward, ungluers who pledge $30 will receive the $25 acknowledgement as well.</p>
<ul class="terms">
<li><em>Any level ($1 minimum)</em> &#8212; The unglued ebook delivered to your inbox</li>
<li><em>$25</em> &#8212; Your username under "supporters" in the acknowledgements section</li>
<li><em>$50</em> &#8212; Your name &amp; profile link under "benefactors"</li>
<li><em>$100</em> &#8212; Your name, profile link, &amp; profile tagline under "bibliophiles"</li>
<li><em>Any amount</em> &#8212; The unglued ebook</li>
<li><em>$25 and above</em> &#8212; Their name in the acknowledgements section under "supporters"</li>
<li><em>$50 and above</em> &#8212; Their name &amp; profile link under "benefactors"</li>
<li><em>$100 and above</em> &#8212; Their name, profile link, &amp; a dedication under "bibliophiles"</li>
</ul>
<h2>More Questions</h2>

View File

@ -48,7 +48,7 @@ from regluit.frontend.forms import UserData, UserEmail, ProfileForm, CampaignPle
from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm
from regluit.frontend.forms import getManageCampaignForm, DonateForm, CampaignAdminForm, EmailShareForm, FeedbackForm
from regluit.frontend.forms import EbookForm, CustomPremiumForm, EditManagersForm, EditionForm, PledgeCancelForm
from regluit.frontend.forms import getTransferCreditForm, CCForm
from regluit.frontend.forms import getTransferCreditForm, CCForm, CloneCampaignForm
from regluit.payment.manager import PaymentManager
from regluit.payment.models import Transaction, Account
from regluit.payment.parameters import TRANSACTION_STATUS_ACTIVE, TRANSACTION_STATUS_COMPLETE, TRANSACTION_STATUS_CANCELED, TRANSACTION_STATUS_ERROR, TRANSACTION_STATUS_FAILED, TRANSACTION_STATUS_INCOMPLETE, TRANSACTION_STATUS_NONE, TRANSACTION_STATUS_MODIFIED
@ -1154,7 +1154,7 @@ def rh_tools(request):
claim.campaigns = claim.work.campaigns.all()
else:
claim.campaigns = []
claim.can_open_new=True
claim.can_open_new=False if claim.work.last_campaign_status in ['ACTIVE','INITIALIZED'] else True
for campaign in claim.campaigns:
if campaign.status in ['ACTIVE','INITIALIZED']:
claim.can_open_new=False
@ -1179,7 +1179,17 @@ def rh_tools(request):
claim.campaign_form = OpenCampaignForm(data={'work': claim.work, 'name': claim.work.title, 'userid': request.user.id, 'managers_1': request.user.id})
else:
claim.can_open_new=False
return render(request, "rh_tools.html", {'claims': claims ,})
campaigns = request.user.campaigns.all()
new_campaign = None
for campaign in campaigns:
if campaign.clonable():
if request.method == 'POST' and request.POST.has_key('c%s-campaign_id'% campaign.id):
clone_form= CloneCampaignForm(data=request.POST, prefix = 'c%s' % campaign.id)
if clone_form.is_valid():
campaign.clone()
else:
campaign.clone_form= CloneCampaignForm(initial={'campaign_id':campaign.id}, prefix = 'c%s' % campaign.id)
return render(request, "rh_tools.html", {'claims': claims ,'campaigns': campaigns})
def rh_admin(request):
if not request.user.is_authenticated() :