2011-10-10 16:57:10 +00:00
|
|
|
import random
|
2011-10-10 17:09:00 +00:00
|
|
|
import datetime
|
2011-10-10 16:57:10 +00:00
|
|
|
from decimal import Decimal
|
|
|
|
|
2011-08-31 03:46:55 +00:00
|
|
|
from django.db import models
|
2011-09-29 06:23:50 +00:00
|
|
|
from django.db.models import Q
|
2011-09-02 04:10:54 +00:00
|
|
|
from django.contrib.auth.models import User
|
2011-10-10 16:57:10 +00:00
|
|
|
|
2011-10-08 03:11:57 +00:00
|
|
|
class UnglueitError(RuntimeError):
|
|
|
|
pass
|
2011-09-06 03:50:38 +00:00
|
|
|
|
2011-08-31 03:46:55 +00:00
|
|
|
class Campaign(models.Model):
|
2011-09-02 04:10:54 +00:00
|
|
|
created = models.DateTimeField(auto_now_add=True)
|
2011-10-14 19:37:22 +00:00
|
|
|
name = models.CharField(max_length=500, null=True, blank=False)
|
|
|
|
description = models.TextField(null=True, blank=False)
|
|
|
|
target = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=False)
|
|
|
|
deadline = models.DateTimeField()
|
2011-10-07 21:17:54 +00:00
|
|
|
activated = models.DateTimeField(null=True)
|
|
|
|
suspended = models.DateTimeField(null=True)
|
|
|
|
withdrawn = models.DateTimeField(null=True)
|
2011-10-14 19:37:22 +00:00
|
|
|
suspended_reason = models.TextField(null=True, blank=True)
|
|
|
|
withdrawn_reason = models.TextField(null=True, blank=True)
|
|
|
|
paypal_receiver = models.CharField(max_length=100, blank=True)
|
|
|
|
amazon_receiver = models.CharField(max_length=100, blank=True)
|
2011-10-09 18:27:27 +00:00
|
|
|
work = models.ForeignKey("Work", related_name="campaigns", null=False)
|
2011-09-10 11:36:38 +00:00
|
|
|
|
|
|
|
def __unicode__(self):
|
2011-10-08 03:11:57 +00:00
|
|
|
try:
|
|
|
|
return u"Campaign for %s" % self.work.title
|
|
|
|
except:
|
|
|
|
return u"Campaign %s (no associated work)" % self.name
|
2011-10-10 20:35:22 +00:00
|
|
|
|
|
|
|
@property
|
2011-10-07 21:17:54 +00:00
|
|
|
def status(self):
|
|
|
|
"""Returns the status of the campaign
|
|
|
|
"""
|
2011-10-08 03:11:57 +00:00
|
|
|
now = datetime.datetime.utcnow()
|
|
|
|
|
2011-10-07 21:17:54 +00:00
|
|
|
if self.activated is None:
|
|
|
|
return 'INITIALIZED'
|
2011-10-09 18:27:27 +00:00
|
|
|
elif self.suspended is not None:
|
|
|
|
return 'SUSPENDED'
|
|
|
|
elif self.withdrawn is not None:
|
|
|
|
return 'WITHDRAWN'
|
|
|
|
elif self.deadline < now:
|
2011-10-10 20:56:53 +00:00
|
|
|
if self.current_total >= self.target:
|
2011-10-09 18:27:27 +00:00
|
|
|
return 'SUCCESSFUL'
|
2011-10-08 03:11:57 +00:00
|
|
|
else:
|
2011-10-09 18:27:27 +00:00
|
|
|
return 'UNSUCCESSFUL'
|
|
|
|
else:
|
|
|
|
return 'ACTIVE'
|
2011-10-08 03:11:57 +00:00
|
|
|
|
2011-10-10 20:56:53 +00:00
|
|
|
@property
|
|
|
|
def current_total(self):
|
|
|
|
p = PaymentManager()
|
|
|
|
return p.query_campaign(campaign=self,summary=True)
|
|
|
|
|
2011-10-13 17:28:23 +00:00
|
|
|
def transactions(self, pledged=True, authorized=True):
|
|
|
|
p = PaymentManager()
|
|
|
|
return p.query_campaign(campaign=self, summary=False, pledged=pledged, authorized=authorized)
|
|
|
|
|
2011-10-08 03:11:57 +00:00
|
|
|
def activate(self):
|
2011-10-10 20:35:22 +00:00
|
|
|
status = self.status
|
2011-10-08 03:11:57 +00:00
|
|
|
if status != 'INITIALIZED':
|
|
|
|
raise UnglueitError('Campaign needs to be initialized in order to be activated')
|
2011-10-09 18:27:27 +00:00
|
|
|
self.activated = datetime.datetime.utcnow()
|
|
|
|
self.save()
|
|
|
|
return self
|
2011-10-08 03:11:57 +00:00
|
|
|
|
|
|
|
def suspend(self, reason):
|
2011-10-10 20:35:22 +00:00
|
|
|
status = self.status
|
2011-10-08 03:11:57 +00:00
|
|
|
if status != 'ACTIVE':
|
|
|
|
raise UnglueitError('Campaign needs to be active in order to be suspended')
|
2011-10-09 18:27:27 +00:00
|
|
|
self.suspended = datetime.datetime.utcnow()
|
2011-10-14 14:28:41 +00:00
|
|
|
self.suspended_reason = reason
|
2011-10-09 18:27:27 +00:00
|
|
|
self.save()
|
|
|
|
return self
|
2011-10-08 03:11:57 +00:00
|
|
|
|
|
|
|
def withdraw(self, reason):
|
2011-10-10 20:35:22 +00:00
|
|
|
status = self.status
|
2011-10-08 03:11:57 +00:00
|
|
|
if status != 'ACTIVE':
|
|
|
|
raise UnglueitError('Campaign needs to be active in order to be withdrawn')
|
2011-10-09 18:27:27 +00:00
|
|
|
self.withdrawn = datetime.datetime.utcnow()
|
|
|
|
self.withdrawn_reason = reason
|
|
|
|
self.save()
|
|
|
|
return self
|
2011-10-08 03:11:57 +00:00
|
|
|
|
|
|
|
def resume(self):
|
|
|
|
"""Change campaign status from SUSPENDED to ACTIVE. We may want to track reason for resuming and track history"""
|
2011-10-10 20:35:22 +00:00
|
|
|
status = self.status
|
2011-10-08 03:11:57 +00:00
|
|
|
if status != 'SUSPENDED':
|
|
|
|
raise UnglueitError('Campaign needs to be suspended in order to be resumed')
|
2011-10-09 18:27:27 +00:00
|
|
|
self.suspended = None
|
|
|
|
self.suspended_reason = None
|
|
|
|
self.save()
|
|
|
|
return self
|
2011-09-10 11:36:38 +00:00
|
|
|
|
|
|
|
|
2011-08-31 03:46:55 +00:00
|
|
|
class Work(models.Model):
|
|
|
|
created = models.DateTimeField(auto_now_add=True)
|
2011-09-02 04:10:54 +00:00
|
|
|
title = models.CharField(max_length=1000)
|
2011-09-10 11:36:38 +00:00
|
|
|
openlibrary_id = models.CharField(max_length=50, null=True)
|
|
|
|
|
2011-09-29 06:23:50 +00:00
|
|
|
def cover_image_small(self):
|
2011-10-20 03:31:16 +00:00
|
|
|
return self.editions.all()[0].cover_image_small()
|
2011-09-29 06:23:50 +00:00
|
|
|
|
2011-10-14 13:43:30 +00:00
|
|
|
def last_campaign_status(self):
|
2011-10-25 23:07:44 +00:00
|
|
|
try:
|
|
|
|
last = self.campaigns.order_by('-created')[0].status
|
|
|
|
except:
|
|
|
|
last = "No campaign yet"
|
|
|
|
return last
|
2011-10-14 13:43:30 +00:00
|
|
|
|
|
|
|
def percent_unglued(self):
|
2011-10-25 23:07:44 +00:00
|
|
|
if(self.last_campaign_status() == 'SUCCESSFUL'):
|
|
|
|
return 6;
|
|
|
|
elif(self.last_campaign_status() == 'ACTIVE'):
|
|
|
|
target = float(self.campaigns.order_by('-created')[0].target)
|
|
|
|
if target <= 0:
|
|
|
|
return 6
|
|
|
|
else:
|
|
|
|
total = float(self.campaigns.order_by('-created')[0].current_total)
|
|
|
|
percent = int(total*6/target)
|
|
|
|
if percent >= 6:
|
|
|
|
return 6
|
|
|
|
else:
|
|
|
|
return percent;
|
|
|
|
else:
|
|
|
|
return 0;
|
2011-10-14 13:43:30 +00:00
|
|
|
|
2011-09-10 11:36:38 +00:00
|
|
|
def __unicode__(self):
|
|
|
|
return self.title
|
2011-08-31 03:46:55 +00:00
|
|
|
|
2011-09-09 05:38:28 +00:00
|
|
|
|
|
|
|
class Author(models.Model):
|
|
|
|
created = models.DateTimeField(auto_now_add=True)
|
|
|
|
name = models.CharField(max_length=500)
|
2011-10-10 16:57:10 +00:00
|
|
|
editions = models.ManyToManyField("Edition", related_name="authors")
|
2011-09-09 05:38:28 +00:00
|
|
|
|
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
|
|
|
|
2011-09-10 11:36:38 +00:00
|
|
|
|
2011-09-09 05:38:28 +00:00
|
|
|
class Subject(models.Model):
|
|
|
|
created = models.DateTimeField(auto_now_add=True)
|
|
|
|
name = models.CharField(max_length=500)
|
2011-10-10 16:57:10 +00:00
|
|
|
editions = models.ManyToManyField("Edition", related_name="subjects")
|
2011-09-09 05:38:28 +00:00
|
|
|
|
2011-09-10 11:36:38 +00:00
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
2011-08-31 03:46:55 +00:00
|
|
|
class Edition(models.Model):
|
2011-10-10 16:57:10 +00:00
|
|
|
googlebooks_id = models.CharField(max_length=50, null=False)
|
2011-08-31 03:46:55 +00:00
|
|
|
created = models.DateTimeField(auto_now_add=True)
|
|
|
|
title = models.CharField(max_length=1000)
|
2011-09-30 01:57:12 +00:00
|
|
|
description = models.TextField(default='', null=True)
|
2011-08-31 03:46:55 +00:00
|
|
|
publisher = models.CharField(max_length=255)
|
2011-09-09 05:38:28 +00:00
|
|
|
publication_date = models.CharField(max_length=50)
|
2011-09-10 11:36:38 +00:00
|
|
|
isbn_10 = models.CharField(max_length=10, null=True)
|
|
|
|
isbn_13 = models.CharField(max_length=13, null=True)
|
2011-09-30 01:57:12 +00:00
|
|
|
work = models.ForeignKey("Work", related_name="editions", null=True)
|
2011-10-14 04:02:19 +00:00
|
|
|
language = models.CharField(max_length=2, null=True)
|
2011-08-31 03:46:55 +00:00
|
|
|
|
2011-09-09 18:27:29 +00:00
|
|
|
def __unicode__(self):
|
2011-10-10 21:26:38 +00:00
|
|
|
return "%s (%s)" % (self.title, self.isbn_13)
|
2011-09-09 18:27:29 +00:00
|
|
|
|
2011-10-20 03:31:16 +00:00
|
|
|
def cover_image_small(self):
|
|
|
|
server_id = random.randint(0, 9)
|
|
|
|
return "http://bks%i.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=5" % (server_id, self.googlebooks_id)
|
|
|
|
|
|
|
|
def cover_image_thumbnail(self):
|
|
|
|
server_id = random.randint(0, 9)
|
|
|
|
return "http://bks%s.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=1" % (server_id, self.googlebooks_id)
|
|
|
|
|
2011-09-29 06:23:50 +00:00
|
|
|
@classmethod
|
|
|
|
def get_by_isbn(klass, isbn):
|
|
|
|
for e in Edition.objects.filter(Q(isbn_10=isbn) | Q(isbn_13=isbn)):
|
|
|
|
return e
|
|
|
|
return None
|
2011-08-31 03:46:55 +00:00
|
|
|
|
2011-10-14 14:18:38 +00:00
|
|
|
|
2011-09-02 04:10:54 +00:00
|
|
|
class Wishlist(models.Model):
|
|
|
|
created = models.DateTimeField(auto_now_add=True)
|
|
|
|
user = models.OneToOneField(User, related_name='wishlist')
|
|
|
|
works = models.ManyToManyField('Work', related_name='wishlists')
|
2011-09-12 05:53:54 +00:00
|
|
|
|
2011-10-14 14:18:38 +00:00
|
|
|
|
2011-10-03 16:36:04 +00:00
|
|
|
class UserProfile(models.Model):
|
2011-10-13 16:22:38 +00:00
|
|
|
user = models.OneToOneField(User, related_name='profile')
|
2011-10-03 16:36:04 +00:00
|
|
|
tagline = models.CharField(max_length=140, blank=True)
|
2011-10-25 03:32:32 +00:00
|
|
|
home_url = models.URLField(blank=True)
|
|
|
|
twitter_id = models.CharField(max_length=15, blank=True)
|
2011-09-12 05:53:54 +00:00
|
|
|
|
2011-10-25 01:29:01 +00:00
|
|
|
#class GoodreadsProfile(models.Model):
|
|
|
|
# user_id = models.CharField(max_length=32)
|
|
|
|
# username = models.CharField(max_length=200, blank=True)
|
|
|
|
# auth_token = models.TextField(null=True, blank=True)
|
|
|
|
# auth_secret = models.TextField(null=True, blank=True)
|
|
|
|
|
2011-09-12 05:53:54 +00:00
|
|
|
from regluit.core import signals
|
2011-10-08 03:11:57 +00:00
|
|
|
from regluit.payment.manager import PaymentManager
|