add command to import legacy lessons
[redakcja.git] / apps / catalogue / models / book.py
index f58fe10..5990428 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()
 
@@ -319,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
 
@@ -388,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,
@@ -408,14 +408,26 @@ class Book(models.Model):
                 parse_dublincore=parse_dublincore,
                 strict=strict)
 
                 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()
         changes = self.get_current_changes()
         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 host:
+            gallery_url = u'%s%s%s%s/' % (host, settings.MEDIA_URL, settings.IMAGE_DIR, self.slug)
+            gallery_dir = os.path.join(settings.MEDIA_ROOT, settings.IMAGE_DIR, self.slug)
+            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:
         # record the publish
         br = BookPublishRecord.objects.create(book=self, user=user)
         for c in changes:
@@ -423,63 +435,4 @@ class Book(models.Model):
         post_publish.send(sender=br)
 
     def wl1_xml(self, publishable=True, changes=None):
         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
-        from librarian import ParseError
-
-        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 ParseError('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 ParseError('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)