Merge pull request #202 from Gluejar/b2u_fulfillment
B2u file upload, testing and watermarkingpull/1/head
commit
c5048c15b5
|
@ -0,0 +1,74 @@
|
|||
import requests
|
||||
from django.conf import settings
|
||||
from urllib import quote
|
||||
from functools import partial
|
||||
from xml.etree import ElementTree
|
||||
|
||||
|
||||
from . exceptions import BooXtreamError
|
||||
from . models import Boox
|
||||
|
||||
|
||||
class BooXtream(object):
|
||||
""" ``apikey``
|
||||
|
||||
The API key for your BooXtream account, obtained from BooXtream. Defaults to using
|
||||
settings.BOOXTREAM_API_KEY
|
||||
|
||||
``apiuser``
|
||||
|
||||
The username key for your BooXtream account, obtained from BooXtream. Defaults to using
|
||||
settings.BOOXTREAM_API_USER
|
||||
|
||||
|
||||
``timeout``
|
||||
|
||||
passed to requests
|
||||
"""
|
||||
def __init__(self,
|
||||
apikey='', apiuser='',
|
||||
timeout=None,
|
||||
**params):
|
||||
if not apikey:
|
||||
apikey = settings.BOOXTREAM_API_KEY
|
||||
if not apiuser:
|
||||
apiuser = settings.BOOXTREAM_API_USER
|
||||
self.endpoint = 'http://service.booxtream.com/'
|
||||
self.postrequest = partial(requests.post, timeout=timeout, auth=(apiuser,apikey))
|
||||
|
||||
|
||||
def platform(self, epubfile=None, epub=True, kf8mobi=False, **kwargs):
|
||||
""" Make an API request to BooXtream
|
||||
``self.apikey``, ``epubfile`` and the supplied ``kwargs``.
|
||||
Attempts to deserialize the XML response and return the download link.
|
||||
|
||||
Will raise ``BooXtreamError`` if BooXtream returns an exception
|
||||
code.
|
||||
"""
|
||||
url = self.endpoint + 'booxtream.xml'
|
||||
kwargs['epub'] = '1' if epub else '0'
|
||||
kwargs['kf8mobi'] = '1' if kf8mobi else '0'
|
||||
|
||||
files= {'epubfile': epubfile} if epubfile else {}
|
||||
resp = self.postrequest(url, data=kwargs, files=files)
|
||||
doc = ElementTree.fromstring(resp.content)
|
||||
|
||||
# it turns out an Error can have an Error in it
|
||||
errors = doc.findall('.//Response/Error')
|
||||
if len(errors) > 0:
|
||||
raise BooXtreamError(errors)
|
||||
download_link_epub = doc.find('.//DownloadLink[@type="epub"]')
|
||||
if download_link_epub is not None:
|
||||
download_link_epub = download_link_epub.text
|
||||
download_link_mobi = doc.find('.//DownloadLink[@type="mobi"]')
|
||||
if download_link_mobi is not None:
|
||||
download_link_mobi = download_link_mobi.text
|
||||
boox = Boox.objects.create(
|
||||
download_link_epub=download_link_epub,
|
||||
download_link_mobi=download_link_mobi,
|
||||
referenceid= kwargs.get('referenceid'),
|
||||
downloads_remaining= kwargs.get('downloadlimit'),
|
||||
expirydays=kwargs.get('expirydays'),
|
||||
)
|
||||
return boox
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
|
||||
class BooXtreamError(Exception):
|
||||
""" list of errors returned in xml
|
||||
"""
|
||||
def __init__(self, errors):
|
||||
self.errors = errors
|
||||
|
||||
def __str__(self):
|
||||
errormsg='BooXtream errors:'
|
||||
for error in self.errors:
|
||||
errormsg += 'Error %s: %s\n'% (error.find('Code').text,error.find('Msg').text)
|
||||
return errormsg
|
|
@ -0,0 +1,42 @@
|
|||
# -*- 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 model 'Boox'
|
||||
db.create_table('booxtream_boox', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('download_link_epub', self.gf('django.db.models.fields.URLField')(max_length=200, null=True)),
|
||||
('download_link_mobi', self.gf('django.db.models.fields.URLField')(max_length=200, null=True)),
|
||||
('referenceid', self.gf('django.db.models.fields.CharField')(max_length=32)),
|
||||
('downloads_remaining', self.gf('django.db.models.fields.PositiveSmallIntegerField')(default=0)),
|
||||
('expirydays', self.gf('django.db.models.fields.PositiveSmallIntegerField')()),
|
||||
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
))
|
||||
db.send_create_signal('booxtream', ['Boox'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'Boox'
|
||||
db.delete_table('booxtream_boox')
|
||||
|
||||
|
||||
models = {
|
||||
'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'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['booxtream']
|
|
@ -0,0 +1,19 @@
|
|||
from datetime import timedelta, datetime
|
||||
|
||||
from django.db import models
|
||||
|
||||
class Boox(models.Model):
|
||||
"""
|
||||
keeps a record of a file that's been watermarked
|
||||
"""
|
||||
download_link_epub = models.URLField(null=True)
|
||||
download_link_mobi = models.URLField(null=True)
|
||||
referenceid = models.CharField(max_length=32)
|
||||
downloads_remaining = models.PositiveSmallIntegerField(default = 0)
|
||||
expirydays = models.PositiveSmallIntegerField()
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@property
|
||||
def expired(self):
|
||||
return self.created+timedelta(days=self.expirydays) < datetime.now()
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
This is a thin Python (2.6+) wrapper for BooXtream's API for watermarking epub files. It's configured to look for parameters in Django settings files:
|
||||
BOOXTREAM_API_KEY = ''
|
||||
BOOXTREAM_API_USER = ''
|
||||
BOOXTREAM_TEST_EPUB = ''
|
||||
|
||||
http://www.booxtream.com/
|
||||
version 2.52.
|
||||
|
||||
Currently, only the platform method is implemented.
|
||||
|
||||
See Tests for usage
|
||||
|
||||
Eric Hellman August 2013
|
||||
Apache license
|
|
@ -0,0 +1,38 @@
|
|||
import unittest
|
||||
import time
|
||||
|
||||
# uses settings.BOOXTREAM_TEST_EPUB
|
||||
from . import settings
|
||||
|
||||
class TestBooXtream(unittest.TestCase):
|
||||
def _makeOne(self):
|
||||
from . import BooXtream
|
||||
manager = BooXtream()
|
||||
return manager
|
||||
|
||||
def test_booxtream_errors(self):
|
||||
from .exceptions import BooXtreamError
|
||||
inst = self._makeOne()
|
||||
with self.assertRaises(BooXtreamError) as cm:
|
||||
inst.platform()
|
||||
self.assertIn( 'expirydays not set',str(cm.exception))
|
||||
|
||||
|
||||
def test_booxtream_good(self):
|
||||
inst = self._makeOne()
|
||||
params={
|
||||
'customeremailaddress':'jane@example.com',
|
||||
'customername': 'Jane Test',
|
||||
'languagecode':'1043',
|
||||
'expirydays': 1,
|
||||
'downloadlimit': 3,
|
||||
'exlibris':1,
|
||||
'chapterfooter':1,
|
||||
'disclaimer':1,
|
||||
}
|
||||
params['referenceid']= 'order'+str(time.time())
|
||||
epubfile= open(settings.BOOXTREAM_TEST_EPUB)
|
||||
boox=inst.platform(epubfile=epubfile, **params)
|
||||
self.assertRegexpMatches(boox.download_link_epub,'download.booxtream.com/')
|
||||
self.assertFalse(boox.expired)
|
||||
self.assertEqual(boox.downloads_remaining,3)
|
|
@ -0,0 +1,319 @@
|
|||
# -*- 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 'Acq.watermarked'
|
||||
db.add_column('core_acq', 'watermarked',
|
||||
self.gf('django.db.models.fields.related.ForeignKey')(to=orm['booxtream.Boox'], null=True),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting field 'Acq.watermarked'
|
||||
db.delete_column('core_acq', 'watermarked_id')
|
||||
|
||||
|
||||
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', 'blank': 'True'}),
|
||||
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'license': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
|
||||
'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'}),
|
||||
'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', [], {'db_index': 'True'}),
|
||||
'description': ('ckeditor.fields.RichTextField', [], {'null': 'True'}),
|
||||
'details': ('ckeditor.fields.RichTextField', [], {'null': 'True', 'blank': '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'}),
|
||||
'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'}),
|
||||
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
|
||||
'type': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
|
||||
'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(2013, 8, 26, 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': "'pending'", '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', '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'},
|
||||
'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'}),
|
||||
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'publication_date': ('django.db.models.fields.CharField', [], {'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.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'}),
|
||||
'mrc_record': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
|
||||
'xml_record': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
|
||||
},
|
||||
'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', [], {}),
|
||||
'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', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'source': ('django.db.models.fields.CharField', [], {'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', 'blank': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
|
||||
'num_wishes': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True'}),
|
||||
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['core']
|
|
@ -47,7 +47,19 @@ from regluit.payment.parameters import (
|
|||
TRANSACTION_STATUS_FAILED,
|
||||
TRANSACTION_STATUS_INCOMPLETE
|
||||
)
|
||||
from regluit.core.parameters import *
|
||||
|
||||
from regluit.core.parameters import (
|
||||
REWARDS,
|
||||
BUY2UNGLUE,
|
||||
INDIVIDUAL,
|
||||
LIBRARY,
|
||||
BORROWED,
|
||||
TESTING
|
||||
)
|
||||
|
||||
|
||||
from regluit.booxtream import BooXtream
|
||||
watermarker = BooXtream()
|
||||
|
||||
pm = PostMonkey(settings.MAILCHIMP_API_KEY)
|
||||
|
||||
|
@ -226,7 +238,6 @@ class CCLicense():
|
|||
return ''
|
||||
|
||||
|
||||
(INDIVIDUAL, LIBRARY, BORROWED) = (1, 2, 3)
|
||||
class Offer(models.Model):
|
||||
CHOICES = ((INDIVIDUAL,'Individual license'),(LIBRARY,'Library License'))
|
||||
work = models.ForeignKey("Work", related_name="offers", null=False)
|
||||
|
@ -244,13 +255,33 @@ class Acq(models.Model):
|
|||
"""
|
||||
Short for Acquisition, this is a made-up word to describe the thing you acquire when you buy or borrow an ebook
|
||||
"""
|
||||
CHOICES = ((INDIVIDUAL,'Individual license'),(LIBRARY,'Library License'),(BORROWED,'Borrowed from Library'))
|
||||
CHOICES = ((INDIVIDUAL,'Individual license'),(LIBRARY,'Library License'),(BORROWED,'Borrowed from Library'), (TESTING,'Just for Testing'))
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
expires = models.DateTimeField(null=True)
|
||||
work = models.ForeignKey("Work", related_name='acqs', null=False)
|
||||
user = models.ForeignKey(User, related_name='acqs')
|
||||
license = models.PositiveSmallIntegerField(null = False, default = INDIVIDUAL,
|
||||
choices=CHOICES)
|
||||
watermarked = models.ForeignKey("booxtream.Boox", null=True)
|
||||
|
||||
def get_epub_url(self):
|
||||
if self.watermarked == None or self.watermarked.expired:
|
||||
params={
|
||||
'customeremailaddress': self.user.email,
|
||||
'customername': self.user.username,
|
||||
'languagecode':'1043',
|
||||
'expirydays': 1,
|
||||
'downloadlimit': 7,
|
||||
'exlibris':1,
|
||||
'chapterfooter':1,
|
||||
'disclaimer':1,
|
||||
'referenceid': '%s:%s:%s' % (self.work.id, self.user.id, self.id),
|
||||
'kf8mobi': True,
|
||||
'epub': True,
|
||||
}
|
||||
self.watermarked = watermarker.platform(epubfile= self.work.ebookfiles()[0].file, **params)
|
||||
self.save()
|
||||
return self.watermarked.download_link_epub
|
||||
|
||||
class Campaign(models.Model):
|
||||
LICENSE_CHOICES = settings.CCCHOICES
|
||||
|
@ -870,7 +901,7 @@ class Work(models.Model):
|
|||
return Ebook.objects.filter(edition__work=self).order_by('-created')
|
||||
|
||||
def ebookfiles(self):
|
||||
return EbookFile.objects.filter(edition__work=self).order_by('format')
|
||||
return EbookFile.objects.filter(edition__work=self).order_by('-created')
|
||||
|
||||
@property
|
||||
def download_count(self):
|
||||
|
@ -986,7 +1017,7 @@ class Work(models.Model):
|
|||
def purchased_by(self,user):
|
||||
if user==None or not user.is_authenticated():
|
||||
return False
|
||||
acqs= Acq.objects.filter(user=user,work=self)
|
||||
acqs= self.acqs.filter(user=user)
|
||||
if acqs.count()==0:
|
||||
return False
|
||||
for acq in acqs:
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
(REWARDS, BUY2UNGLUE) = (1, 2)
|
||||
(INDIVIDUAL, LIBRARY, BORROWED) = (1, 2, 3)
|
||||
TESTING = 0
|
||||
|
|
|
@ -184,9 +184,11 @@ def handle_transaction_charged(sender,transaction=None, **kwargs):
|
|||
else:
|
||||
# provision the book
|
||||
Acq = get_model('core', 'Acq')
|
||||
Acq.objects.create(user=transaction.user,work=transaction.campaign.work,license= transaction.offer.license)
|
||||
new_acq = Acq.objects.create(user=transaction.user,work=transaction.campaign.work,license= transaction.offer.license)
|
||||
transaction.campaign.update_left()
|
||||
notification.send([transaction.user], "purchase_complete", {'transaction':transaction}, True)
|
||||
from regluit.core.tasks import watermark_acq
|
||||
watermark_acq(new_acq).delay()
|
||||
from regluit.core.tasks import emit_notifications
|
||||
emit_notifications.delay()
|
||||
|
||||
|
|
|
@ -121,5 +121,7 @@ def notify_ending_soon():
|
|||
"""
|
||||
deadline_impending.send(sender=None, campaign=c)
|
||||
|
||||
|
||||
@task
|
||||
def watermark_acq(acq):
|
||||
acq.get_epub_url()
|
||||
|
|
@ -6,8 +6,11 @@ from decimal import Decimal as D
|
|||
from math import factorial
|
||||
from time import sleep, mktime
|
||||
from urlparse import parse_qs, urlparse
|
||||
from tempfile import NamedTemporaryFile
|
||||
from celery.task import chord
|
||||
from celery.task.sets import TaskSet
|
||||
import requests
|
||||
import os
|
||||
|
||||
"""
|
||||
django imports
|
||||
|
@ -17,6 +20,7 @@ from django.contrib.auth.models import User
|
|||
from django.contrib.comments.models import Comment
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core.files import File as DjangoFile
|
||||
from django.db import IntegrityError
|
||||
from django.http import Http404
|
||||
from django.test import TestCase
|
||||
|
@ -49,7 +53,11 @@ from regluit.core.models import (
|
|||
Subject,
|
||||
Publisher,
|
||||
Offer,
|
||||
EbookFile,
|
||||
Acq,
|
||||
)
|
||||
|
||||
from regluit.core.parameters import TESTING
|
||||
from regluit.frontend.views import safe_get_work
|
||||
from regluit.payment.models import Transaction
|
||||
from regluit.payment.parameters import PAYMENT_TYPE_AUTHORIZATION
|
||||
|
@ -812,4 +820,40 @@ class MailingListTests(TestCase):
|
|||
self.user = User.objects.create_user('chimp_test', 'eric@gluejar.com', 'chimp_test')
|
||||
self.assertTrue(self.user.profile.on_ml)
|
||||
|
||||
class EbookFileTests(TestCase):
|
||||
|
||||
def test_ebookfile(self):
|
||||
"""
|
||||
Read the test epub file
|
||||
"""
|
||||
w = Work.objects.create(title="Work 1")
|
||||
e = Edition.objects.create(title=w.title,work=w)
|
||||
u = User.objects.create_user('test', 'test@example.org', 'testpass')
|
||||
|
||||
# download the test epub into a temp file
|
||||
temp = NamedTemporaryFile(delete=False)
|
||||
test_file_content = requests.get(settings.BOOXTREAM_TEST_EPUB_URL).content
|
||||
|
||||
temp.write(test_file_content)
|
||||
temp.close()
|
||||
|
||||
try:
|
||||
# now we can try putting the test epub file into Django storage
|
||||
temp_file = open(temp.name)
|
||||
|
||||
dj_file = DjangoFile(temp_file)
|
||||
ebf = EbookFile( format='epub', edition=e, file=dj_file)
|
||||
ebf.save()
|
||||
|
||||
temp_file.close()
|
||||
finally:
|
||||
# make sure we get rid of temp file
|
||||
os.remove(temp.name)
|
||||
|
||||
|
||||
acq=Acq.objects.create(user=u,work=w,license=TESTING)
|
||||
url= acq.get_epub_url()
|
||||
self.assertRegexpMatches(url,'download.booxtream.com/')
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ from regluit.core.lookups import (
|
|||
EditionLookup
|
||||
)
|
||||
from regluit.utils.localdatetime import now
|
||||
from regluit.utils.fields import EpubFileField
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -135,10 +136,15 @@ class EditionForm(forms.ModelForm):
|
|||
'add_subject': forms.TextInput(attrs={'size': 30}),
|
||||
'unglued': forms.CheckboxInput(),
|
||||
}
|
||||
|
||||
class EbookFileForm(forms.ModelForm):
|
||||
file = EpubFileField(max_length=16777216)
|
||||
def clean_format(self):
|
||||
return 'epub'
|
||||
|
||||
class Meta:
|
||||
model = EbookFile
|
||||
widgets = { 'edition': forms.HiddenInput, }
|
||||
widgets = { 'edition': forms.HiddenInput, 'format': forms.HiddenInput }
|
||||
exclude = { 'created', }
|
||||
|
||||
class EbookForm(forms.ModelForm):
|
||||
|
|
|
@ -20,15 +20,31 @@
|
|||
|
||||
</div>
|
||||
{% if edition.ebook_files.all %}
|
||||
<h2> Ebook Files for this Edition</h2>
|
||||
<ul>
|
||||
{% for ebook_file in edition.ebook_files.all %}
|
||||
<li>{{ebook_file.file}} created {{ebook_file.created}} </li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h2> Ebook Files for this Edition</h2>
|
||||
<ul>
|
||||
{% for ebook_file in edition.ebook_files.all %}
|
||||
<li>{{ebook_file.file}} created {{ebook_file.created}} </li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if uploaded %}
|
||||
<h2> Your file was successfully loaded. </h2>
|
||||
{% if watermarked %}
|
||||
<p> Reference id: <b>{{watermarked.referenceid}}</b></p>
|
||||
<ul>
|
||||
<li><a href="{{watermarked.download_link_epub}}">Watermarked epub for testing</a></li>
|
||||
<li><a href="{{watermarked.download_link_mobi}}">Watermarked mobi for testing</a></li>
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>
|
||||
<span class="yikes">Unfortunately, your file failed testing.</span>
|
||||
The error(s) were: <pre>
|
||||
{{ upload_error }}</pre>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<h2>Upload Ebook files</h2>
|
||||
<p>At this time, we accept only EPUB files for "Buy to Unglue" campaigns. Use the <a href=https://code.google.com/p/epubcheck/">epubcheck</a> tool to make sure everything will work properly.</p>
|
||||
<form method="POST" action="#" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{form.as_p}}
|
||||
|
|
|
@ -54,10 +54,11 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="find-book">
|
||||
<label>Available formats...</label>
|
||||
{% for ebookfile in work.ebookfiles %}
|
||||
<span class="format_display"><img src="/static/images/{{ ebookfile.format }}32.png" height="32" alt="{{ ebookfile.get_format_display }}" title="{{ ebookfile.get_format_display }}" /></span>
|
||||
{% endfor %}
|
||||
<h4>Available formats...</h4>
|
||||
<ul>
|
||||
<li><span class="format_display"><img src="/static/images/mobi32.png" height="32" alt="mobi" title="mobi" /> (for Kindle) </span></li>
|
||||
<li><span class="format_display"><img src="/static/images/epub32.png" height="32" alt="epub" title="epub" /> (for iBooks, Readmill, Nook, Kobo) </span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -134,6 +134,7 @@ from regluit.payment.parameters import (
|
|||
)
|
||||
|
||||
from regluit.utils.localdatetime import now, date_today
|
||||
from regluit.booxtream.exceptions import BooXtreamError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -424,6 +425,7 @@ def work(request, work_id, action='display'):
|
|||
})
|
||||
|
||||
def edition_uploads(request, edition_id):
|
||||
context = {}
|
||||
if not request.user.is_authenticated() :
|
||||
return render(request, "admins_only.html")
|
||||
try:
|
||||
|
@ -437,13 +439,22 @@ def edition_uploads(request, edition_id):
|
|||
form = EbookFileForm(request.POST,request.FILES)
|
||||
if form.is_valid() :
|
||||
form.save()
|
||||
context['uploaded']=True
|
||||
# campaign mangager gets a copy
|
||||
test_acq = models.Acq.objects.create(user=request.user,work=edition.work,license= TESTING)
|
||||
try:
|
||||
test_acq.get_epub_url()
|
||||
context['watermarked']= test_acq.watermarked
|
||||
except (BooXtreamError, ET.ParseError) as e:
|
||||
context['upload_error']= e
|
||||
form.instance.delete()
|
||||
|
||||
else:
|
||||
form = EbookFileForm(initial={'edition':edition})
|
||||
return render(request, 'edition_uploads.html', {
|
||||
form = EbookFileForm(initial={'edition':edition,'format':'epub'})
|
||||
context.update({
|
||||
'form': form, 'edition': edition,
|
||||
'ebook_files': models.EbookFile.objects.filter(edition = edition)
|
||||
})
|
||||
return render(request, 'edition_uploads.html', context )
|
||||
|
||||
|
||||
def new_edition(request, work_id, edition_id, by=None):
|
||||
|
@ -1091,6 +1102,7 @@ class PurchaseView(PledgeView):
|
|||
template_name="purchase.html"
|
||||
form_class = CampaignPurchaseForm
|
||||
action = "purchase"
|
||||
offer_id = None
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(PledgeView, self).get_context_data(**kwargs)
|
||||
|
@ -1100,7 +1112,8 @@ class PurchaseView(PledgeView):
|
|||
'faqmenu': 'purchase' ,
|
||||
'transaction': self.transaction,
|
||||
'tid': self.transaction.id if self.transaction else None,
|
||||
'cover_width': cover_width(self.work)
|
||||
'cover_width': cover_width(self.work),
|
||||
'offer_id':self.offer_id,
|
||||
})
|
||||
|
||||
return context
|
||||
|
@ -1117,10 +1130,9 @@ class PurchaseView(PledgeView):
|
|||
except Exception, e:
|
||||
# this used to raise an exception, but that seemed pointless. This now has the effect of preventing any pledges.
|
||||
return {}
|
||||
|
||||
self.data = {
|
||||
'preapproval_amount':self.get_preapproval_amount(),
|
||||
'anonymous':self.request.user.profile.anon_pref
|
||||
'anonymous':self.request.user.profile.anon_pref,
|
||||
}
|
||||
if self.request.method == 'POST':
|
||||
self.data.update(self.request.POST.dict())
|
||||
|
@ -1131,11 +1143,13 @@ class PurchaseView(PledgeView):
|
|||
return {'initial':self.data}
|
||||
|
||||
def get_preapproval_amount(self):
|
||||
offer_id = self.request.REQUEST.get('offer_id', None)
|
||||
self.offer_id = self.request.REQUEST.get('offer_id', None)
|
||||
if not self.offer_id:
|
||||
self.offer_id = self.work.last_campaign().active_offers()[0].id
|
||||
preapproval_amount = None
|
||||
if offer_id != None:
|
||||
if self.offer_id != None:
|
||||
try:
|
||||
preapproval_amount = D(models.Offer.objects.get(id=offer_id).price)
|
||||
preapproval_amount = D(models.Offer.objects.get(id=self.offer_id).price)
|
||||
except:
|
||||
preapproval_amount = None
|
||||
return preapproval_amount
|
||||
|
|
|
@ -148,6 +148,7 @@ INSTALLED_APPS = (
|
|||
# this must appear *after* django.frontend or else it overrides the
|
||||
# registration templates in frontend/templates/registration
|
||||
'django.contrib.admin',
|
||||
'booxtream',
|
||||
|
||||
)
|
||||
|
||||
|
@ -407,3 +408,7 @@ MARC_CHOICES = (
|
|||
('UNGLUE', 'Unglue.it link'),
|
||||
)
|
||||
|
||||
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'
|
||||
FILE_UPLOAD_MAX_MEMORY_SIZE = 20971520 #20MB
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,14 @@
|
|||
import zipfile
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.template.defaultfilters import filesizeformat
|
||||
|
||||
class EpubFileField(forms.FileField):
|
||||
"""
|
||||
does some epub checking; currently only checks its a zip:
|
||||
"""
|
||||
def clean(self, data, initial=None):
|
||||
data = super(EpubFileField, self).clean(data, initial)
|
||||
if data.name and not zipfile.is_zipfile(data.file):
|
||||
raise forms.ValidationError(_('%s is not a valid EPUB file' % data.name) )
|
||||
return data
|
Loading…
Reference in New Issue