Merge pull request #386 from Gluejar/pdf_ask

Insert Pdf/epub ask into served files [Take 2]
pull/1/head
eshellman 2014-09-17 04:48:46 -04:00
commit 2223446f36
16 changed files with 1258 additions and 26 deletions

View File

@ -16,7 +16,15 @@ def personalize(epub_file, acq):
output.writetodisk(personalized_epub)
#logger.info("personalized")
return personalized_epub
def ask_epub(epub_file, context):
output = EPUB(epub_file, "a")
part = StringIO(unicode(render_to_string('epub/ask.xhtml', context)))
output.addpart(part, "ask.xhtml", "application/xhtml+xml", 1) #after title, we hope
asking_epub= StringIO()
output.writetodisk(asking_epub)
return asking_epub
def ungluify(epub_file, campaign):
output = EPUB(epub_file, "a")

View File

@ -0,0 +1,351 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Campaign.use_add_ask'
db.add_column('core_campaign', 'use_add_ask',
self.gf('django.db.models.fields.BooleanField')(default=True),
keep_default=False)
# Adding field 'EbookFile.asking'
db.add_column('core_ebookfile', 'asking',
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Campaign.use_add_ask'
db.delete_column('core_campaign', 'use_add_ask')
# Deleting field 'EbookFile.asking'
db.delete_column('core_ebookfile', 'asking')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'booxtream.boox': {
'Meta': {'object_name': 'Boox'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'download_link_epub': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
'download_link_mobi': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
'downloads_remaining': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
'expirydays': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'referenceid': ('django.db.models.fields.CharField', [], {'max_length': '32'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'core.acq': {
'Meta': {'object_name': 'Acq'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'lib_acq': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'loans'", 'null': 'True', 'to': "orm['core.Acq']"}),
'license': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'nonce': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'refreshed': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'refreshes': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 8, 28, 0, 0)', 'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'acqs'", 'to': "orm['auth.User']"}),
'watermarked': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['booxtream.Boox']", 'null': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'acqs'", 'to': "orm['core.Work']"})
},
'core.author': {
'Meta': {'object_name': 'Author'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'editions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'core.badge': {
'Meta': {'object_name': 'Badge'},
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '72', 'blank': 'True'})
},
'core.campaign': {
'Meta': {'object_name': 'Campaign'},
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'cc_date_initial': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'deadline': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'description': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
'details': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
'do_watermark': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'dollar_per_day': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Edition']"}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2', 'db_index': 'True'}),
'license': ('django.db.models.fields.CharField', [], {'default': "'CC BY-NC-ND'", 'max_length': '255'}),
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Publisher']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True', 'db_index': 'True'}),
'target': ('django.db.models.fields.DecimalField', [], {'default': '0.0', 'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'type': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'use_add_ask': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
},
'core.campaignaction': {
'Meta': {'object_name': 'CampaignAction'},
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['core.Campaign']"}),
'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15'})
},
'core.celerytask': {
'Meta': {'object_name': 'CeleryTask'},
'active': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 8, 28, 0, 0)', 'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True'}),
'function_args': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'function_name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'task_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'null': 'True', 'to': "orm['auth.User']"})
},
'core.claim': {
'Meta': {'object_name': 'Claim'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rights_holder': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.RightsHolder']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'active'", 'max_length': '7'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.Work']"})
},
'core.ebook': {
'Meta': {'object_name': 'Ebook'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'download_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebooks'", 'to': "orm['core.Edition']"}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'rights': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
},
'core.ebookfile': {
'Meta': {'object_name': 'EbookFile'},
'asking': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebook_files'", 'to': "orm['core.Edition']"}),
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'core.edition': {
'Meta': {'object_name': 'Edition'},
'cover_image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'publication_date': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'publisher_name': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.PublisherName']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'unglued': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.Work']"})
},
'core.hold': {
'Meta': {'object_name': 'Hold'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'library': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'holds'", 'to': "orm['libraryauth.Library']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'holds'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'holds'", 'to': "orm['core.Work']"})
},
'core.identifier': {
'Meta': {'unique_together': "(('type', 'value'),)", 'object_name': 'Identifier'},
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'null': 'True', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
'value': ('django.db.models.fields.CharField', [], {'max_length': '31'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Work']"})
},
'core.key': {
'Meta': {'object_name': 'Key'},
'encrypted_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'core.libpref': {
'Meta': {'object_name': 'Libpref'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'marc_link_target': ('django.db.models.fields.CharField', [], {'default': "'UNGLUE'", 'max_length': '6'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'libpref'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.marcrecord': {
'Meta': {'object_name': 'MARCRecord'},
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'MARCrecords'", 'null': 'True', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'link_target': ('django.db.models.fields.CharField', [], {'default': "'DIRECT'", 'max_length': '6'})
},
'core.offer': {
'Meta': {'object_name': 'Offer'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'license': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'offers'", 'to': "orm['core.Work']"})
},
'core.premium': {
'Meta': {'object_name': 'Premium'},
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'limit': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
},
'core.press': {
'Meta': {'object_name': 'Press'},
'date': ('django.db.models.fields.DateField', [], {'db_index': 'True'}),
'highlight': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'note': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'max_length': '140'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '140'}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
'core.publisher': {
'Meta': {'object_name': 'Publisher'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'key_publisher'", 'to': "orm['core.PublisherName']"}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'})
},
'core.publishername': {
'Meta': {'object_name': 'PublisherName'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'alternate_names'", 'null': 'True', 'to': "orm['core.Publisher']"})
},
'core.rightsholder': {
'Meta': {'object_name': 'RightsHolder'},
'can_sell': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rights_holder'", 'to': "orm['auth.User']"}),
'rights_holder_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'core.subject': {
'Meta': {'ordering': "['name']", 'object_name': 'Subject'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"})
},
'core.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'avatar_source': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1', 'null': 'True'}),
'badges': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'holders'", 'symmetrical': 'False', 'to': "orm['core.Badge']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'facebook_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'goodreads_auth_secret': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_auth_token': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_user_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'goodreads_user_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'goodreads_user_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'home_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'kindle_email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'blank': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '31', 'blank': 'True'}),
'pic_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'tagline': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'twitter_id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.waswork': {
'Meta': {'object_name': 'WasWork'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'moved': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
'was': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Work']"})
},
'core.wishes': {
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15', 'blank': 'True'}),
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wishes'", 'to': "orm['core.Work']"})
},
'core.wishlist': {
'Meta': {'object_name': 'Wishlist'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
},
'core.work': {
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
'earliest_publication': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'featured': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '5', 'db_index': 'True'}),
'num_wishes': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True'}),
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'selected_edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'selected_works'", 'null': 'True', 'to': "orm['core.Edition']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
},
'libraryauth.library': {
'Meta': {'object_name': 'Library'},
'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'backend': ('django.db.models.fields.CharField', [], {'default': "'ip'", 'max_length': '10'}),
'group': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'library'", 'unique': 'True', 'null': 'True', 'to': "orm['auth.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '80'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'libraries'", 'to': "orm['auth.User']"}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'library'", 'unique': 'True', 'to': "orm['auth.User']"})
}
}
complete_apps = ['core']

View File

@ -0,0 +1,345 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Ebook.active'
db.add_column('core_ebook', 'active',
self.gf('django.db.models.fields.BooleanField')(default=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Ebook.active'
db.delete_column('core_ebook', 'active')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'booxtream.boox': {
'Meta': {'object_name': 'Boox'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'download_link_epub': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
'download_link_mobi': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
'downloads_remaining': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
'expirydays': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'referenceid': ('django.db.models.fields.CharField', [], {'max_length': '32'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'core.acq': {
'Meta': {'object_name': 'Acq'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'lib_acq': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'loans'", 'null': 'True', 'to': "orm['core.Acq']"}),
'license': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'nonce': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'refreshed': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'refreshes': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 9, 4, 0, 0)', 'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'acqs'", 'to': "orm['auth.User']"}),
'watermarked': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['booxtream.Boox']", 'null': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'acqs'", 'to': "orm['core.Work']"})
},
'core.author': {
'Meta': {'object_name': 'Author'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'editions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'core.badge': {
'Meta': {'object_name': 'Badge'},
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '72', 'blank': 'True'})
},
'core.campaign': {
'Meta': {'object_name': 'Campaign'},
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'cc_date_initial': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'deadline': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'description': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
'details': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': 'True'}),
'do_watermark': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'dollar_per_day': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Edition']"}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2', 'db_index': 'True'}),
'license': ('django.db.models.fields.CharField', [], {'default': "'CC BY-NC-ND'", 'max_length': '255'}),
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'null': 'True', 'to': "orm['core.Publisher']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True', 'db_index': 'True'}),
'target': ('django.db.models.fields.DecimalField', [], {'default': '0.0', 'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'type': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'use_add_ask': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
},
'core.campaignaction': {
'Meta': {'object_name': 'CampaignAction'},
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['core.Campaign']"}),
'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15'})
},
'core.celerytask': {
'Meta': {'object_name': 'CeleryTask'},
'active': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 9, 4, 0, 0)', 'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True'}),
'function_args': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'function_name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'task_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'null': 'True', 'to': "orm['auth.User']"})
},
'core.claim': {
'Meta': {'object_name': 'Claim'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rights_holder': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.RightsHolder']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'active'", 'max_length': '7'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.Work']"})
},
'core.ebook': {
'Meta': {'object_name': 'Ebook'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'download_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebooks'", 'to': "orm['core.Edition']"}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'rights': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
},
'core.ebookfile': {
'Meta': {'object_name': 'EbookFile'},
'asking': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebook_files'", 'to': "orm['core.Edition']"}),
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'core.edition': {
'Meta': {'object_name': 'Edition'},
'cover_image': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'publication_date': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'publisher_name': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.PublisherName']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'unglued': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'null': 'True', 'to': "orm['core.Work']"})
},
'core.hold': {
'Meta': {'object_name': 'Hold'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'library': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'holds'", 'to': "orm['libraryauth.Library']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'holds'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'holds'", 'to': "orm['core.Work']"})
},
'core.identifier': {
'Meta': {'unique_together': "(('type', 'value'),)", 'object_name': 'Identifier'},
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'null': 'True', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
'value': ('django.db.models.fields.CharField', [], {'max_length': '31'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Work']"})
},
'core.key': {
'Meta': {'object_name': 'Key'},
'encrypted_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'core.libpref': {
'Meta': {'object_name': 'Libpref'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'marc_link_target': ('django.db.models.fields.CharField', [], {'default': "'UNGLUE'", 'max_length': '6'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'libpref'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.marcrecord': {
'Meta': {'object_name': 'MARCRecord'},
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'MARCrecords'", 'null': 'True', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'link_target': ('django.db.models.fields.CharField', [], {'default': "'DIRECT'", 'max_length': '6'})
},
'core.offer': {
'Meta': {'object_name': 'Offer'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'license': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'offers'", 'to': "orm['core.Work']"})
},
'core.premium': {
'Meta': {'object_name': 'Premium'},
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'limit': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
},
'core.press': {
'Meta': {'object_name': 'Press'},
'date': ('django.db.models.fields.DateField', [], {'db_index': 'True'}),
'highlight': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'note': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'max_length': '140'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '140'}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
'core.publisher': {
'Meta': {'object_name': 'Publisher'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'key_publisher'", 'to': "orm['core.PublisherName']"}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'})
},
'core.publishername': {
'Meta': {'object_name': 'PublisherName'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'publisher': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'alternate_names'", 'null': 'True', 'to': "orm['core.Publisher']"})
},
'core.rightsholder': {
'Meta': {'object_name': 'RightsHolder'},
'can_sell': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rights_holder'", 'to': "orm['auth.User']"}),
'rights_holder_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'core.subject': {
'Meta': {'ordering': "['name']", 'object_name': 'Subject'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"})
},
'core.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'avatar_source': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1', 'null': 'True'}),
'badges': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'holders'", 'symmetrical': 'False', 'to': "orm['core.Badge']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'facebook_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'goodreads_auth_secret': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_auth_token': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_user_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'goodreads_user_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'goodreads_user_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'home_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'kindle_email': ('django.db.models.fields.EmailField', [], {'max_length': '254', 'blank': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '31', 'blank': 'True'}),
'pic_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'tagline': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'twitter_id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.waswork': {
'Meta': {'object_name': 'WasWork'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'moved': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
'was': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Work']"})
},
'core.wishes': {
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15', 'blank': 'True'}),
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wishes'", 'to': "orm['core.Work']"})
},
'core.wishlist': {
'Meta': {'object_name': 'Wishlist'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
},
'core.work': {
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
'earliest_publication': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'featured': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '5', 'db_index': 'True'}),
'num_wishes': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True'}),
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'selected_edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'selected_works'", 'null': 'True', 'to': "orm['core.Edition']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
},
'libraryauth.library': {
'Meta': {'object_name': 'Library'},
'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'backend': ('django.db.models.fields.CharField', [], {'default': "'ip'", 'max_length': '10'}),
'group': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'library'", 'unique': 'True', 'null': 'True', 'to': "orm['auth.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '80'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'libraries'", 'to': "orm['auth.User']"}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'library'", 'unique': 'True', 'to': "orm['auth.User']"})
}
}
complete_apps = ['core']

View File

@ -14,6 +14,7 @@ from datetime import timedelta, datetime
from decimal import Decimal
from notification import models as notification
from postmonkey import PostMonkey, MailChimpException
from tempfile import SpooledTemporaryFile
'''
django imports
@ -34,7 +35,8 @@ regluit imports
import regluit
import regluit.core.isbn
import regluit.core.cc as cc
from regluit.core.epub import personalize, ungluify, test_epub
from regluit.core.epub import personalize, ungluify, test_epub, ask_epub
from regluit.core.pdf import ask_pdf, pdf_append
from regluit.core.signals import (
successful_campaign,
@ -399,6 +401,7 @@ class Campaign(models.Model):
email = models.CharField(max_length=100, blank=True)
publisher = models.ForeignKey("Publisher", related_name="campaigns", null=True)
do_watermark = models.BooleanField(default=True)
use_add_ask = models.BooleanField(default=True)
def __init__(self, *args, **kwargs):
self.problems=[]
@ -898,6 +901,60 @@ class Campaign(models.Model):
def latest_ending(cls):
return (timedelta(days=int(settings.UNGLUEIT_LONGEST_DEADLINE)) + now())
def add_ask_to_ebfs(self, position=0):
if not self.use_add_ask or self.type != THANKS :
return
done_formats= []
for ebf in self.work.ebookfiles().filter(asking = False).order_by('-created'):
if ebf.format=='pdf' and 'pdf' not in done_formats:
try:
added = ask_pdf({'campaign':self, 'work':self.work, 'site':Site.objects.get_current()})
new_file = SpooledTemporaryFile()
old_file = SpooledTemporaryFile()
ebf.file.open()
old_file.write(ebf.file.read())
if position==0:
pdf_append(added, old_file, new_file)
else:
pdf_append(old_file, added, new_file)
new_file.seek(0)
new_ebf = EbookFile.objects.create(edition=ebf.edition, format='pdf', asking=True)
new_ebf.file.save(path_for_file(ebf,None),ContentFile(new_file.read()))
new_ebf.save()
for old_ebf in self.work.ebookfiles().filter(asking = True, format='pdf').exclude(pk=new_ebf.pk):
obsolete = Ebook.objects.filter(url=old_ebf.file.url)
for eb in obsolete:
eb.deactivate()
old_ebf.delete()
done_formats.append('pdf')
except Exception as e:
logger.error("error appending pdf ask %s" % (e))
elif ebf.format=='epub' and 'epub' not in done_formats:
try:
new_file = SpooledTemporaryFile()
old_file = SpooledTemporaryFile()
ebf.file.open()
old_file.write(ebf.file.read())
new_file= ask_epub(old_file, {'campaign':self, 'work':self.work, 'site':Site.objects.get_current()})
new_file.seek(0)
new_ebf = EbookFile.objects.create(edition=ebf.edition, format='epub', asking=True)
new_ebf.file.save(path_for_file(ebf,None),ContentFile(new_file.read()))
new_ebf.save()
for old_ebf in self.work.ebookfiles().filter(asking = True, format='epub').exclude(pk=new_ebf.pk):
obsolete = Ebook.objects.filter(url=old_ebf.file.url)
for eb in obsolete:
eb.deactivate()
old_ebf.delete()
done_formats.append('epub')
except Exception as e:
logger.error("error making epub ask %s" % (e))
self.work.make_ebooks_from_ebfs()
def make_unglued_ebf(self, format, watermarked):
ebf=EbookFile.objects.create(edition=self.work.preferred_edition, format=format)
r=urllib2.urlopen(watermarked.download_link(format))
@ -917,7 +974,7 @@ class Campaign(models.Model):
provider="Unglue.it",
)
for old_ebook in old_ebooks:
old_ebook.delete()
old_ebook.deactivate()
return ebook.pk
@ -1163,31 +1220,33 @@ class Work(models.Model):
campaign = self.last_campaign()
return 0 if campaign is None else campaign.percent_of_goal()
def ebooks(self):
return Ebook.objects.filter(edition__work=self).order_by('-created')
def ebooks(self, all=False):
if all:
return Ebook.objects.filter(edition__work=self).order_by('-created')
else:
return Ebook.objects.filter(edition__work=self,active=True).order_by('-created')
def ebookfiles(self):
# filter out non-epub because that's what booxtream accepts
return EbookFile.objects.filter(edition__work=self).order_by('-created')
return EbookFile.objects.filter(edition__work=self).exclude(file='').order_by('-created')
def epubfiles(self):
# filter out non-epub because that's what booxtream accepts
return EbookFile.objects.filter(edition__work=self, format='epub').order_by('-created')
return EbookFile.objects.filter(edition__work=self, format='epub').exclude(file='').order_by('-created')
def mobifiles(self):
return EbookFile.objects.filter(edition__work=self, format='mobi').order_by('-created')
return EbookFile.objects.filter(edition__work=self, format='mobi').exclude(file='').order_by('-created')
def pdffiles(self):
return EbookFile.objects.filter(edition__work=self, format='pdf').order_by('-created')
return EbookFile.objects.filter(edition__work=self, format='pdf').exclude(file='').order_by('-created')
def make_ebooks_from_ebfs(self):
if self.last_campaign().type != THANKS: # just to make sure that ebf's can be unglued by mistake
return
ebfs=EbookFile.objects.filter(edition__work=self).order_by('-created')
ebfs=EbookFile.objects.filter(edition__work=self).exclude(file='').order_by('-created')
done_formats= []
for ebf in ebfs:
if ebf.format not in done_formats:
ebook=Ebook.objects.create(
ebook=Ebook.objects.get_or_create(
edition=ebf.edition,
format=ebf.format,
rights=self.last_campaign().license,
@ -1195,12 +1254,28 @@ class Work(models.Model):
url= ebf.file.url,
)
done_formats.append(ebf.format)
else:
obsolete=Ebook.objects.filter(url= ebf.file.url,)
for eb in obsolete:
eb.deactivate()
return
def remove_old_ebooks(self):
old=Ebook.objects.filter(edition__work=self, active=True).order_by('-created')
done_formats= []
for eb in old:
if eb.format in done_formats:
eb.deactivate()
else:
done_formats.append(eb.format)
null_files=EbookFile.objects.filter(edition__work=self, file='')
for ebf in null_files:
ebf.delete()
@property
def download_count(self):
dlc=0
for ebook in self.ebooks():
for ebook in self.ebooks(all=True):
dlc += ebook.download_count
return dlc
@ -1585,6 +1660,7 @@ class EbookFile(models.Model):
format = models.CharField(max_length=25, choices = FORMAT_CHOICES)
edition = models.ForeignKey('Edition', related_name='ebook_files')
created = models.DateTimeField(auto_now_add=True)
asking = models.BooleanField(default=False)
def check_file(self):
if self.format == 'epub':
@ -1599,6 +1675,7 @@ class Ebook(models.Model):
format = models.CharField(max_length=25, choices = FORMAT_CHOICES)
provider = models.CharField(max_length=255)
download_count = models.IntegerField(default=0)
active = models.BooleanField(default=True)
# use 'PD-US', 'CC BY', 'CC BY-NC-SA', 'CC BY-NC-ND', 'CC BY-NC', 'CC BY-ND', 'CC BY-SA', 'CC0'
rights = models.CharField(max_length=255, null=True, choices = RIGHTS_CHOICES, db_index=True)
@ -1646,6 +1723,10 @@ class Ebook(models.Model):
def __unicode__(self):
return "%s (%s from %s)" % (self.edition.title, self.format, self.provider)
def deactivate(self):
self.active=False
self.save()
class Wishlist(models.Model):
created = models.DateTimeField(auto_now_add=True)

65
core/pdf.py Normal file
View File

@ -0,0 +1,65 @@
"""
Utilities that manipulate pdf files
"""
import requests
from xhtml2pdf import pisa # import python module
from PyPDF2 import PdfFileMerger,PdfFileReader
from StringIO import StringIO
from tempfile import NamedTemporaryFile
from django.template.loader import render_to_string
from regluit import settings
# Utility function
def ask_pdf(context={}):
ask_html = StringIO(unicode(render_to_string('pdf/ask.html', context)))
# open output file for writing (truncated binary)
resultFile = StringIO()
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
src=ask_html, # the HTML to convert
dest=resultFile) # file to recieve result
# True on success and False on errors
assert pisaStatus.err == 0
return resultFile
def pdf_append( file1, file2, file_out ):
merger = PdfFileMerger(strict=False)
merger.append(file1)
merger.append(file2)
merger.write(file_out)
merger.close()
def test_pdf(pdf_file):
temp = None
try:
if isinstance(pdf_file , str):
if pdf_file.startswith('http:') or pdf_file.startswith('https:'):
temp = NamedTemporaryFile(delete=False)
test_file_content = requests.get(pdf_file).content
temp.write(test_file_content)
temp.seek(0)
else:
# hope it's already a file
temp = open(pdf_file, mode='rb')
else:
pdf_file.seek(0)
temp = pdf_file
try:
PdfFileReader(temp)
success = True
except:
success = False
return success
except:
return False
def test_test_pdf(self):
assert(test_pdf(settings.TEST_PDF_URL))
temp = NamedTemporaryFile(delete=False)
test_file_content = requests.get(settings.TEST_PDF_URL).content
temp.write(test_file_content)
assert test_pdf(temp)
temp.close()

View File

@ -28,7 +28,7 @@ from regluit.core import (
)
from regluit.core.models import Campaign, Acq
from regluit.core.signals import deadline_impending
from regluit.core.parameters import RESERVE, REWARDS
from regluit.core.parameters import RESERVE, REWARDS, THANKS
from regluit.utils.localdatetime import now, date_today
@ -127,6 +127,15 @@ def notify_ending_soon():
def watermark_acq(acq):
acq.get_watermarked()
@task
def process_ebfs(campaign):
if campaign.type == THANKS:
if campaign.use_add_ask:
campaign.add_ask_to_ebfs()
else:
campaign.work.make_ebooks_from_ebfs()
campaign.work.remove_old_ebooks()
@task
def refresh_acqs():
in_10_min = now() + timedelta(minutes=10)

View File

@ -66,6 +66,7 @@ from regluit.payment.parameters import PAYMENT_TYPE_AUTHORIZATION
from regluit.utils.localdatetime import now, date_today
from regluit.pyepub import EPUB
from .epub import test_epub
from .pdf import ask_pdf, test_pdf
class BookLoaderTests(TestCase):
def setUp(self):
@ -838,6 +839,7 @@ class MailingListTests(TestCase):
@override_settings(LOCAL_TEST=True)
class EbookFileTests(TestCase):
def test_badepub_errors(self):
textfile = NamedTemporaryFile(delete=False)
textfile.write("bad text file")
@ -904,8 +906,42 @@ class EbookFileTests(TestCase):
c.do_watermark=False
c.save()
url= acq.get_watermarked().download_link_epub
def test_ebookfile_pdf(self):
w = Work.objects.create(title="Work 2")
e = Edition.objects.create(title=w.title,work=w)
u = User.objects.create_user('test2', 'test@example.org', 'testpass')
rh = RightsHolder.objects.create(owner = u, rights_holder_name = 'rights holder name 2')
cl = Claim.objects.create(rights_holder = rh, work = w, user = u, status = 'active')
c = Campaign.objects.create(work = w,
type = parameters.THANKS,
license = 'CC BY-NC',
description = "Please send me money",
)
# download the test epub into a temp file
temp = NamedTemporaryFile(delete=False)
test_file_content = requests.get(settings.TEST_PDF_URL).content
temp.write(test_file_content)
temp.close()
try:
# now we can try putting the test pdf file into Django storage
temp_file = open(temp.name)
dj_file = DjangoFile(temp_file)
ebf = EbookFile( format='pdf', edition=e, file=dj_file)
ebf.save()
temp_file.close()
finally:
# make sure we get rid of temp file
os.remove(temp.name)
#test the ask-appender
c.add_ask_to_ebfs()
asking_pdf = c.work.ebookfiles().filter(asking = True)[0].file.url
assert test_pdf(asking_pdf)
from .signals import handle_transaction_charged
@override_settings(LOCAL_TEST=True)
class LibTests(TestCase):

View File

@ -194,7 +194,7 @@ class EbookFileForm(forms.ModelForm):
class Meta:
model = EbookFile
widgets = { 'edition': forms.HiddenInput}
exclude = { 'created', }
exclude = { 'created', 'asking' }
class EbookForm(forms.ModelForm):
class Meta:
@ -478,7 +478,7 @@ def getManageCampaignForm ( instance, data=None, initial=None, *args, **kwargs )
class Meta:
model = Campaign
fields = 'description', 'details', 'license', 'target', 'deadline', 'paypal_receiver', 'edition', 'email', 'publisher', 'cc_date_initial', "do_watermark"
fields = 'description', 'details', 'license', 'target', 'deadline', 'paypal_receiver', 'edition', 'email', 'publisher', 'cc_date_initial', "do_watermark", "use_add_ask",
widgets = { 'deadline': SelectDateWidget }
def clean_target(self):

View File

@ -26,7 +26,7 @@ $j(document).ready(function() {
{% if work.last_campaign.ask_money %}
<div class="border" style="padding: 10px; min-height: 18em">
<div id="askblock">
<div>Please help us thank the creators for making this book free. The amount is up to you.</div>
<div>Please help us thank the creators for making <a href="{% url work work.id %}">{{ work.title }}</a> free. The amount is up to you.</div>
<form class="askform" method="POST" action="{% url thank work.id %}#">
{% csrf_token %}
{{ form.non_field_errors }}
@ -74,6 +74,9 @@ $j(document).ready(function() {
</div>
</div>
{% endif %}
{% if source %}
{% else %}
<div class="border">
<h2 style="width:60%">Downloads for <I><a href="{% url work work.id %}">{{ work.title }}</a></i></h2>
<div class="sharing ebook_download_container">
@ -402,6 +405,7 @@ $j(document).ready(function() {
</div>
{% else %}
{% endif %}
{% endif %}
</div>
</div>
<script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" ></script>

View File

@ -23,7 +23,9 @@
<h2> Ebook Files for this Edition</h2>
<ul>
{% for ebook_file in edition.ebook_files.all %}
<li><a href="{{ebook_file.file.url}}">{{ebook_file.file}}</a> created {{ebook_file.created}} </li>
{% if ebook_file.file %}
<li><a href="{{ebook_file.file.url}}">{{ebook_file.file}}</a> created {{ebook_file.created}} {% if ebook_file.asking %}(This file has had the campaign 'ask' added.){% endif %}</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}

View File

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>unglue.it
&mdash; Thank the Creators of {{ work.title }}
</title>
<base href="https://{{ site.domain }}" />
<style type="text/css">
.header-text{height:36px;line-height:36px;display:block;text-decoration:none;font-weight:bold;letter-spacing:-0.05em}
.panelborders{border-width:1px 0;border-style:solid none;border-color:#fff}
.roundedspan{border:1px solid #d4d4d4;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;padding:1px;color:#fff;margin:0 8px 0 0;display:inline-block}
.roundedspan>span{padding:7px 7px;min-width:15px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;text-align:center;display:inline-block}
.roundedspan>span .hovertext{display:none}
.roundedspan>span:hover .hovertext{display:inline}
.mediaborder{padding:5px;border:solid 5px #edf3f4}
.actionbuttons{width:auto;height:36px;line-height:36px;background:#8dc63f;-moz-border-radius:32px;-webkit-border-radius:32px;border-radius:32px;color:white;cursor:pointer;font-size:13px;font-weight:bold;padding:0 15px;border:0;margin:5px 0}
.header-text{height:36px;line-height:36px;display:block;text-decoration:none;font-weight:bold;letter-spacing:-0.05em}
.download_container{width:75%;margin:auto}
#lightbox_content a{color:#6994a3}
#lightbox_content .signuptoday a{color:white}
#lightbox_content h2,#lightbox_content h3,#lightbox_content h4{margin-top:15px}
#lightbox_content h2 a{font-size:18.75px}
#lightbox_content .ebook_download a{margin:auto 5px auto 0;font-size:15px}
#lightbox_content .ebook_download img{vertical-align:middle}
#lightbox_content .logo{font-size:15px}
#lightbox_content .logo img{-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;height:50px;width:50px;margin-right:5px}
#lightbox_content .one_click,#lightbox_content .ebook_download_container{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;margin-left:-0.25%;padding:.5%;padding-bottom:15px;margin-bottom:5px;width:74%}
#lightbox_content .one_click h3,#lightbox_content .ebook_download_container h3{margin-top:5px}
#lightbox_content .one_click{border:solid 2px #8dc63f}
#lightbox_content .ebook_download_container{border:solid 2px #d6dde0}
#lightbox_content a.add-wishlist .on-wishlist,#lightbox_content a.success,a.success:hover{text-decoration:none;color:#3d4e53}
#lightbox_content a.success,a.success:hover{cursor:default}
#lightbox_content ul{padding-left:50px}
#lightbox_content ul li{margin-bottom:4px}
.border{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:solid 2px #d6dde0;margin:5px auto;padding-right:5px;padding-left:5px}
.btn_support.kindle{height:40px}
.btn_support.kindle a{width:auto;font-size:15px}
.preview{border:solid 3px #e35351;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;clear:both;padding:5px 10px;font-size:13px;width:90%}
.preview a{color:#8dc63f}
.launch_top{border:solid 3px #e35351;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;clear:both;padding:5px 10px;font-size:13px;width:90%;border-color:#8dc63f;margin:10px auto 0 auto;font-size:15px;line-height:22.5px}
.launch_top a{color:#8dc63f}
.launch_top.pale{border-color:#d6dde0;font-size:13px}
.launch_top.alert{border-color:#e35351;font-size:13px}
.preview_content{border:solid 3px #e35351;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;clear:both;padding:5px 10px;font-size:13px;width:90%;width:80%;margin:10px auto}
.preview_content a{color:#8dc63f}
.utilityheaders{text-transform:uppercase;color:#3d4e53;font-size:15px;display:block}
html,body{height:100%}
body{padding:0 0 20px 0;margin:0;font-size:13px;line-height:16.900000000000002px;font-family:"Lucida Grande","Lucida Sans Unicode","Lucida Sans",Arial,Helvetica,sans-serif;color:#3d4e53}
a{font-weight:bold;font-size:inherit;text-decoration:none;cursor:pointer;color:#6994a3}
a:hover{text-decoration:underline}
h1{font-size:22.5px}
h2{font-size:18.75px}
h3{font-size:17.549999999999997px}
h4{font-size:15px}
img{border:0}
img.user-avatar{float:left;margin-right:10px;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px}
input,textarea,a.fakeinput{border:2px solid #d6dde0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}
input:focus,textarea:focus,a.fakeinput:focus{border:2px solid #8dc63f;outline:0}
a.fakeinput:hover{text-decoration:none}
.js-search input{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}
h2.content-heading{padding:15px;margin:0;font-size:19px;font-weight:normal;color:#3d4e53;float:left;width:50%}
h2.content-heading span{font-style:italic}
h3.jsmod-title{-moz-border-radius:8px 8px 0 0;-webkit-border-radius:8px 8px 0 0;border-radius:8px 8px 0 0;background:#a7c1ca;padding:0;margin:0;height:73px}
h3.jsmod-title span{font-size:19px;font-style:italic;color:#3d4e53;padding:26px 40px 27px 20px;display:block}
input[type="submit"],a.fakeinput{background:#8dc63f;color:white;font-weight:bold;padding:.5em 1em;cursor:pointer}
.js-page-wrap{position:relative;min-height:100%}
.js-main{width:960px;margin:0 auto;clear:both;padding:0}
.bigger{font-size:15px}
ul.menu{list-style:none;padding:0;margin:0}
.p_form .errorlist{-moz-border-radius:16px;-webkit-border-radius:16px;border-radius:16px;border:0;color:#e35351;clear:none;width:100%;height:auto;line-height:16px;padding:0;font-weight:normal;text-align:left;display:inline}
.p_form .errorlist li{display:inline}
.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden}
#locationhash{display:none}
#block-intro-text{padding-right:10px}
#block-intro-text span.def{font-style:italic}
#main-container{margin:15px 0 0 0}
#js-maincol-fr{float:right;width:725px}
div#content-block{overflow:hidden;padding:0 0 0 7px;margin-bottom:20px}
div#content-block.jsmodule{background:0}
.content-block-heading a.block-link{float:right;padding:15px;font-size:13px;color:#3d4e53;text-decoration:underline;font-weight:normal}
div#content-block-content,div#content-block-content-1{width:100%;overflow:hidden;padding-left:10px}
div#content-block-content .cols3 .column,div#content-block-content-1 .cols3 .column{width:33.33%;float:left}
.pagination{width:100%;text-align:center;margin-top:20px;clear:both;border-top:solid #3d4e53 thin;padding-top:7px}
.pagination .endless_page_link{font-size:13px;border:thin #3d4e53 solid;font-weight:normal;margin:5px;padding:1px}
.pagination .endless_page_current{font-size:13px;border:thin #3d4e53 solid;font-weight:normal;margin:5px;padding:1px;background-color:#edf3f4}
a.nounderline{text-decoration:none}
#lightbox_content p,#lightbox_content li{padding:9px 0;font-size:15px;line-height:20px}
#lightbox_content p a,#lightbox_content li a{font-size:15px;line-height:20px}
#lightbox_content p b,#lightbox_content li b{color:#8dc63f}
#lightbox_content p.last,#lightbox_content li.last{border-bottom:solid 2px #d6dde0;margin-bottom:5px}
#lightbox_content .right_border{border-right:solid 1px #d6dde0;float:left;padding:9px}
#lightbox_content .signuptoday{float:right;margin-top:0;clear:none}
#lightbox_content h2+form,#lightbox_content h3+form,#lightbox_content h4+form{margin-top:15px}
#lightbox_content h2,#lightbox_content h3,#lightbox_content h4{margin-bottom:10px}
.nonlightbox .about_page{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:solid 5px #d6dde0;width:75%;margin:10px auto auto auto;padding:9px}
.central{width:480px;margin:0 auto}
.btn_support{margin:10px;width:215px}
.btn_support a,.btn_support form input,.btn_support>span{font-size:22px;border:4px solid #d6dde0;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;display:block;text-align:center;padding-top:14.25px;padding-bottom:14.25px;background-color:#8dc63f;color:white!important}
.btn_support a span,.btn_support form input span,.btn_support>span span{color:white!important;font-weight:bold;padding-left:0;margin-left:0!important;background:0}
.btn_support.create-account span{padding:0;margin:0;background:0}
.btn_support a:hover,.btn_support form input:hover{background-color:#7aae34;text-decoration:none}
.btn_support a{width:207px}
.btn_support form input{width:215px}
.btn_support.modify a,.btn_support.modify form input{background-color:#a7c1ca}
.btn_support.modify a:hover,.btn_support.modify form input:hover{background-color:#91b1bd}
.yes_js{display:none}
.std_form,.std_form input,.std_form select{line-height:30px;font-size:15px}
.contrib_amount{padding:10px;font-size:19px;text-align:center}
#id_preapproval_amount{width:50%;line-height:30px;font-size:15px}
#askblock{float:right;min-width:260px;background:#edf3f4;padding:10px;width:30%}
.rh_ask{font-size:15px;width:65%}
#contribsubmit{text-align:center;font-size:19px;margin:0 0 10px;cursor:pointer}
#anoncontribbox{padding-bottom:10px}
.faq_tldr{font-style:italic;font-size:19px;text-align:center;line-height:24.7px;color:#6994a3;margin-left:2em}
</style>
</head>
<body style="background:white">
<div class="download_container booksection">
<div class="border" style="padding: 10px; min-height: 18em">
<div class="rh_ask" style=" width: initial;">
{{ work.last_campaign.description|safe }}
</div>
{% if campaign.ask_money %}
<div id="askblock" style="float: initial; width: initial;">
<p>You can use <a href="https://{{ site.domain }}">Unglue.it</a> to help to thank the creators for making <i>{{ work.title }}</i> free. The amount is up to you.<br /><br />
<a href="https://{{ site.domain }}{% url thank work.id %}?offer_id={{campaign.individual_offer.id}}&amp;source=pdf">Click here to thank the creators</a></p>
</div>
{% endif %}
</div>
</div>
</body>
</html>

View File

@ -157,7 +157,7 @@ Please fix the following before launching your campaign:
<h3>Uploaded Files</h3>
{% endif %}
{% if campaign.work.epubfiles.0 %}
<p>Active EPUB file: <a href="{{campaign.work.epubfiles.0.file.url}}">{{campaign.work.epubfiles.0.file}}</a> <br />created {{campaign.work.epubfiles.0.created}} for edition <a href="#edition_{{campaign.work.epubfiles.0.edition.id}}">{{campaign.work.epubfiles.0.edition.id}}</a> </p>
<p>Active EPUB file: <a href="{{campaign.work.epubfiles.0.file.url}}">{{campaign.work.epubfiles.0.file}}</a> <br />created {{campaign.work.epubfiles.0.created}} for edition <a href="#edition_{{campaign.work.epubfiles.0.edition.id}}">{{campaign.work.epubfiles.0.edition.id}}</a> {% if campaign.work.epubfiles.0.asking %}(This file has had the campaign 'ask' added.){% endif %}</p>
{% if campaign.work.test_acqs.0 %}
<ul>
<li><a href="{{campaign.work.test_acqs.0.watermarked.download_link_epub}}">Processed epub for testing</a></li>
@ -166,10 +166,10 @@ Please fix the following before launching your campaign:
{% endif %}
{% endif %}
{% if campaign.work.mobifiles.0 %}
<p>Active MOBI file: <a href="{{campaign.work.mobifiles.0.file.url}}">{{campaign.work.mobifiles.0.file}}</a> <br />created {{campaign.work.mobifiles.0.created}} for edition <a href="#edition_{{campaign.work.mobifiles.0.edition.id}}">{{campaign.work.mobifiles.0.edition.id}}</a> </p>
<p>Active MOBI file: <a href="{{campaign.work.mobifiles.0.file.url}}">{{campaign.work.mobifiles.0.file}}</a> <br />created {{campaign.work.mobifiles.0.created}} for edition <a href="#edition_{{campaign.work.mobifiles.0.edition.id}}">{{campaign.work.mobifiles.0.edition.id}}</a> {% if campaign.work.mobifiles.0.asking %}(This file has had the campaign 'ask' added.){% endif %}</p>
{% endif %}
{% if campaign.work.pdffiles.0 %}
<p>Active PDF file: <a href="{{campaign.work.pdffiles.0.file.url}}">{{campaign.work.pdffiles.0.file}}</a> <br />created {{campaign.work.pdffiles.0.created}} for edition <a href="#edition_{{campaign.work.pdffiles.0.edition.id}}">{{campaign.work.pdffiles.0.edition.id}}</a> </p>
<p>Active PDF file: <a href="{{campaign.work.pdffiles.0.file.url}}">{{campaign.work.pdffiles.0.file}}</a> <br />created {{campaign.work.pdffiles.0.created}} for edition <a href="#edition_{{campaign.work.pdffiles.0.edition.id}}">{{campaign.work.pdffiles.0.edition.id}}</a> {% if campaign.work.pdffiles.0.asking %}(This file has had the campaign 'ask' added.){% endif %}</p>
{% endif %}
{% ifnotequal campaign_status 'ACTIVE' %}
{% ifnotequal campaign.type 3 %}
@ -318,6 +318,12 @@ Please fix the following before launching your campaign:
<div style="padding-top:2em;padding-bottom:0.5em">Next, the <b>Ask</b>. A "thank you" form will float right in this area, so don't use wide graphic elements.</div>
{% endifequal %}
{{ form.description.errors }}{{ form.description }}
{% ifequal campaign.type 3 %}
<h3>Enable "Thanks" in your ebook files</h3>
<p> Unglue.it can add your "Ask" along with a link to your book's "thank the creators" page into your ebook files. That way, people who download the book without making a contribution will be reminded that they can do it later.</p>
<div class="std_form">Add your ask to files: {{ form.use_add_ask.errors }}{{ form.use_add_ask }}</div>
{% endifequal %}
<h3>Edition and Rights Details</h3>
<p>This will be displayed on the More... tab for your work. It's the fine print for your campaign. {% ifequal campaign.type 1 %}Make sure to disclose any ways the unglued edition will differ from the existing edition; for example:
<ul class="bullets">

View File

@ -0,0 +1,165 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>unglue.it
&mdash; Thank the Creators of {{ work.title }}
</title>
<base href="https://{{ site.domain }}" />
<style type="text/css">
.header-text{height:36px;line-height:36px;display:block;text-decoration:none;font-weight:bold;letter-spacing:-0.05em}
.panelborders{border-width:1px 0;border-style:solid none;border-color:#fff}
.roundedspan{border:1px solid #d4d4d4;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;padding:1px;color:#fff;margin:0 8px 0 0;display:inline-block}
.roundedspan>span{padding:7px 7px;min-width:15px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;text-align:center;display:inline-block}
.roundedspan>span .hovertext{display:none}
.roundedspan>span:hover .hovertext{display:inline}
.mediaborder{padding:5px;border:solid 5px #edf3f4}
.actionbuttons{width:auto;height:36px;line-height:36px;background:#8dc63f;-moz-border-radius:32px;-webkit-border-radius:32px;border-radius:32px;color:white;cursor:pointer;font-size:13px;font-weight:bold;padding:0 15px;border:0;margin:5px 0}
.header-text{height:36px;line-height:36px;display:block;text-decoration:none;font-weight:bold;letter-spacing:-0.05em}
.download_container{width:75%;margin:auto}
#lightbox_content a{color:#6994a3}
#lightbox_content .signuptoday a{color:white}
#lightbox_content h2,#lightbox_content h3,#lightbox_content h4{margin-top:15px}
#lightbox_content h2 a{font-size:18.75px}
#lightbox_content .ebook_download a{margin:auto 5px auto 0;font-size:15px}
#lightbox_content .ebook_download img{vertical-align:middle}
#lightbox_content .logo{font-size:15px}
#lightbox_content .logo img{-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;height:50px;width:50px;margin-right:5px}
#lightbox_content .one_click,#lightbox_content .ebook_download_container{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;margin-left:-0.25%;padding:.5%;padding-bottom:15px;margin-bottom:5px;width:74%}
#lightbox_content .one_click h3,#lightbox_content .ebook_download_container h3{margin-top:5px}
#lightbox_content .one_click{border:solid 2px #8dc63f}
#lightbox_content .ebook_download_container{border:solid 2px #d6dde0}
#lightbox_content a.add-wishlist .on-wishlist,#lightbox_content a.success,a.success:hover{text-decoration:none;color:#3d4e53}
#lightbox_content a.success,a.success:hover{cursor:default}
#lightbox_content ul{padding-left:50px}
#lightbox_content ul li{margin-bottom:4px}
.border{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:solid 2px #d6dde0;margin:5px auto;padding-right:5px;padding-left:5px}
.btn_support.kindle{height:40px}
.btn_support.kindle a{width:auto;font-size:15px}
.preview{border:solid 3px #e35351;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;clear:both;padding:5px 10px;font-size:13px;width:90%}
.preview a{color:#8dc63f}
.launch_top{border:solid 3px #e35351;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;clear:both;padding:5px 10px;font-size:13px;width:90%;border-color:#8dc63f;margin:10px auto 0 auto;font-size:15px;line-height:22.5px}
.launch_top a{color:#8dc63f}
.launch_top.pale{border-color:#d6dde0;font-size:13px}
.launch_top.alert{border-color:#e35351;font-size:13px}
.preview_content{border:solid 3px #e35351;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;clear:both;padding:5px 10px;font-size:13px;width:90%;width:80%;margin:10px auto}
.preview_content a{color:#8dc63f}
.utilityheaders{text-transform:uppercase;color:#3d4e53;font-size:15px;display:block}
html,body{height:100%}
body{padding:0 0 20px 0;margin:0;font-size:13px;line-height:16.900000000000002px;font-family:"Lucida Grande","Lucida Sans Unicode","Lucida Sans",Arial,Helvetica,sans-serif;color:#3d4e53}
a{font-weight:bold;font-size:inherit;text-decoration:none;cursor:pointer;color:#6994a3}
a:hover{text-decoration:underline}
h1{font-size:22.5px}
h2{font-size:18.75px}
h3{font-size:17.549999999999997px}
h4{font-size:15px}
img{border:0}
img.user-avatar{float:left;margin-right:10px;-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px}
input,textarea,a.fakeinput{border:2px solid #d6dde0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}
input:focus,textarea:focus,a.fakeinput:focus{border:2px solid #8dc63f;outline:0}
a.fakeinput:hover{text-decoration:none}
.js-search input{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}
h2.content-heading{padding:15px;margin:0;font-size:19px;font-weight:normal;color:#3d4e53;float:left;width:50%}
h2.content-heading span{font-style:italic}
h3.jsmod-title{-moz-border-radius:8px 8px 0 0;-webkit-border-radius:8px 8px 0 0;border-radius:8px 8px 0 0;background:#a7c1ca;padding:0;margin:0;height:73px}
h3.jsmod-title span{font-size:19px;font-style:italic;color:#3d4e53;padding:26px 40px 27px 20px;display:block}
input[type="submit"],a.fakeinput{background:#8dc63f;color:white;font-weight:bold;padding:.5em 1em;cursor:pointer}
.js-page-wrap{position:relative;min-height:100%}
.js-main{width:960px;margin:0 auto;clear:both;padding:0}
.bigger{font-size:15px}
ul.menu{list-style:none;padding:0;margin:0}
.p_form .errorlist{-moz-border-radius:16px;-webkit-border-radius:16px;border-radius:16px;border:0;color:#e35351;clear:none;width:100%;height:auto;line-height:16px;padding:0;font-weight:normal;text-align:left;display:inline}
.p_form .errorlist li{display:inline}
.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden}
#locationhash{display:none}
#block-intro-text{padding-right:10px}
#block-intro-text span.def{font-style:italic}
#main-container{margin:15px 0 0 0}
#js-maincol-fr{float:right;width:725px}
div#content-block{overflow:hidden;padding:0 0 0 7px;margin-bottom:20px}
div#content-block.jsmodule{background:0}
.content-block-heading a.block-link{float:right;padding:15px;font-size:13px;color:#3d4e53;text-decoration:underline;font-weight:normal}
div#content-block-content,div#content-block-content-1{width:100%;overflow:hidden;padding-left:10px}
div#content-block-content .cols3 .column,div#content-block-content-1 .cols3 .column{width:33.33%;float:left}
.pagination{width:100%;text-align:center;margin-top:20px;clear:both;border-top:solid #3d4e53 thin;padding-top:7px}
.pagination .endless_page_link{font-size:13px;border:thin #3d4e53 solid;font-weight:normal;margin:5px;padding:1px}
.pagination .endless_page_current{font-size:13px;border:thin #3d4e53 solid;font-weight:normal;margin:5px;padding:1px;background-color:#edf3f4}
a.nounderline{text-decoration:none}
#lightbox_content p,#lightbox_content li{padding:9px 0;font-size:15px;line-height:20px}
#lightbox_content p a,#lightbox_content li a{font-size:15px;line-height:20px}
#lightbox_content p b,#lightbox_content li b{color:#8dc63f}
#lightbox_content p.last,#lightbox_content li.last{border-bottom:solid 2px #d6dde0;margin-bottom:5px}
#lightbox_content .right_border{border-right:solid 1px #d6dde0;float:left;padding:9px}
#lightbox_content .signuptoday{float:right;margin-top:0;clear:none}
#lightbox_content h2+form,#lightbox_content h3+form,#lightbox_content h4+form{margin-top:15px}
#lightbox_content h2,#lightbox_content h3,#lightbox_content h4{margin-bottom:10px}
.nonlightbox .about_page{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:solid 5px #d6dde0;width:75%;margin:10px auto auto auto;padding:9px}
.central{width:480px;margin:0 auto}
.btn_support{margin:10px;width:215px}
.btn_support a,.btn_support form input,.btn_support>span{font-size:22px;border:4px solid #d6dde0;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;display:block;text-align:center;padding-top:14.25px;padding-bottom:14.25px;background-color:#8dc63f;color:white!important}
.btn_support a span,.btn_support form input span,.btn_support>span span{color:white!important;font-weight:bold;padding-left:0;margin-left:0!important;background:0}
.btn_support.create-account span{padding:0;margin:0;background:0}
.btn_support a:hover,.btn_support form input:hover{background-color:#7aae34;text-decoration:none}
.btn_support a{width:207px}
.btn_support form input{width:215px}
.btn_support.modify a,.btn_support.modify form input{background-color:#a7c1ca}
.btn_support.modify a:hover,.btn_support.modify form input:hover{background-color:#91b1bd}
.yes_js{display:none}
.std_form,.std_form input,.std_form select{line-height:30px;font-size:15px}
.contrib_amount{padding:10px;font-size:19px;text-align:center}
#id_preapproval_amount{width:50%;line-height:30px;font-size:15px}
#askblock{float:right;min-width:260px;background:#edf3f4;padding:10px;width:30%}
.rh_ask{font-size:15px;width:65%}
#contribsubmit{text-align:center;font-size:19px;margin:0 0 10px;cursor:pointer}
#anoncontribbox{padding-bottom:10px}
.faq_tldr{font-style:italic;font-size:19px;text-align:center;line-height:24.7px;color:#6994a3;margin-left:2em}
</style>
</head>
<body style="background:white">
<div class="download_container">
<div class="border" style="padding: 10px; min-height: 18em">
<div class="rh_ask" style=" width: initial;">
{{ work.last_campaign.description|safe }}
</div>
{% if campaign.ask_money %}
<div id="askblock" style="float: initial; width: initial;">
<p>You can use <a href="https://{{ site.domain }}">Unglue.it</a> to help to thank the creators for making <i>{{ work.title }}</i> free. The amount is up to you.<br /><br />
<a href="https://{{ site.domain }}{% url thank work.id %}?offer_id={{campaign.individual_offer.id}}&amp;source=pdf">Click here to thank the creators</a></p>
</div>
{% endif %}
</div>
</div>
</body>
</html>

View File

@ -475,6 +475,8 @@ def edition_uploads(request, edition_id):
logger.error(e)
context['upload_error']= e
form.instance.delete()
else:
tasks.process_ebfs.delay(edition.work.last_campaign())
else:
context['upload_error']= form.errors
form = EbookFileForm(initial={'edition':edition,'format':'epub'}, campaign_type=campaign_type)
@ -685,6 +687,7 @@ def manage_campaign(request, id, action='manage'):
campaign.update_left()
if campaign.type is THANKS :
campaign.work.description = form.cleaned_data['work_description']
tasks.process_ebfs.delay(campaign)
campaign.work.save()
alerts.append(_('Campaign data has been saved'))
activetab = '#2'
@ -2827,6 +2830,8 @@ class DownloadView(PurchaseView):
'lib_thanked': self.lib_thanked,
'amount': self.request.session.pop('amount') if self.request.session.has_key('amount') else None,
'testmode': self.request.REQUEST.has_key('testmode'),
'source': self.request.REQUEST.get('source', ''),
})
return context

View File

@ -1,8 +1,8 @@
Django==1.4.5
Fabric==1.4.3
MySQL-python==1.2.3
Pillow==1.7.7
PyPDF2==1.20
Pillow==2.5.3
PyPDF2==1.23
git+git://github.com/urschrei/pyzotero.git@v0.9.51
South==0.7.6
WebOb==1.2.3
@ -13,6 +13,7 @@ billiard==2.7.3.12
boto==2.8.0
#git+ssh://git@github.com/Gluejar/boto.git@2.3.0
celery==3.0.9
# pip installing pillow seems to delete distribute
distribute==0.6.28
django-celery==3.0.9
#django-ckeditor==3.6.2.1
@ -35,6 +36,7 @@ django-storages==1.1.6
django-tastypie==0.9.11
feedparser==5.1.2
freebase==1.0.8
html5lib==1.0b3
httplib2==0.7.5
kombu==2.4.5
lxml==2.3.5
@ -52,12 +54,15 @@ python-openid==2.2.5
pytz==2012d
rdflib==2.4.0
redis==2.6.2
reportlab==3.1.8
requests==0.14.0
selenium==2.40.0
six==1.2.0
six==1.7.3
ssh==1.7.14
stevedore==0.4
stripe==1.9.1
virtualenv==1.4.9
# virtualenv-clone==0.2.4 not sure why I have this in my env
virtualenvwrapper==3.6
wsgiref==0.1.2
xhtml2pdf==0.0.6

View File

@ -398,6 +398,7 @@ MARC_PREF_OPTIONS =(
BOOXTREAM_API_KEY = '7ynRCsx4q21zEY67it7yk8u5rc6EXY'
BOOXTREAM_API_USER = 'ungluetest'
BOOXTREAM_TEST_EPUB_URL = 'https://github.com/Gluejar/open_access_ebooks_ebook/raw/master/download/open_access_ebooks.epub'
TEST_PDF_URL = "https://github.com/Gluejar/flatland/raw/master/downloads/Flatland.pdf"
FILE_UPLOAD_MAX_MEMORY_SIZE = 20971520 #20MB
DROPBOX_KEY = '4efhwty5aph52bd' #for unglue.it, just.unglue.it