70 lines
2.7 KiB
Python
70 lines
2.7 KiB
Python
import logging
|
|
import requests
|
|
from ftplib import FTP, FTP_TLS
|
|
from StringIO import StringIO
|
|
from django.db import models
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class Target(models.Model):
|
|
name = models.CharField(max_length=30)
|
|
host = models.CharField(max_length=60)
|
|
pw = models.CharField(max_length=30)
|
|
user = models.CharField(max_length=30)
|
|
protocol = models.CharField(max_length=10, default='ftp')
|
|
formats = models.ManyToManyField('Format', related_name='targets')
|
|
|
|
def __unicode__(self):
|
|
return self.name
|
|
|
|
def get_ftp(self):
|
|
if self.protocol == 'secure':
|
|
_ftp = FTP_TLS(self.host, self.user, self.pw)
|
|
_ftp.prot_p()
|
|
else:
|
|
_ftp = FTP(self.host, self.user, self.pw)
|
|
return _ftp
|
|
|
|
def push(self, book, new=False):
|
|
pushed_formats = []
|
|
pushed_isbns = set()
|
|
for ebook in book.ebooks():
|
|
isbn = ebook.edition.isbn_13 if ebook.edition.isbn_13 else book.first_isbn_13()
|
|
if isbn and self.formats.filter(name=ebook.format).exists() and ebook.format not in pushed_formats:
|
|
dont_push = new and Deposit.objects.filter(isbn=isbn, target=self, format=ebook.format).exists()
|
|
if not dont_push:
|
|
ebfile = ebook.get_archive()
|
|
if ebfile:
|
|
self.push_file(u'{}.{}'.format(isbn,ebook.format), ebfile)
|
|
ebfile.close()
|
|
pushed_formats.append(ebook.format)
|
|
pushed_isbns.add(isbn)
|
|
Deposit.objects.create(target=self, isbn=isbn, format=ebook.format)
|
|
else:
|
|
logger.error('no file available for ebook {}'.format(ebook.id))
|
|
if pushed_isbns:
|
|
cover = book.cover_image_large()
|
|
if cover:
|
|
r = requests.get(cover)
|
|
for isbn in pushed_isbns:
|
|
self.push_file(u'{}.{}'.format(isbn,'jpg'), StringIO(r.content))
|
|
else:
|
|
logger.error('no cover available for {}'.format(book))
|
|
return pushed_isbns
|
|
|
|
def push_file(self, filename, file_to_push):
|
|
self.get_ftp().storbinary(u'STOR {}'.format(filename), file_to_push)
|
|
|
|
|
|
class Deposit(models.Model):
|
|
target = models.ForeignKey(Target, on_delete=models.CASCADE, related_name="deposits")
|
|
isbn = models.CharField(max_length=13)
|
|
format = models.CharField(max_length=30)
|
|
updated = models.DateTimeField(auto_now_add=True)
|
|
|
|
class Format(models.Model):
|
|
name = models.CharField(max_length=4)
|
|
|
|
def __unicode__(self):
|
|
return self.name
|