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
@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):
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)
# 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()
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
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,
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:
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 and sect[0].text.strip() == 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'):
- # 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')
+ return wl2_to_wl1(self.materialize(publishable=publishable, changes=changes), self.slug)