add batch publish command
[redakcja.git] / apps / catalogue / models / book.py
index b5a3bf3..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.xml_tools import compile_text, split_xml
+from catalogue.xml_tools import compile_text, split_xml, wl2_to_wl1
 from cover.models import Image
 
 
@@ -92,10 +92,10 @@ class Book(models.Model):
 
     @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[0].commit(text, author=creator)
+        b[0].commit(text, author=creator, **(commit_args or {}))
         return b
 
     def add(self, *args, **kwargs):
@@ -137,7 +137,7 @@ class Book(models.Model):
         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)
@@ -200,10 +200,10 @@ class Book(models.Model):
 
         # 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()
 
@@ -319,14 +319,14 @@ class Book(models.Model):
 
     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:
-                return BookInfo.from_string(book_xml.encode('utf-8'))
+                return BookInfo.from_string(book_xml)
             except (self.NoTextError, ParseError, NoDublinCore, ValidationError):
                 return None
 
@@ -388,7 +388,7 @@ class Book(models.Model):
         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,
@@ -408,14 +408,29 @@ class Book(models.Model):
                 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.
         """
+        import json
+        import os
+        from django.conf import settings
         self.assert_publishable()
         changes = self.get_current_changes()
-        book_xml = self.wl1_xml(changes=changes)
-        apiclient.api_call(user, "lessons/", {"lesson_xml": book_xml})
+        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:
@@ -423,62 +438,4 @@ class Book(models.Model):
         post_publish.send(sender=br)
 
     def wl1_xml(self, publishable=True, changes=None):
-        from lxml import etree
-        import re
-        from StringIO import StringIO
-        from urllib import unquote
-        import os.path
-        from django.conf import settings
-        from fnpdjango.utils.text.slughifi import slughifi
-
-        def _register_function(f):
-            """ Register extension function with lxml """
-            ns = etree.FunctionNamespace('http://wolnelektury.pl/functions')
-            ns[f.__name__] = f
-            return f
-
-        @_register_function
-        def slugify(context, text):
-            """Remove unneeded whitespace from beginning and end"""
-            if isinstance(text, list):
-                text = ''.join(text)
-            return slughifi(text)
-
-        @_register_function
-        def rmext(context, text):
-            if isinstance(text, list):
-                text = ''.join(text)
-            text = unquote(text)
-            if '.' in text:
-                name, ext = text.rsplit('.', 1)
-                if ext.lower() in ('doc', 'docx', 'odt', 'pdf', 'jpg', 'jpeg'):
-                    text = name
-            return text
-
-        t = etree.parse(os.path.join(settings.PROJECT_ROOT, 'xslt/wl2to1.xslt'))
-        ft = self.materialize(publishable=publishable, changes=changes)
-        ft = ft.replace(' ', ' ')
-        f2 = StringIO(ft)
-        i1 = etree.parse(f2)
-
-        for sect in i1.findall('//section'):
-            if sect[0].text == u'Przebieg zajęć':
-                # Prostujemy.
-                first = sect.find('section')
-                subs = first.findall('.//section')
-                for sub in subs:
-                    sect.append(sub)
-                break
-        else:
-            # print 'BRAK PRZEBIEGU'
-            raise ValueError('Brak przebiegu')
-
-        i1.getroot().attrib['redslug'] = self.slug
-        i1.getroot().attrib['wlslug'] = self.slug  # THIS!
-        # print '.',
-        w1t = i1.xslt(t)
-        for h in w1t.findall('//aktywnosc/opis'):
-            if not re.match(r'\d\.\s', h[0].text):
-                raise AssertionError('Niepoprawny nagłówek (aktywnosc/opis): %s' % repr(h[0].text))
-            h[0].text = h[0].text[3:]
-        return etree.tostring(w1t, encoding='utf-8')
+        return wl2_to_wl1(self.materialize(publishable=publishable, changes=changes), self.slug)