X-Git-Url: https://git.mdrn.pl/redakcja.git/blobdiff_plain/cb3eefff46f3ae0b331f7babbd111a3735e22652..16e6aeef587784cb0c4ff42277657fd34eee7ba6:/src/depot/models.py diff --git a/src/depot/models.py b/src/depot/models.py index c654d1b9..4b5bf654 100644 --- a/src/depot/models.py +++ b/src/depot/models.py @@ -1,11 +1,16 @@ import json import os import tempfile +import traceback import zipfile from datetime import datetime +from django.conf import settings from django.db import models +from django.utils.timezone import now from librarian.cover import make_cover from librarian.builders import EpubBuilder, MobiBuilder +from .publishers.legimi import Legimi +from .publishers.woblink import Woblink class Package(models.Model): @@ -23,25 +28,25 @@ class Package(models.Model): self.set_status(self.get_status()) except: pass - + try: self.set_definition(self.get_definition()) except: pass super().save(*args, **kwargs) - + def get_status(self): return json.loads(self.status_json) def set_status(self, status): - self.status_json = json.dumps(status, indent=4) + self.status_json = json.dumps(status, indent=4, ensure_ascii=False) def get_definition(self): return json.loads(self.definition_json) def set_definition(self, definition): - self.definition_json = json.dumps(definition, indent=4) + self.definition_json = json.dumps(definition, indent=4, ensure_ascii=False) def build(self): f = tempfile.NamedTemporaryFile(prefix='depot-', suffix='.zip', mode='wb', delete=False) @@ -115,3 +120,119 @@ class Package(models.Model): fname, output.get_bytes() ) + + +class ShopBookPublish(models.Model): + book = models.ForeignKey('documents.Book', models.CASCADE) + user = models.ForeignKey(settings.AUTH_USER_MODEL, models.SET_NULL, null=True) + shop = models.ForeignKey('Shop', models.SET_NULL, null=True) + created_at = models.DateTimeField() + started_at = models.DateTimeField(null=True, blank=True) + finished_at = models.DateTimeField(null=True, blank=True) + status = models.PositiveSmallIntegerField(choices=[ + (0, 'queued'), + (10, 'running'), + (100, 'done'), + (110, 'error'), + ], default=0) + error = models.TextField(blank=True) + + @classmethod + def create_for(cls, book, user, shop): + book.assert_publishable() + changes = book.get_current_changes(publishable=True) + me = cls.objects.create(book=book, user=user, shop=shop, created_at=now()) + for change in changes: + me.shopchunkpublish_set.create(change=change) + return me + + def publish(self): + self.status = 10 + self.started_at = now() + self.save(update_fields=['status', 'started_at']) + try: + changes = [ + p.change for p in + self.shopchunkpublish_set.order_by('change__chunk__number') + ] + + self.shop.publish(self.book, changes=changes) + + except Exception: + self.status = 110 + self.error = traceback.format_exc() + else: + self.status = 100 + self.error = '' + self.finished_at = now() + self.save(update_fields=['status', 'finished_at', 'error']) + + +class ShopChunkPublish(models.Model): + book_publish = models.ForeignKey(ShopBookPublish, models.CASCADE) + change = models.ForeignKey('documents.ChunkChange', models.CASCADE) + + +class Shop(models.Model): + name = models.CharField(max_length=255) + shop = models.CharField(max_length=32, choices=[ + ('legimi', 'Legimi'), + ('woblink', 'Woblink'), + ]) + username = models.CharField(max_length=255) + password = models.CharField(max_length=255) + publisher_handle = models.CharField(max_length=255, blank=True) + description_add = models.TextField(blank=True) + + def __str__(self): + return self.shop + + def get_texts(self): + return [t.text for t in self.mediainserttext_set.all()] + + def get_price(self, words, pages): + price_obj = self.pricelevel_set.exclude( + min_pages__gt=pages + ).exclude( + min_words__gt=words + ).order_by('-price').first() + if price_obj is None: + return None + return price_obj.price + + def get_publisher(self): + if self.shop == 'legimi': + pub_class = Legimi + elif self.shop == 'woblink': + pub_class = Woblink + return pub_class(self.username, self.password, self.publisher_handle) + + def publish(self, book, changes): + self.get_publisher().send_book( + self, book, changes=changes, + ) + + def can_publish(self, book): + return self.get_publisher().can_publish(self, book) + + def get_last(self, book): + return self.shopbookpublish_set.filter(book=book).order_by('-created_at').first() + + +class PriceLevel(models.Model): + shop = models.ForeignKey(Shop, models.CASCADE) + min_pages = models.IntegerField(null=True, blank=True) + min_words = models.IntegerField(null=True, blank=True) + price = models.IntegerField() + + class Meta: + ordering = ('price',) + + +class MediaInsertText(models.Model): + shop = models.ForeignKey(Shop, models.CASCADE) + ordering = models.IntegerField() + text = models.TextField() + + class Meta: + ordering = ('ordering',)