X-Git-Url: https://git.mdrn.pl/redakcja.git/blobdiff_plain/1c4c468783e5f380324c29ebc3b2c452da8cc2a0..24ef4f83129e718634e60e53a5c028e9fe3d7446:/apps/catalogue/xml_tools.py diff --git a/apps/catalogue/xml_tools.py b/apps/catalogue/xml_tools.py index 75cb2d8c..abab7f27 100644 --- a/apps/catalogue/xml_tools.py +++ b/apps/catalogue/xml_tools.py @@ -2,6 +2,7 @@ from copy import deepcopy import re +from django.utils.encoding import force_str from lxml import etree from catalogue.constants import TRIM_BEGIN, TRIM_END, MASTERS @@ -135,3 +136,105 @@ def split_xml(text): ch[1] = add_trim_end(ch[1]) return chunks + + +def wl2_to_wl1(wl2_xml, slug): + 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, DCNS + + 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 = wl2_xml.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: + 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'] = slug + i1.getroot().attrib['wlslug'] = slug # THIS! + w1t = i1.xslt(t) + for h in w1t.findall('//aktywnosc/opis'): + 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') + + +EXCEPTIONS = [ + ('div', 'img'), + ('div', 'video'), + ('div', 'table.cell'), +] + + +def remove_element(element): + parent = element.getparent() + tail = element.tail + if tail: + prev = element.getprevious() + if prev is not None: + prev.tail = (prev.tail or '') + tail + else: + parent.text = (parent.text or '') + tail + parent.remove(element) + + +def remove_empty_elements(xml): + try: + tree = etree.fromstring(force_str(xml.replace(' ', u'\xa0'))) + except SyntaxError: + return None + changed = False + another_loop = True + while another_loop: + another_loop = False + for element in tree.findall('.//*'): + if (not element.text or not element.text.strip()) and len(element) == 0: + if (element.tag, element.attrib.get('class')) not in EXCEPTIONS: + remove_element(element) + changed = True + another_loop = True + return etree.tostring(tree, encoding=unicode) if changed else None