add export lesson command
[redakcja.git] / apps / catalogue / models / book.py
index f58fe10..4572655 100755 (executable)
@@ -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:
@@ -430,7 +442,7 @@ class Book(models.Model):
         import os.path
         from django.conf import settings
         from fnpdjango.utils.text.slughifi import slughifi
         import os.path
         from django.conf import settings
         from fnpdjango.utils.text.slughifi import slughifi
-        from librarian import ParseError
+        from librarian import ParseError, DCNS
 
         def _register_function(f):
             """ Register extension function with lxml """
 
         def _register_function(f):
             """ Register extension function with lxml """
@@ -463,7 +475,7 @@ class Book(models.Model):
         i1 = etree.parse(f2)
 
         for sect in i1.findall('//section'):
         i1 = etree.parse(f2)
 
         for sect in i1.findall('//section'):
-            if sect[0].text == u'Przebieg zajęć':
+            if sect[0].text and sect[0].text.strip() == u'Przebieg zajęć':
                 # Prostujemy.
                 first = sect.find('section')
                 subs = first.findall('.//section')
                 # Prostujemy.
                 first = sect.find('section')
                 subs = first.findall('.//section')
@@ -472,14 +484,19 @@ class Book(models.Model):
                 break
         else:
             # print 'BRAK PRZEBIEGU'
                 break
         else:
             # print 'BRAK PRZEBIEGU'
-            raise ParseError('Brak przebiegu')
+            dc_type = i1.findall('//dc:type', namespaces={'dc': DCNS.uri})
+            if dc_type and dc_type[0] in ('course', 'synthetic'):
+                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'):
 
         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):
+            if len(h) == 0:
+                raise ParseError('Pusty element aktywnosc/opis')
+            # FIXME assumption that every lesson has at most 9 parts
+            if not h[0].text or 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')
                 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')