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

pull/1/head
Raymond Yee 2012-04-19 10:56:53 -07:00
commit 7fc0ae7165
15 changed files with 129 additions and 111 deletions

View File

@ -8,6 +8,10 @@ from regluit import payment
from djcelery.admin import TaskState, WorkerState, TaskMonitor, WorkerMonitor, \
IntervalSchedule, CrontabSchedule, PeriodicTask, PeriodicTaskAdmin
from notification.admin import NoticeTypeAdmin, NoticeSettingAdmin, NoticeAdmin
from notification.models import NoticeType, NoticeSetting, Notice, ObservedItem, NoticeQueueBatch
import pickle
class RegluitAdmin(AdminSite):
login_template = 'registration/login.html'
@ -67,7 +71,16 @@ class PaymentResponseAdmin(ModelAdmin):
pass
class ReceiverAdmin(ModelAdmin):
ordering = ('email',)
ordering = ('email',)
def notice_queue_batch_data(obj):
return pickle.loads(str(obj.pickled_data).decode("base64"))
notice_queue_batch_data.short_description = 'unpickled_data'
class NoticeQueueBatchAdmin(ModelAdmin):
# show the pickled data in a form humans can parse more easily
list_display = (notice_queue_batch_data,)
pass
admin_site = RegluitAdmin("Admin")
@ -99,3 +112,12 @@ admin_site.register(WorkerState, WorkerMonitor)
admin_site.register(IntervalSchedule)
admin_site.register(CrontabSchedule)
admin_site.register(PeriodicTask, PeriodicTaskAdmin)
# add the django-notification admin panel
# https://github.com/jtauber/django-notification/blob/master/notification/admin.py
admin_site.register(NoticeQueueBatch, NoticeQueueBatchAdmin)
admin_site.register(NoticeType, NoticeTypeAdmin)
admin_site.register(NoticeSetting, NoticeSettingAdmin)
admin_site.register(Notice, NoticeAdmin)
admin_site.register(ObservedItem)

View File

@ -1,3 +1,10 @@
"""
a command that creates a given number of random tasks to test out celery
"""
from django.core.management.base import BaseCommand
from regluit.core import tasks
from regluit.core.models import CeleryTask
@ -11,6 +18,16 @@ class Command(BaseCommand):
args = "<num_tasks action>"
def handle(self, num_tasks, action, **options):
"""
actions:
c: create num_tasks tasks
s: print state of existing tasks
d: delete all tasks
an integer: compute factorial of the integer -- can then follow up with s to find the state
"""
import django
django.db.transaction.enter_transaction_management()
if action == 'c':
for i in xrange(int(num_tasks)):
n = random.randint(1,1000)
@ -41,4 +58,4 @@ class Command(BaseCommand):
ct.save()
except Exception, e:
print e
django.db.transaction.commit()

23
deploy/crontab_please.txt Normal file
View File

@ -0,0 +1,23 @@
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
* * * * * cd /opt/regluit; source /opt/regluit/ENV/bin/activate; /opt/regluit/ENV/bin/django-admin.py emit_notices --settings=regluit.settings.please > /opt/regluit/deploy/emit_notices.log 2>&1 ; touch /opt/regluit/deploy/last-cron

23
deploy/crontab_prod.txt Normal file
View File

@ -0,0 +1,23 @@
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
* * * * * /opt/regluit/deploy/emit_notices.sh

8
deploy/emit_notices.sh Normal file
View File

@ -0,0 +1,8 @@
#!/bin/bash
# run django-admin.py emit_notices
cd /opt/regluit
source /opt/regluit/ENV/bin/activate
/opt/regluit/ENV/bin/django-admin.py emit_notices --settings=regluit.settings.prod > /opt/regluit/deploy/emit_notices.log 2>&1
touch /opt/regluit/deploy/last-cron

View File

@ -9,4 +9,6 @@ django-admin.py collectstatic --noinput --settings regluit.settings.prod
sudo /etc/init.d/apache2 restart
sudo /etc/init.d/celeryd restart
sudo /etc/init.d/celerybeat restart
chmod +x deploy/emit_notices.sh
crontab deploy/crontab_prod.txt
touch /opt/regluit/deploy/last-update

View File

@ -15,4 +15,5 @@ django-admin.py collectstatic --noinput --settings regluit.settings.please
sudo /etc/init.d/apache2 restart
sudo /etc/init.d/celeryd restart
sudo /etc/init.d/celerybeat restart
touch /opt/regluit/deploy/last-update
crontab deploy/crontab_please.txt
touch /opt/regluit/deploy/last-update

View File

@ -41,7 +41,11 @@
<div class="jsmodule rounded">
<div class="jsmod-content">
{% if faqmenu == 'modify' %}
<p>You have pledged ${{preapproval_amount}}. If you would like to modify your pledge, please use the following form.</p>
{% endif %}
{% comment %}
Even there is a CampaignPledgeForm in frontend/forms.py , the "widget" for premium_id is implemented in HTML here for now.
{% endcomment %}
@ -73,7 +77,7 @@
{% endfor %}
</ul>
<input type="submit" value="Pledge" id="pledgesubmit" />
<input type="submit" {% if faqmenu == 'modify' %}value="Modify Pledge"{% else %}value="Pledge"{% endif %} id="pledgesubmit" />
</form>
</div>

View File

@ -32,7 +32,7 @@ we need the share options and also something like the home page slide show to gi
<h2 class="thank-you">Thank you!</h2>
<p class="pledge_complete">You're now ungluing <I>{{work.title}}</I>.</p>
<p class="pledge_complete">You're now ungluing <a href="{% url work work.id %}">{{work.title}}</a>.</p>
<p class="pledge_complete">You can help even more by sharing this campaign with your friends:</p>
<div id="widgetcode">Copy/paste this into your site:<br /><textarea rows="7" cols="22">&lt;iframe src="https://{{request.META.HTTP_HOST}}/api/widget/{{work.first_isbn_13}}/" width="152" height="325" frameborder="0"&gt;&lt;/iframe&gt;</textarea></div>

View File

@ -1,97 +0,0 @@
{% extends "basepledge.html" %}
{% block title %}Pledge (Modify){% endblock %}
{% block extra_extra_head %}
<link type="text/css" rel="stylesheet" href="/static/css/campaign.css" />
<link type="text/css" rel="stylesheet" href="/static/css/pledge.css" />
{% endblock %}
{% block doccontent %}
<div style="height:10px";></div>
<div class="book-detail">
<div class="book-detail-img">
<a href="#"><img src="{{ work.cover_image_thumbnail }}" alt="{{ work.title }}" title="{{ work.title }}" width="131" height="192" /></a>
</div>
<div class="book-detail-info">
<h2 class="book-name">{{ work.title }}</h2>
<h3 class="book-author">{{ work.author }}</h3>
<h3 class="book-year">{{ work.publication_date }}</h3>
<div class="find-book">
<label>Find it here</label>
<div class="find-link">
<a class="find-google" href="{{ work.googlebooks_url }}"><img src="/static/images/supporter_icons/googlebooks_square.png" title="Find on Google Books" alt="Find on Google Books" /></a>
<a rel="nofollow" class="find-openlibrary" href="{% url work_openlibrary work.id %}"><img src="/static/images/supporter_icons/openlibrary_square.png" title="Find on OpenLibrary" alt="Find on OpenLibrary"></a>
{% if not request.user.is_anonymous %}
{% if request.user.profile.goodreads_user_link %}
<a rel="nofollow" class="find-goodreads" href="{% url work_goodreads work.id %}"><img src="/static/images/supporter_icons/goodreads_square.png" title="Find on GoodReads" alt="Find on GoodReads"></a>
{% endif %}
{% if request.user.profile.librarything_id %}
<a rel="nofollow" class="find-librarything" href="{% url work_librarything work.id %}"><img src="/static/images/supporter_icons/librarything_square.png" title="Find on LibraryThing" alt="Find on LibraryThing" /></a>
{% endif %}
{% endif %}
</div>
</div>
<div class="pledged-info">
<div class="pledged-group">
{{ work.last_campaign.supporters.count }} Ungluers have pledged ${{ work.last_campaign.current_total }}
</div>
<div class="status">
<img src="/static/images/images/icon-book-37by25-{{ work.percent_unglued }}.png" title="book list status" alt="book list status" />
</div>
</div>
</div>
</div>
<div class="jsmodule rounded pledge">
<div class="jsmod-content">
${{ work.last_campaign.target }} needed by<br />
{{ work.last_campaign.deadline }}
</div>
</div>
<div class="jsmodule rounded">
<div class="jsmod-content">
<p>You have pledged ${{preapproval_amount}}. If you would like to modify your pledge, please use the following form.</p>
{% comment %}
Even there is a CampaignPledgeForm in frontend/forms.py , the "widget" for premium_id is implemented in HTML here for now.
{% endcomment %}
<form method="POST" action="{% url pledge_modify work_id=work.id %}">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="pledge_amount">{{ form.preapproval_amount.label_tag }}: {{ form.preapproval_amount.errors }}${{ form.preapproval_amount }}</div>
{% comment %}
not supported yet; don't display
{{ form.anonymous.label_tag }}: {{ form.anonymous.errors }}{{ form.anonymous }}
{% endcomment %}
<ul class="support menu">
{% for premium in premiums %}
<label for="{{premium.id}}">
<li class="{% if forloop.first %}first{% else %}{% if forloop.last %}last{% endif %}{% endif %}">
<input type="radio" name="premium_id" value="{{premium.id}}" {% ifequal form.premium_id.value premium.id %}checked="checked"{% endifequal %} />
<span class="menu-item-price">
${{ premium.amount }}
</span>
<span class="menu-item-desc">
{{ premium.description }}
</span>
</a></li></label>
{% endfor %}
</ul>
<input type="submit" value="Modify Pledge" id="pledgesubmit" />
</form>
</div>
{% endblock %}

View File

@ -103,7 +103,7 @@ $j(document).ready(function(){
</div>
{% if status == 'ACTIVE' %}
{% if pledged %}
<div class="btn_support modify"><form action="{% url pledge_modify work_id=work.id %}" method="get"><input type="submit" value="Change Pledge" /></form></div>
<div class="btn_support modify"><form action="{% url pledge_modify work_id=work.id %}" method="get"><input type="submit" value="Modify Pledge" /></form></div>
{% else %}
<div class="btn_support"><form action="{% url pledge work_id=work.id %}" method="get"><input type="submit" value="Support" /></form></div>
{% endif %}

View File

@ -479,7 +479,7 @@ class PledgeModifyView(FormView):
"""
A view to handle request to change an existing pledge
"""
template_name="pledge_modify.html"
template_name="pledge.html"
form_class = CampaignPledgeForm
embedded = False
@ -529,7 +529,7 @@ class PledgeModifyView(FormView):
form_class = self.get_form_class()
form = form_class(initial=data)
context.update({'work':work,'campaign':campaign, 'premiums':premiums, 'form':form,'preapproval_amount':preapproval_amount, 'premium_id':premium_id, 'faqmenu': 'pledge'})
context.update({'work':work,'campaign':campaign, 'premiums':premiums, 'form':form,'preapproval_amount':preapproval_amount, 'premium_id':premium_id, 'faqmenu': 'modify'})
return context

View File

@ -570,7 +570,7 @@ h2.thank-you {
font-size: 34px;
color: #8dc63f;
}
.pledge_complete {
.pledge_complete, .pledge_complete a {
font-size: 14px;
line-height: 17px;
margin-bottom: 14px;
@ -579,7 +579,7 @@ h2.thank-you {
width: 960px !important;
}
h3 .pledge_indent {
margin-left: 215px;
margin-left: 240px;
}
ul.social.pledge {
margin-bottom: 150px;

View File

@ -294,10 +294,10 @@ h2.thank-you {
color: @call-to-action;
}
.pledge_complete {
.pledge_complete, .pledge_complete a {
font-size: 14px;
line-height: 17px;
margin-bottom: 14px;
margin-bottom: 14px;
}
#js-slide .jsmodule.pledge {
@ -305,7 +305,7 @@ h2.thank-you {
}
h3 .pledge_indent {
margin-left: 215px;
margin-left: 240px;
}
ul.social.pledge {

View File

@ -3,6 +3,10 @@ import boto
# connect up parts of the Amazon infrastructure
# notes: to delete snapshots I have made of instances, one has to deregister the AMI first and then delete the snapshot
GLUEJAR_ACCOUNT_ID = 439256357102
ec2 = boto.connect_ec2()
cw = boto.connect_cloudwatch()
rds = boto.connect_rds()
@ -17,12 +21,23 @@ def all_zones():
def all_rds():
return rds.get_all_dbinstances()
def all_snapshots(owner=GLUEJAR_ACCOUNT_ID):
"""by default, return only snapshots owned by Gluejar -- None returns all snapshots available to us"""
return ec2.get_all_snapshots(owner=owner)
def instance(tag_name):
try:
return ec2.get_all_instances(filters={'tag:Name' : tag_name})[0].instances[0]
except Exception, e:
return None
def all_images(owners=(GLUEJAR_ACCOUNT_ID, )):
return ec2.get_all_images(owners=owners)
def stop_instances(instances):
return ec2.stop_instances(instance_ids=[instance.id for instance in instances])
def console_output(instance):
"""returnn console output of instance"""