add batch publish command
[redakcja.git] / apps / catalogue / models / book.py
index f40a368..d8acd7f 100755 (executable)
@@ -14,7 +14,7 @@ from catalogue.helpers import cached_in_field, GalleryMerger
 from catalogue.models import BookPublishRecord, ChunkPublishRecord, Project
 from catalogue.signals import post_publish
 from catalogue.tasks import refresh_instance, book_content_updated
 from catalogue.models import BookPublishRecord, ChunkPublishRecord, Project
 from catalogue.signals import post_publish
 from catalogue.tasks import refresh_instance, book_content_updated
-from catalogue.xml_tools import compile_text, split_xml
+from catalogue.xml_tools import compile_text, split_xml, wl2_to_wl1
 from cover.models import Image
 
 
 from cover.models import Image
 
 
@@ -92,10 +92,10 @@ class Book(models.Model):
 
     @classmethod
     @transaction.commit_on_success
 
     @classmethod
     @transaction.commit_on_success
-    def create(cls, creator, text, **kwargs):
+    def create(cls, creator, text, commit_args=None, **kwargs):
         b = cls.objects.create(**kwargs)
         b.chunk_set.all().update(creator=creator)
         b = cls.objects.create(**kwargs)
         b.chunk_set.all().update(creator=creator)
-        b[0].commit(text, author=creator)
+        b[0].commit(text, author=creator, **(commit_args or {}))
         return b
 
     def add(self, *args, **kwargs):
         return b
 
     def add(self, *args, **kwargs):
@@ -137,7 +137,7 @@ class Book(models.Model):
         return instance
 
     def make_chunk_slug(self, proposed):
         return instance
 
     def make_chunk_slug(self, proposed):
-        """ 
+        """
             Finds a chunk slug not yet used in the book.
         """
         slugs = set(c.slug for c in self)
             Finds a chunk slug not yet used in the book.
         """
         slugs = set(c.slug for c in self)
@@ -200,10 +200,10 @@ class Book(models.Model):
 
         # and move the gallery starts
         if gm.was_merged:
 
         # and move the gallery starts
         if gm.was_merged:
-                for chunk in self[len(self) - len_other:]:
-                        old_start = chunk.gallery_start or 1
-                        chunk.gallery_start = old_start + gm.dest_size - gm.num_deleted
-                        chunk.save()
+            for chunk in self[len(self) - len_other:]:
+                old_start = chunk.gallery_start or 1
+                chunk.gallery_start = old_start + gm.dest_size - gm.num_deleted
+                chunk.save()
 
         other.delete()
 
 
         other.delete()
 
@@ -246,7 +246,7 @@ class Book(models.Model):
     def assert_publishable(self):
         assert self.chunk_set.exists(), _('No chunks in the book.')
         try:
     def assert_publishable(self):
         assert self.chunk_set.exists(), _('No chunks in the book.')
         try:
-            changes = self.get_current_changes(publishable=True)
+            changes = self.get_current_changes()
         except self.NoTextError:
             raise AssertionError(_('Not all chunks have publishable revisions.'))
 
         except self.NoTextError:
             raise AssertionError(_('Not all chunks have publishable revisions.'))
 
@@ -254,6 +254,10 @@ class Book(models.Model):
 
         try:
             bi = self.wldocument(changes=changes, strict=True).book_info
 
         try:
             bi = self.wldocument(changes=changes, strict=True).book_info
+            if not bi.audience:
+                raise ValidationError('No audience specified')
+            if not bi.type:
+                raise ValidationError('No type specified')
         except ParseError, e:
             raise AssertionError(_('Invalid XML') + ': ' + unicode(e))
         except NoDublinCore:
         except ParseError, e:
             raise AssertionError(_('Invalid XML') + ': ' + unicode(e))
         except NoDublinCore:
@@ -315,14 +319,14 @@ class Book(models.Model):
 
     def book_info(self, publishable=True):
         try:
 
     def book_info(self, publishable=True):
         try:
-            book_xml = self.materialize(publishable=publishable)
+            book_xml = self.wl1_xml(publishable=publishable)
         except self.NoTextError:
             pass
         else:
             from librarian.dcparser import BookInfo
             from librarian import NoDublinCore, ParseError, ValidationError
             try:
         except self.NoTextError:
             pass
         else:
             from librarian.dcparser import BookInfo
             from librarian import NoDublinCore, ParseError, ValidationError
             try:
-                return BookInfo.from_string(book_xml.encode('utf-8'))
+                return BookInfo.from_string(book_xml)
             except (self.NoTextError, ParseError, NoDublinCore, ValidationError):
                 return None
 
             except (self.NoTextError, ParseError, NoDublinCore, ValidationError):
                 return None
 
@@ -384,7 +388,7 @@ class Book(models.Model):
         return changes
 
     def materialize(self, publishable=False, changes=None):
         return changes
 
     def materialize(self, publishable=False, changes=None):
-        """ 
+        """
             Get full text of the document compiled from chunks.
             Takes the current versions of all texts
             or versions most recently tagged for publishing,
             Get full text of the document compiled from chunks.
             Takes the current versions of all texts
             or versions most recently tagged for publishing,
@@ -399,21 +403,39 @@ class Book(models.Model):
         from librarian.parser import WLDocument
 
         return WLDocument.from_string(
         from librarian.parser import WLDocument
 
         return WLDocument.from_string(
-                self.materialize(publishable=publishable, changes=changes),
+                self.wl1_xml(publishable=publishable, changes=changes),
                 provider=RedakcjaDocProvider(publishable=publishable),
                 parse_dublincore=parse_dublincore,
                 strict=strict)
 
                 provider=RedakcjaDocProvider(publishable=publishable),
                 parse_dublincore=parse_dublincore,
                 strict=strict)
 
-    def publish(self, user):
+    def publish(self, user, host=None):
         """
             Publishes a book on behalf of a (local) user.
         """
         """
             Publishes a book on behalf of a (local) user.
         """
+        import json
+        import os
+        from django.conf import settings
         self.assert_publishable()
         self.assert_publishable()
-        changes = self.get_current_changes(publishable=True)
-        book_xml = self.materialize(changes=changes)
-        apiclient.api_call(user, "books/", {"book_xml": book_xml})
+        changes = self.get_current_changes()
+        data = {"lesson_xml": self.wl1_xml(changes=changes)}
+
+        if not host:
+            host = 'https://' + Site.objects.get_current().domain
+        gallery_url = u'%s%s%s%s/' % (host, settings.MEDIA_URL, settings.IMAGE_DIR, self.gallery)
+        gallery_dir = os.path.join(settings.MEDIA_ROOT, settings.IMAGE_DIR, self.gallery)
+        if os.path.isdir(gallery_dir):
+            data['gallery_url'] = gallery_url
+            attachments = os.listdir(gallery_dir)
+        else:
+            attachments = []
+        data['attachments'] = json.dumps(attachments)
+
+        apiclient.api_call(user, "lessons/", data)
         # record the publish
         br = BookPublishRecord.objects.create(book=self, user=user)
         for c in changes:
             ChunkPublishRecord.objects.create(book_record=br, change=c)
         post_publish.send(sender=br)
         # record the publish
         br = BookPublishRecord.objects.create(book=self, user=user)
         for c in changes:
             ChunkPublishRecord.objects.create(book_record=br, change=c)
         post_publish.send(sender=br)
+
+    def wl1_xml(self, publishable=True, changes=None):
+        return wl2_to_wl1(self.materialize(publishable=publishable, changes=changes), self.slug)