style
authorJan Szejko <jan.szejko@gmail.com>
Fri, 1 Jul 2016 12:26:00 +0000 (14:26 +0200)
committerJan Szejko <jan.szejko@gmail.com>
Fri, 1 Jul 2016 12:26:00 +0000 (14:26 +0200)
28 files changed:
librarian/__init__.py
librarian/book2anything.py
librarian/cover.py
librarian/dcparser.py
librarian/epub.py
librarian/fb2.py
librarian/functions.py
librarian/html.py
librarian/mobi.py
librarian/packagers.py
librarian/parser.py
librarian/pdf.py
librarian/picture.py
librarian/pyhtml.py
librarian/pypdf.py
librarian/styles/wolnelektury/cover.py
librarian/styles/wolnelektury/pdf.py [deleted file]
librarian/text.py
librarian/xmlutils.py
setup.py
tests/test_dcparser.py
tests/test_epub.py
tests/test_html.py
tests/test_iofile.py
tests/test_pdf.py
tests/test_picture.py
tests/test_pyhtml.py
tests/utils.py

index 23244ef..5c145d3 100644 (file)
@@ -9,6 +9,7 @@ import os
 import re
 import shutil
 import urllib
 import re
 import shutil
 import urllib
+import lxml.etree as etree
 
 
 class UnicodeException(Exception):
 
 
 class UnicodeException(Exception):
@@ -25,22 +26,27 @@ class UnicodeException(Exception):
             message = unicode(args, encoding='utf-8', errors='ignore')
         return message
 
             message = unicode(args, encoding='utf-8', errors='ignore')
         return message
 
+
 class ParseError(UnicodeException):
     pass
 
 class ParseError(UnicodeException):
     pass
 
+
 class ValidationError(UnicodeException):
     pass
 
 class ValidationError(UnicodeException):
     pass
 
+
 class NoDublinCore(ValidationError):
     """There's no DublinCore section, and it's required."""
     pass
 
 class NoDublinCore(ValidationError):
     """There's no DublinCore section, and it's required."""
     pass
 
+
 class NoProvider(UnicodeException):
     """There's no DocProvider specified, and it's needed."""
     pass
 
 class NoProvider(UnicodeException):
     """There's no DocProvider specified, and it's needed."""
     pass
 
+
 class XMLNamespace(object):
 class XMLNamespace(object):
-    '''A handy structure to repsent names in an XML namespace.'''
+    """A handy structure to repsent names in an XML namespace."""
 
     def __init__(self, uri):
         self.uri = uri
 
     def __init__(self, uri):
         self.uri = uri
@@ -57,6 +63,7 @@ class XMLNamespace(object):
     def __str__(self):
         return '%s' % self.uri
 
     def __str__(self):
         return '%s' % self.uri
 
+
 class EmptyNamespace(XMLNamespace):
     def __init__(self):
         super(EmptyNamespace, self).__init__('')
 class EmptyNamespace(XMLNamespace):
     def __init__(self):
         super(EmptyNamespace, self).__init__('')
@@ -80,8 +87,9 @@ class WLURI(object):
     slug = None
 
     example = 'http://edukacjamedialna.edu.pl/lekcje/template'
     slug = None
 
     example = 'http://edukacjamedialna.edu.pl/lekcje/template'
-    _re_wl_uri = re.compile(r'http://(www\.)?edukacjamedialna.edu.pl/lekcje/'
-            '(?P<slug>[-a-z0-9]+)/?$')
+    _re_wl_uri = re.compile(
+        r'http://(www\.)?edukacjamedialna.edu.pl/lekcje/'
+        '(?P<slug>[-a-z0-9]+)/?$')
 
     def __init__(self, uri):
         uri = unicode(uri)
 
     def __init__(self, uri):
         uri = unicode(uri)
@@ -148,43 +156,46 @@ class DirDocProvider(DocProvider):
         return IOFile.from_filename(os.path.join(self.dir, fname))
 
 
         return IOFile.from_filename(os.path.join(self.dir, fname))
 
 
-import lxml.etree as etree
-import dcparser
-
-DEFAULT_BOOKINFO = dcparser.BookInfo(
-        { RDFNS('about'): u'http://wiki.wolnepodreczniki.pl/Lektury:Template'},
-        { 
-          DCNS('creator.expert'): [u'Some, Author'],
-          DCNS('creator.scenario'): [u'Some, Author'],
-          DCNS('creator.textbook'): [u'Some, Author'],
-          DCNS('title'): [u'Some Title'],
-          DCNS('subject.period'): [u'Unknown'],
-          DCNS('subject.type'): [u'Unknown'],
-          DCNS('subject.genre'): [u'Unknown'],
-          DCNS('date'): ['1970-01-01'],
-          DCNS('language'): [u'pol'],
-          # DCNS('date'): [creation_date],
-          DCNS('publisher'): [u"Fundacja Nowoczesna Polska"],
-          DCNS('description'):
-          [u"""Publikacja zrealizowana w ramach projektu
-             Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa
-             wykonana przez Bibliotekę Narodową z egzemplarza
-             pochodzącego ze zbiorów BN."""],
-          DCNS('identifier.url'): [WLURI.example],
-          DCNS('rights'):
-            [u"Domena publiczna - zm. [OPIS STANU PRAWNEGO TEKSTU]"] })
+def get_default_bookinfo():
+    import dcparser
+    dcparser.BookInfo(
+        {RDFNS('about'): u'http://wiki.wolnepodreczniki.pl/Lektury:Template'},
+        {
+            DCNS('creator.expert'): [u'Some, Author'],
+            DCNS('creator.scenario'): [u'Some, Author'],
+            DCNS('creator.textbook'): [u'Some, Author'],
+            DCNS('title'): [u'Some Title'],
+            DCNS('subject.period'): [u'Unknown'],
+            DCNS('subject.type'): [u'Unknown'],
+            DCNS('subject.genre'): [u'Unknown'],
+            DCNS('date'): ['1970-01-01'],
+            DCNS('language'): [u'pol'],
+            # DCNS('date'): [creation_date],
+            DCNS('publisher'): [u"Fundacja Nowoczesna Polska"],
+            DCNS('description'):
+                [u"""Publikacja zrealizowana w ramach projektu
+                 Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa
+                 wykonana przez Bibliotekę Narodową z egzemplarza
+                 pochodzącego ze zbiorów BN."""],
+            DCNS('identifier.url'): [WLURI.example],
+            DCNS('rights'):
+                [u"Domena publiczna - zm. [OPIS STANU PRAWNEGO TEKSTU]"],
+        })
+
+DEFAULT_BOOKINFO = get_default_bookinfo()
+
 
 def xinclude_forURI(uri):
     e = etree.Element(XINS("include"))
     e.set("href", uri)
     return etree.tostring(e, encoding=unicode)
 
 
 def xinclude_forURI(uri):
     e = etree.Element(XINS("include"))
     e.set("href", uri)
     return etree.tostring(e, encoding=unicode)
 
+
 def wrap_text(ocrtext, creation_date, bookinfo=DEFAULT_BOOKINFO):
     """Wrap the text within the minimal XML structure with a DC template."""
     bookinfo.created_at = creation_date
 
 def wrap_text(ocrtext, creation_date, bookinfo=DEFAULT_BOOKINFO):
     """Wrap the text within the minimal XML structure with a DC template."""
     bookinfo.created_at = creation_date
 
-    dcstring = etree.tostring(bookinfo.to_etree(), \
-        method='xml', encoding=unicode, pretty_print=True)
+    dcstring = etree.tostring(bookinfo.to_etree(), encoding=unicode, pretty_print=True)
 
     return u'<utwor>\n' + dcstring + u'\n<plain-text>\n' + ocrtext + \
         u'\n</plain-text>\n</utwor>'
 
     return u'<utwor>\n' + dcstring + u'\n<plain-text>\n' + ocrtext + \
         u'\n</plain-text>\n</utwor>'
@@ -194,8 +205,7 @@ def serialize_raw(element):
     b = u'' + (element.text or '')
 
     for child in element.iterchildren():
     b = u'' + (element.text or '')
 
     for child in element.iterchildren():
-        e = etree.tostring(child, method='xml', encoding=unicode,
-                pretty_print=True)
+        e = etree.tostring(child, encoding=unicode, pretty_print=True)
         b += e
 
     return b
         b += e
 
     return b
@@ -204,9 +214,11 @@ SERIALIZERS = {
     'raw': serialize_raw,
 }
 
     'raw': serialize_raw,
 }
 
+
 def serialize_children(element, format='raw'):
     return SERIALIZERS[format](element)
 
 def serialize_children(element, format='raw'):
     return SERIALIZERS[format](element)
 
+
 def get_resource(path):
     return os.path.join(os.path.dirname(__file__), path)
 
 def get_resource(path):
     return os.path.join(os.path.dirname(__file__), path)
 
index b60cd0f..c8726c6 100644 (file)
@@ -4,7 +4,6 @@
 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from collections import namedtuple
 import os.path
 import optparse
 
 import os.path
 import optparse
 
@@ -30,19 +29,18 @@ class Option(object):
 
 class Book2Anything(object):
     """A class for creating book2... scripts.
 
 class Book2Anything(object):
     """A class for creating book2... scripts.
-    
+
     Subclass it for any format you want to convert to.
     """
     Subclass it for any format you want to convert to.
     """
-    format_name = None # Set format name, like "PDF".
-    ext = None # Set file extension, like "pdf".
-    uses_cover = False # Can it add a cover?
-    cover_optional = True # Only relevant if uses_cover
-    uses_provider = False # Does it need a DocProvider?
-    transform = None # Transform method. Uses WLDocument.as_{ext} by default.
-    parser_options = [] # List of Option objects for additional parser args.
-    transform_options = [] # List of Option objects for additional transform args.
-    transform_flags = [] # List of Option objects for supported transform flags.
-
+    format_name = None  # Set format name, like "PDF".
+    ext = None  # Set file extension, like "pdf".
+    uses_cover = False  # Can it add a cover?
+    cover_optional = True  # Only relevant if uses_cover
+    uses_provider = False  # Does it need a DocProvider?
+    transform = None  # Transform method. Uses WLDocument.as_{ext} by default.
+    parser_options = []  # List of Option objects for additional parser args.
+    transform_options = []  # List of Option objects for additional transform args.
+    transform_flags = []  # List of Option objects for supported transform flags.
 
     @classmethod
     def run(cls):
 
     @classmethod
     def run(cls):
@@ -52,27 +50,33 @@ class Book2Anything(object):
 
         parser = optparse.OptionParser(usage=usage)
 
 
         parser = optparse.OptionParser(usage=usage)
 
-        parser.add_option('-v', '--verbose', 
-                action='store_true', dest='verbose', default=False,
-                help='print status messages to stdout')
-        parser.add_option('-d', '--make-dir',
-                action='store_true', dest='make_dir', default=False,
-                help='create a directory for author and put the output file in it')
-        parser.add_option('-o', '--output-file',
-                dest='output_file', metavar='FILE',
-                help='specifies the output file')
-        parser.add_option('-O', '--output-dir',
-                dest='output_dir', metavar='DIR',
-                help='specifies the directory for output')
+        parser.add_option(
+            '-v', '--verbose',
+            action='store_true', dest='verbose', default=False,
+            help='print status messages to stdout')
+        parser.add_option(
+            '-d', '--make-dir',
+            action='store_true', dest='make_dir', default=False,
+            help='create a directory for author and put the output file in it')
+        parser.add_option(
+            '-o', '--output-file',
+            dest='output_file', metavar='FILE',
+            help='specifies the output file')
+        parser.add_option(
+            '-O', '--output-dir',
+            dest='output_dir', metavar='DIR',
+            help='specifies the directory for output')
         if cls.uses_cover:
             if cls.cover_optional:
         if cls.uses_cover:
             if cls.cover_optional:
-                parser.add_option('-c', '--with-cover', 
-                        action='store_true', dest='with_cover', default=False,
-                        help='create default cover')
-            parser.add_option('-C', '--image-cache',
-                    dest='image_cache', metavar='URL',
-                    help='prefix for image download cache' +
-                        (' (implies --with-cover)' if cls.cover_optional else ''))
+                parser.add_option(
+                    '-c', '--with-cover',
+                    action='store_true', dest='with_cover', default=False,
+                    help='create default cover')
+            parser.add_option(
+                '-C', '--image-cache',
+                dest='image_cache', metavar='URL',
+                help='prefix for image download cache' +
+                     (' (implies --with-cover)' if cls.cover_optional else ''))
         for option in cls.parser_options + cls.transform_options + cls.transform_flags:
             option.add(parser)
 
         for option in cls.parser_options + cls.transform_options + cls.transform_flags:
             option.add(parser)
 
@@ -80,7 +84,7 @@ class Book2Anything(object):
 
         if len(input_filenames) < 1:
             parser.print_help()
 
         if len(input_filenames) < 1:
             parser.print_help()
-            return(1)
+            return 1
 
         # Prepare additional args for parser.
         parser_args = {}
 
         # Prepare additional args for parser.
         parser_args = {}
@@ -91,8 +95,7 @@ class Book2Anything(object):
         for option in cls.transform_options:
             transform_args[option.name()] = option.value(options)
         # Add flags to transform_args, if any.
         for option in cls.transform_options:
             transform_args[option.name()] = option.value(options)
         # Add flags to transform_args, if any.
-        transform_flags = [flag.name() for flag in cls.transform_flags
-                    if flag.value(options)]
+        transform_flags = [flag.name() for flag in cls.transform_flags if flag.value(options)]
         if transform_flags:
             transform_args['flags'] = transform_flags
         # Add cover support, if any.
         if transform_flags:
             transform_args['flags'] = transform_flags
         # Add cover support, if any.
@@ -105,35 +108,35 @@ class Book2Anything(object):
             elif not cls.cover_optional or options.with_cover:
                 transform_args['cover'] = WLCover
 
             elif not cls.cover_optional or options.with_cover:
                 transform_args['cover'] = WLCover
 
-
         # Do some real work
         # Do some real work
+        main_input = None
         try:
             for main_input in input_filenames:
                 if options.verbose:
                     print main_input
 
         try:
             for main_input in input_filenames:
                 if options.verbose:
                     print main_input
 
-            # Where to find input?
-            if cls.uses_provider:
-                path, fname = os.path.realpath(main_input).rsplit('/', 1)
-                provider = DirDocProvider(path)
-            else:
-                provider = None
-
-            # Where to write output?
-            if not (options.output_file or options.output_dir):
-                output_file = os.path.splitext(main_input)[0] + '.' + cls.ext
-            else:
-                output_file = None
-
-            # Do the transformation.
-            doc = WLDocument.from_file(main_input, provider=provider, **parser_args)
-            transform = cls.transform
-            if transform is None:
-                transform = getattr(WLDocument, 'as_%s' % cls.ext)
-            output = transform(doc, **transform_args)
-
-            doc.save_output_file(output,
-                output_file, options.output_dir, options.make_dir, cls.ext)
+                # Where to find input?
+                if cls.uses_provider:
+                    path, fname = os.path.realpath(main_input).rsplit('/', 1)
+                    provider = DirDocProvider(path)
+                else:
+                    provider = None
+
+                # Where to write output?
+                if not (options.output_file or options.output_dir):
+                    output_file = os.path.splitext(main_input)[0] + '.' + cls.ext
+                else:
+                    output_file = None
+
+                # Do the transformation.
+                doc = WLDocument.from_file(main_input, provider=provider, **parser_args)
+                transform = cls.transform
+                if transform is None:
+                    transform = getattr(WLDocument, 'as_%s' % cls.ext)
+                output = transform(doc, **transform_args)
+
+                doc.save_output_file(
+                    output, output_file, options.output_dir, options.make_dir, cls.ext)
 
         except ParseError, e:
             print '%(file)s:%(name)s:%(message)s' % {
 
         except ParseError, e:
             print '%(file)s:%(name)s:%(message)s' % {
index dc64a9c..2320f19 100644 (file)
@@ -113,12 +113,12 @@ class Cover(object):
     exts = {
         'JPEG': 'jpg',
         'PNG': 'png',
     exts = {
         'JPEG': 'jpg',
         'PNG': 'png',
-        }
+    }
 
     mime_types = {
         'JPEG': 'image/jpeg',
         'PNG': 'image/png',
 
     mime_types = {
         'JPEG': 'image/jpeg',
         'PNG': 'image/png',
-        }
+    }
 
     def __init__(self, book_info, format=None):
         try:
 
     def __init__(self, book_info, format=None):
         try:
@@ -154,24 +154,22 @@ class Cover(object):
         top = self.author_top
         tbox = TextBox(
             self.width - self.author_margin_left - self.author_margin_right,
         top = self.author_top
         tbox = TextBox(
             self.width - self.author_margin_left - self.author_margin_right,
-            self.height - top,
-            )
+            self.height - top)
         author_font = self.author_font or ImageFont.truetype(
             get_resource('fonts/DejaVuSerif.ttf'), 30)
         tbox.text(self.pretty_author(), self.author_color, author_font,
         author_font = self.author_font or ImageFont.truetype(
             get_resource('fonts/DejaVuSerif.ttf'), 30)
         tbox.text(self.pretty_author(), self.author_color, author_font,
-            self.author_lineskip, self.author_shadow)
+                  self.author_lineskip, self.author_shadow)
         text_img = tbox.image()
         img.paste(text_img, (self.author_margin_left, top), text_img)
 
         top += text_img.size[1] + self.title_top
         tbox = TextBox(
             self.width - self.title_margin_left - self.title_margin_right,
         text_img = tbox.image()
         img.paste(text_img, (self.author_margin_left, top), text_img)
 
         top += text_img.size[1] + self.title_top
         tbox = TextBox(
             self.width - self.title_margin_left - self.title_margin_right,
-            self.height - top,
-            )
+            self.height - top)
         title_font = self.author_font or ImageFont.truetype(
             get_resource('fonts/DejaVuSerif.ttf'), 40)
         tbox.text(self.pretty_title(), self.title_color, title_font,
         title_font = self.author_font or ImageFont.truetype(
             get_resource('fonts/DejaVuSerif.ttf'), 40)
         tbox.text(self.pretty_title(), self.title_color, title_font,
-            self.title_lineskip, self.title_shadow)
+                  self.title_lineskip, self.title_shadow)
         text_img = tbox.image()
         img.paste(text_img, (self.title_margin_left, top), text_img)
 
         text_img = tbox.image()
         img.paste(text_img, (self.title_margin_left, top), text_img)
 
index afcefa0..747ac86 100644 (file)
@@ -10,7 +10,7 @@ import time
 from librarian import (ValidationError, NoDublinCore, ParseError, DCNS, RDFNS,
                        WLURI)
 
 from librarian import (ValidationError, NoDublinCore, ParseError, DCNS, RDFNS,
                        WLURI)
 
-import lxml.etree as etree # ElementTree API using libxml2
+import lxml.etree as etree  # ElementTree API using libxml2
 from lxml.etree import XMLSyntaxError
 
 
 from lxml.etree import XMLSyntaxError
 
 
@@ -25,7 +25,7 @@ class Person(object):
 
     @classmethod
     def from_text(cls, text):
 
     @classmethod
     def from_text(cls, text):
-        parts = [ token.strip() for token in text.split(',') ]
+        parts = [token.strip() for token in text.split(',')]
         if len(parts) == 1:
             surname = parts[0]
             names = []
         if len(parts) == 1:
             surname = parts[0]
             names = []
@@ -36,7 +36,7 @@ class Person(object):
             if len(parts[1]) == 0:
                 # there is no non-whitespace data after the comma
                 raise ValueError("Found a comma, but no names given: \"%s\" -> %r." % (text, parts))
             if len(parts[1]) == 0:
                 # there is no non-whitespace data after the comma
                 raise ValueError("Found a comma, but no names given: \"%s\" -> %r." % (text, parts))
-            names = [ name for name in parts[1].split() if len(name) ] # all non-whitespace tokens
+            names = [name for name in parts[1].split() if len(name)]  # all non-whitespace tokens
         return cls(surname, *names)
 
     def readable(self):
         return cls(surname, *names)
 
     def readable(self):
@@ -60,6 +60,7 @@ class Person(object):
     def __repr__(self):
         return 'Person(last_name=%r, first_names=*%r)' % (self.last_name, self.first_names)
 
     def __repr__(self):
         return 'Person(last_name=%r, first_names=*%r)' % (self.last_name, self.first_names)
 
+
 def as_date(text):
     try:
         try:
 def as_date(text):
     try:
         try:
@@ -70,18 +71,22 @@ def as_date(text):
     except ValueError, e:
         raise ValueError("Unrecognized date format. Try YYYY-MM-DD or YYYY.")
 
     except ValueError, e:
         raise ValueError("Unrecognized date format. Try YYYY-MM-DD or YYYY.")
 
+
 def as_person(text):
     return Person.from_text(text)
 
 def as_person(text):
     return Person.from_text(text)
 
+
 def as_unicode(text):
     if isinstance(text, unicode):
         return text
     else:
         return text.decode('utf-8')
 
 def as_unicode(text):
     if isinstance(text, unicode):
         return text
     else:
         return text.decode('utf-8')
 
+
 def as_wluri_strict(text):
     return WLURI.strict(text)
 
 def as_wluri_strict(text):
     return WLURI.strict(text)
 
+
 class Field(object):
     def __init__(self, uri, attr_name, validator=as_unicode, strict=None, multiple=False, salias=None, **kwargs):
         self.uri = uri
 class Field(object):
     def __init__(self, uri, attr_name, validator=as_unicode, strict=None, multiple=False, salias=None, **kwargs):
         self.uri = uri
@@ -91,7 +96,7 @@ class Field(object):
         self.multiple = multiple
         self.salias = salias
 
         self.multiple = multiple
         self.salias = salias
 
-        self.required = kwargs.get('required', True) and not kwargs.has_key('default')
+        self.required = kwargs.get('required', True) and 'default' not in kwargs
         self.default = kwargs.get('default', [] if multiple else [None])
 
     def validate_value(self, val, strict=False):
         self.default = kwargs.get('default', [] if multiple else [None])
 
     def validate_value(self, val, strict=False):
@@ -104,7 +109,7 @@ class Field(object):
             if self.multiple:
                 if validator is None:
                     return val
             if self.multiple:
                 if validator is None:
                     return val
-                return [ validator(v) if v is not None else v for v in val ]
+                return [validator(v) if v is not None else v for v in val]
             elif len(val) > 1:
                 raise ValidationError("Multiple values not allowed for field '%s'" % self.uri)
             elif len(val) == 0:
             elif len(val) > 1:
                 raise ValidationError("Multiple values not allowed for field '%s'" % self.uri)
             elif len(val) == 0:
@@ -119,7 +124,7 @@ class Field(object):
     def validate(self, fdict, fallbacks=None, strict=False):
         if fallbacks is None:
             fallbacks = {}
     def validate(self, fdict, fallbacks=None, strict=False):
         if fallbacks is None:
             fallbacks = {}
-        if not fdict.has_key(self.uri):
+        if self.uri not in fdict:
             if not self.required:
                 # Accept single value for single fields and saliases.
                 if self.name in fallbacks:
             if not self.required:
                 # Accept single value for single fields and saliases.
                 if self.name in fallbacks:
@@ -145,7 +150,7 @@ class Field(object):
 
 
 class DCInfo(type):
 
 
 class DCInfo(type):
-    def __new__(meta, classname, bases, class_dict):
+    def __new__(mcs, classname, bases, class_dict):
         fields = list(class_dict['FIELDS'])
 
         for base in bases[::-1]:
         fields = list(class_dict['FIELDS'])
 
         for base in bases[::-1]:
@@ -157,41 +162,41 @@ class DCInfo(type):
                         fields.insert(0, field)
 
         class_dict['FIELDS'] = tuple(fields)
                         fields.insert(0, field)
 
         class_dict['FIELDS'] = tuple(fields)
-        return super(DCInfo, meta).__new__(meta, classname, bases, class_dict)
+        return super(DCInfo, mcs).__new__(mcs, classname, bases, class_dict)
 
 
 class WorkInfo(object):
     __metaclass__ = DCInfo
 
     FIELDS = (
 
 
 class WorkInfo(object):
     __metaclass__ = DCInfo
 
     FIELDS = (
-        Field( DCNS('creator.expert'), 'authors_expert', as_person, salias='author', required=False, multiple=True),
-        Field( DCNS('creator.methodologist'), 'authors_methodologist', as_person, salias='author', required=False, multiple=True),
-        Field( DCNS('creator.scenario'), 'authors_scenario', as_person, salias='author', required=False, multiple=True),
-        Field( DCNS('creator.textbook'), 'authors_textbook', as_person, salias='author', required=False, multiple=True),
-        Field( DCNS('requires'), 'requires', required=False, multiple=True),
-        Field( DCNS('title'), 'title'),
-        Field( DCNS('type'), 'type', required=False),
-
-        Field( DCNS('contributor.editor'), 'editors', \
-            as_person, salias='editor', multiple=True, default=[]),
-        Field( DCNS('contributor.technical_editor'), 'technical_editors',
-            as_person, salias='technical_editor', multiple=True, default=[]),
-
-        Field( DCNS('date'), 'created_at', as_date),
-        Field( DCNS('date.pd'), 'released_to_public_domain_at', as_date, required=False),
-        Field( DCNS('publisher'), 'publisher'),
-
-        Field( DCNS('subject.competence'), 'competences', multiple=True, required=False),
-        Field( DCNS('subject.curriculum'), 'curriculum', multiple=True, required=False),
-
-        Field( DCNS('language'), 'language'),
-        Field( DCNS('description'), 'description', required=False),
-
-        Field( DCNS('source'), 'source_name', required=False),
-        Field( DCNS('source.URL'), 'source_url', required=False),
-        Field( DCNS('identifier.url'), 'url', WLURI, strict=as_wluri_strict),
-        Field( DCNS('rights.license'), 'license', required=False),
-        Field( DCNS('rights'), 'license_description'),
+        Field(DCNS('creator.expert'), 'authors_expert', as_person, salias='author', required=False, multiple=True),
+        Field(DCNS('creator.methodologist'), 'authors_methodologist', as_person, salias='author', required=False,
+              multiple=True),
+        Field(DCNS('creator.scenario'), 'authors_scenario', as_person, salias='author', required=False, multiple=True),
+        Field(DCNS('creator.textbook'), 'authors_textbook', as_person, salias='author', required=False, multiple=True),
+        Field(DCNS('requires'), 'requires', required=False, multiple=True),
+        Field(DCNS('title'), 'title'),
+        Field(DCNS('type'), 'type', required=False),
+
+        Field(DCNS('contributor.editor'), 'editors', as_person, salias='editor', multiple=True, default=[]),
+        Field(DCNS('contributor.technical_editor'), 'technical_editors', as_person, salias='technical_editor',
+              multiple=True, default=[]),
+
+        Field(DCNS('date'), 'created_at', as_date),
+        Field(DCNS('date.pd'), 'released_to_public_domain_at', as_date, required=False),
+        Field(DCNS('publisher'), 'publisher'),
+
+        Field(DCNS('subject.competence'), 'competences', multiple=True, required=False),
+        Field(DCNS('subject.curriculum'), 'curriculum', multiple=True, required=False),
+
+        Field(DCNS('language'), 'language'),
+        Field(DCNS('description'), 'description', required=False),
+
+        Field(DCNS('source'), 'source_name', required=False),
+        Field(DCNS('source.URL'), 'source_url', required=False),
+        Field(DCNS('identifier.url'), 'url', WLURI, strict=as_wluri_strict),
+        Field(DCNS('rights.license'), 'license', required=False),
+        Field(DCNS('rights'), 'license_description'),
     )
 
     @classmethod
     )
 
     @classmethod
@@ -203,8 +208,8 @@ class WorkInfo(object):
     def from_file(cls, xmlfile, *args, **kwargs):
         desc_tag = None
         try:
     def from_file(cls, xmlfile, *args, **kwargs):
         desc_tag = None
         try:
-            iter = etree.iterparse(xmlfile, ['start', 'end'])
-            for (event, element) in iter:
+            elements = etree.iterparse(xmlfile, ['start', 'end'])
+            for (event, element) in elements:
                 if element.tag == RDFNS('RDF') and event == 'start':
                     desc_tag = element
                     break
                 if element.tag == RDFNS('RDF') and event == 'start':
                     desc_tag = element
                     break
@@ -214,7 +219,7 @@ class WorkInfo(object):
                     Check if there are rdf:RDF and rdf:Description tags.")
 
             # continue 'till the end of RDF section
                     Check if there are rdf:RDF and rdf:Description tags.")
 
             # continue 'till the end of RDF section
-            for (event, element) in iter:
+            for (event, element) in elements:
                 if element.tag == RDFNS('RDF') and event == 'end':
                     break
 
                 if element.tag == RDFNS('RDF') and event == 'end':
                     break
 
@@ -252,13 +257,13 @@ class WorkInfo(object):
         self.fmap = {}
 
         for field in self.FIELDS:
         self.fmap = {}
 
         for field in self.FIELDS:
-            value = field.validate(dc_fields, fallbacks=fallbacks,
-                            strict=strict)
+            value = field.validate(dc_fields, fallbacks=fallbacks, strict=strict)
             if field.multiple:
                 value = getattr(self, 'prop_' + field.name, []) + value
             setattr(self, 'prop_' + field.name, value)
             self.fmap[field.name] = field
             if field.multiple:
                 value = getattr(self, 'prop_' + field.name, []) + value
             setattr(self, 'prop_' + field.name, value)
             self.fmap[field.name] = field
-            if field.salias: self.fmap[field.salias] = field
+            if field.salias:
+                self.fmap[field.salias] = field
 
     def __getattribute__(self, name):
         try:
 
     def __getattribute__(self, name):
         try:
@@ -266,7 +271,8 @@ class WorkInfo(object):
             value = object.__getattribute__(self, 'prop_'+field.name)
             if field.name == name:
                 return value
             value = object.__getattribute__(self, 'prop_'+field.name)
             if field.name == name:
                 return value
-            else: # singular alias
+            else:
+                # singular alias
                 if not field.multiple:
                     raise "OUCH!! for field %s" % name
 
                 if not field.multiple:
                     raise "OUCH!! for field %s" % name
 
@@ -279,7 +285,8 @@ class WorkInfo(object):
             field = object.__getattribute__(self, 'fmap')[name]
             if field.name == name:
                 object.__setattr__(self, 'prop_'+field.name, newvalue)
             field = object.__getattribute__(self, 'fmap')[name]
             if field.name == name:
                 object.__setattr__(self, 'prop_'+field.name, newvalue)
-            else: # singular alias
+            else:
+                # singular alias
                 if not field.multiple:
                     raise "OUCH! while setting field %s" % name
 
                 if not field.multiple:
                     raise "OUCH! while setting field %s" % name
 
@@ -291,13 +298,13 @@ class WorkInfo(object):
         """Update using field_dict. Verify correctness, but don't check if all
         required fields are present."""
         for field in self.FIELDS:
         """Update using field_dict. Verify correctness, but don't check if all
         required fields are present."""
         for field in self.FIELDS:
-            if field_dict.has_key(field.name):
+            if field.name in field_dict:
                 setattr(self, field.name, field_dict[field.name])
 
                 setattr(self, field.name, field_dict[field.name])
 
-    def to_etree(self, parent = None):
+    def to_etree(self, parent=None):
         """XML representation of this object."""
         """XML representation of this object."""
-        #etree._namespace_map[str(self.RDF)] = 'rdf'
-        #etree._namespace_map[str(self.DC)] = 'dc'
+        # etree._namespace_map[str(self.RDF)] = 'rdf'
+        # etree._namespace_map[str(self.DC)] = 'dc'
 
         if parent is None:
             root = etree.Element(RDFNS('RDF'))
 
         if parent is None:
             root = etree.Element(RDFNS('RDF'))
@@ -313,7 +320,8 @@ class WorkInfo(object):
             v = getattr(self, field.name, None)
             if v is not None:
                 if field.multiple:
             v = getattr(self, field.name, None)
             if v is not None:
                 if field.multiple:
-                    if len(v) == 0: continue
+                    if len(v) == 0:
+                        continue
                     for x in v:
                         e = etree.Element(field.uri)
                         if x is not None:
                     for x in v:
                         e = etree.Element(field.uri)
                         if x is not None:
@@ -327,16 +335,16 @@ class WorkInfo(object):
         return root
 
     def serialize(self):
         return root
 
     def serialize(self):
-        rdf = {}
-        rdf['about'] = { 'uri': RDFNS('about'), 'value': self.about }
+        rdf = {'about': {'uri': RDFNS('about'), 'value': self.about}}
 
         dc = {}
         for field in self.FIELDS:
             v = getattr(self, field.name, None)
             if v is not None:
                 if field.multiple:
 
         dc = {}
         for field in self.FIELDS:
             v = getattr(self, field.name, None)
             if v is not None:
                 if field.multiple:
-                    if len(v) == 0: continue
-                    v = [ unicode(x) for x in v if x is not None ]
+                    if len(v) == 0:
+                        continue
+                    v = [unicode(x) for x in v if x is not None]
                 else:
                     v = unicode(v)
 
                 else:
                     v = unicode(v)
 
@@ -351,43 +359,38 @@ class WorkInfo(object):
 
             if v is not None:
                 if field.multiple:
 
             if v is not None:
                 if field.multiple:
-                    if len(v) == 0: continue
-                    v = [ unicode(x) for x in v if x is not None ]
+                    if len(v) == 0:
+                        continue
+                    v = [unicode(x) for x in v if x is not None]
                 else:
                     v = unicode(v)
                 result[field.name] = v
 
             if field.salias:
                 v = getattr(self, field.salias)
                 else:
                     v = unicode(v)
                 result[field.name] = v
 
             if field.salias:
                 v = getattr(self, field.salias)
-                if v is not None: result[field.salias] = unicode(v)
+                if v is not None:
+                    result[field.salias] = unicode(v)
 
         return result
 
 
 class BookInfo(WorkInfo):
     FIELDS = (
 
         return result
 
 
 class BookInfo(WorkInfo):
     FIELDS = (
-        Field( DCNS('audience'), 'audiences', salias='audience', multiple=True,
-                required=False),
-
-        Field( DCNS('subject.period'), 'epochs', salias='epoch', multiple=True,
-                required=False),
-        Field( DCNS('subject.type'), 'kinds', salias='kind', multiple=True,
-                required=False),
-        Field( DCNS('subject.genre'), 'genres', salias='genre', multiple=True,
-                required=False),
-
-        Field( DCNS('contributor.translator'), 'translators', \
-            as_person,  salias='translator', multiple=True, default=[]),
-        Field( DCNS('relation.hasPart'), 'parts',
-            WLURI, strict=as_wluri_strict, multiple=True, required=False),
-        Field( DCNS('relation.isVariantOf'), 'variant_of',
-            WLURI, strict=as_wluri_strict, required=False),
-        Field( DCNS('relation'), 'relations',
-            WLURI, strict=as_wluri_strict, multiple=True, required=False),
-
-        Field( DCNS('relation.coverImage.url'), 'cover_url', required=False),
-        Field( DCNS('relation.coverImage.attribution'), 'cover_by', required=False),
-        Field( DCNS('relation.coverImage.source'), 'cover_source', required=False),
+        Field(DCNS('audience'), 'audiences', salias='audience', multiple=True, required=False),
+
+        Field(DCNS('subject.period'), 'epochs', salias='epoch', multiple=True, required=False),
+        Field(DCNS('subject.type'), 'kinds', salias='kind', multiple=True, required=False),
+        Field(DCNS('subject.genre'), 'genres', salias='genre', multiple=True, required=False),
+
+        Field(DCNS('contributor.translator'), 'translators', as_person,  salias='translator', multiple=True,
+              default=[]),
+        Field(DCNS('relation.hasPart'), 'parts', WLURI, strict=as_wluri_strict, multiple=True, required=False),
+        Field(DCNS('relation.isVariantOf'), 'variant_of', WLURI, strict=as_wluri_strict, required=False),
+        Field(DCNS('relation'), 'relations', WLURI, strict=as_wluri_strict, multiple=True, required=False),
+
+        Field(DCNS('relation.coverImage.url'), 'cover_url', required=False),
+        Field(DCNS('relation.coverImage.attribution'), 'cover_by', required=False),
+        Field(DCNS('relation.coverImage.source'), 'cover_source', required=False),
     )
 
 
     )
 
 
index 8141eea..01f5c92 100644 (file)
@@ -33,6 +33,7 @@ def inner_xml(node):
     nt = node.text if node.text is not None else ''
     return ''.join([nt] + [etree.tostring(child) for child in node])
 
     nt = node.text if node.text is not None else ''
     return ''.join([nt] + [etree.tostring(child) for child in node])
 
+
 def set_inner_xml(node, text):
     """ sets node's text and children from a string
 
 def set_inner_xml(node, text):
     """ sets node's text and children from a string
 
@@ -121,7 +122,7 @@ class Stanza(object):
     >>> print etree.tostring(s)
     <strofa><wers_normalny>a</wers_normalny><wers_normalny>b<x>x/
     y</x>c</wers_normalny><wers_normalny>d</wers_normalny></strofa>
     >>> print etree.tostring(s)
     <strofa><wers_normalny>a</wers_normalny><wers_normalny>b<x>x/
     y</x>c</wers_normalny><wers_normalny>d</wers_normalny></strofa>
-    
+
     """
     def __init__(self, stanza_elem):
         self.stanza = stanza_elem
     """
     def __init__(self, stanza_elem):
         self.stanza = stanza_elem
@@ -194,7 +195,7 @@ def add_to_manifest(manifest, partno):
 def add_to_spine(spine, partno):
     """ Adds a node to the spine section in content.opf file """
 
 def add_to_spine(spine, partno):
     """ Adds a node to the spine section in content.opf file """
 
-    e = spine.makeelement(OPFNS('itemref'), attrib={'idref': 'part%d' % partno});
+    e = spine.makeelement(OPFNS('itemref'), attrib={'idref': 'part%d' % partno})
     spine.append(e)
 
 
     spine.append(e)
 
 
@@ -286,7 +287,7 @@ def chop(main_text):
     # prepare a container for each chunk
     part_xml = etree.Element('utwor')
     etree.SubElement(part_xml, 'master')
     # prepare a container for each chunk
     part_xml = etree.Element('utwor')
     etree.SubElement(part_xml, 'master')
-    main_xml_part = part_xml[0] # master
+    main_xml_part = part_xml[0]  # master
 
     last_node_part = False
     for one_part in main_text:
 
     last_node_part = False
     for one_part in main_text:
@@ -304,8 +305,10 @@ def chop(main_text):
     yield part_xml
 
 
     yield part_xml
 
 
-def transform_chunk(chunk_xml, chunk_no, annotations, empty=False, _empty_html_static=[]):
+def transform_chunk(chunk_xml, chunk_no, annotations, empty=False, _empty_html_static=None):
     """ transforms one chunk, returns a HTML string, a TOC object and a set of used characters """
     """ transforms one chunk, returns a HTML string, a TOC object and a set of used characters """
+    if _empty_html_static is None:
+        _empty_html_static = []
 
     toc = TOC()
     for element in chunk_xml[0]:
 
     toc = TOC()
     for element in chunk_xml[0]:
@@ -351,8 +354,7 @@ def transform(wldoc, verbose=False,
             # write book title page
             html_tree = xslt(wldoc.edoc, get_resource('epub/xsltTitle.xsl'))
             chars = used_chars(html_tree.getroot())
             # write book title page
             html_tree = xslt(wldoc.edoc, get_resource('epub/xsltTitle.xsl'))
             chars = used_chars(html_tree.getroot())
-            zip.writestr('OPS/title.html',
-                 etree.tostring(html_tree, method="html", pretty_print=True))
+            zip.writestr('OPS/title.html', etree.tostring(html_tree, method="html", pretty_print=True))
             # add a title page TOC entry
             toc.add(u"Strona tytułowa", "title.html")
         elif wldoc.book_info.parts:
             # add a title page TOC entry
             toc.add(u"Strona tytułowa", "title.html")
         elif wldoc.book_info.parts:
@@ -403,7 +405,6 @@ def transform(wldoc, verbose=False,
 
         return toc, chunk_counter, chars, sample
 
 
         return toc, chunk_counter, chars, sample
 
-
     document = deepcopy(wldoc)
     del wldoc
 
     document = deepcopy(wldoc)
     del wldoc
 
@@ -429,11 +430,12 @@ def transform(wldoc, verbose=False,
     mime.compress_type = zipfile.ZIP_STORED
     mime.extra = ''
     zip.writestr(mime, 'application/epub+zip')
     mime.compress_type = zipfile.ZIP_STORED
     mime.extra = ''
     zip.writestr(mime, 'application/epub+zip')
-    zip.writestr('META-INF/container.xml', '<?xml version="1.0" ?><container version="1.0" ' \
-                       'xmlns="urn:oasis:names:tc:opendocument:xmlns:container">' \
-                       '<rootfiles><rootfile full-path="OPS/content.opf" ' \
-                       'media-type="application/oebps-package+xml" />' \
-                       '</rootfiles></container>')
+    zip.writestr(
+        'META-INF/container.xml', '<?xml version="1.0" ?><container version="1.0" '
+        'xmlns="urn:oasis:names:tc:opendocument:xmlns:container">'
+        '<rootfiles><rootfile full-path="OPS/content.opf" '
+        'media-type="application/oebps-package+xml" />'
+        '</rootfiles></container>')
     zip.write(get_resource('res/wl-logo-small.png'), os.path.join('OPS', 'logo_wolnelektury.png'))
     zip.write(get_resource('res/jedenprocent.png'), os.path.join('OPS', 'jedenprocent.png'))
     if not style:
     zip.write(get_resource('res/wl-logo-small.png'), os.path.join('OPS', 'logo_wolnelektury.png'))
     zip.write(get_resource('res/jedenprocent.png'), os.path.join('OPS', 'jedenprocent.png'))
     if not style:
@@ -467,14 +469,14 @@ def transform(wldoc, verbose=False,
         opf.getroot()[0].append(etree.fromstring('<meta name="cover" content="cover-image"/>'))
         guide.append(etree.fromstring('<reference href="cover.html" type="cover" title="Okładka"/>'))
 
         opf.getroot()[0].append(etree.fromstring('<meta name="cover" content="cover-image"/>'))
         guide.append(etree.fromstring('<reference href="cover.html" type="cover" title="Okładka"/>'))
 
-
     annotations = etree.Element('annotations')
 
     annotations = etree.Element('annotations')
 
-    toc_file = etree.fromstring('<?xml version="1.0" encoding="utf-8"?><!DOCTYPE ncx PUBLIC ' \
-                               '"-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">' \
-                               '<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" xml:lang="pl" ' \
-                               'version="2005-1"><head></head><docTitle></docTitle><navMap>' \
-                               '</navMap></ncx>')
+    toc_file = etree.fromstring(
+        '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE ncx PUBLIC '
+        '"-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">'
+        '<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" xml:lang="pl" '
+        'version="2005-1"><head></head><docTitle></docTitle><navMap>'
+        '</navMap></ncx>')
     nav_map = toc_file[-1]
 
     if html_toc:
     nav_map = toc_file[-1]
 
     if html_toc:
@@ -512,7 +514,7 @@ def transform(wldoc, verbose=False,
     zip.writestr('OPS/last.html', etree.tostring(
                         html_tree, method="html", pretty_print=True))
 
     zip.writestr('OPS/last.html', etree.tostring(
                         html_tree, method="html", pretty_print=True))
 
-    if not flags or not 'without-fonts' in flags:
+    if not flags or 'without-fonts' not in flags:
         # strip fonts
         tmpdir = mkdtemp('-librarian-epub')
         try:
         # strip fonts
         tmpdir = mkdtemp('-librarian-epub')
         try:
index 1e110f5..bc1504d 100644 (file)
@@ -17,10 +17,11 @@ functions.reg_person_name()
 
 def sectionify(tree):
     """Finds section headers and adds a tree of _section tags."""
 
 def sectionify(tree):
     """Finds section headers and adds a tree of _section tags."""
-    sections = ['naglowek_czesc',
-            'naglowek_akt', 'naglowek_rozdzial', 'naglowek_scena',
-            'naglowek_podrozdzial']
-    section_level = dict((v,k) for (k,v) in enumerate(sections))
+    sections = [
+        'naglowek_czesc',
+        'naglowek_akt', 'naglowek_rozdzial', 'naglowek_scena',
+        'naglowek_podrozdzial']
+    section_level = {v: k for (k, v) in enumerate(sections)}
 
     # We can assume there are just subelements an no text at section level.
     for level, section_name in reversed(list(enumerate(sections))):
 
     # We can assume there are just subelements an no text at section level.
     for level, section_name in reversed(list(enumerate(sections))):
index bd05ff4..7eb9d56 100644 (file)
@@ -8,6 +8,7 @@ import re
 
 from librarian.dcparser import Person
 
 
 from librarian.dcparser import Person
 
+
 def _register_function(f):
     """ Register extension function with lxml """
     ns = etree.FunctionNamespace('http://wolnelektury.pl/functions')
 def _register_function(f):
     """ Register extension function with lxml """
     ns = etree.FunctionNamespace('http://wolnelektury.pl/functions')
@@ -15,13 +16,14 @@ def _register_function(f):
 
 
 ENTITY_SUBSTITUTIONS = [
 
 
 ENTITY_SUBSTITUTIONS = [
-       (u'---', u'—'),
-       (u'--', u'–'),
-       (u'...', u'…'),
-       (u',,', u'„'),
-       (u'"', u'”'),
+    (u'---', u'—'),
+    (u'--', u'–'),
+    (u'...', u'…'),
+    (u',,', u'„'),
+    (u'"', u'”'),
 ]
 
 ]
 
+
 def substitute_entities(text):
     """XPath extension function converting all entites in passed text."""
     if isinstance(text, list):
 def substitute_entities(text):
     """XPath extension function converting all entites in passed text."""
     if isinstance(text, list):
index 985970a..848935a 100644 (file)
@@ -22,12 +22,15 @@ STYLESHEETS = {
     'partial': 'xslt/wl2html_partial.xslt'
 }
 
     'partial': 'xslt/wl2html_partial.xslt'
 }
 
+
 def get_stylesheet(name):
     return os.path.join(os.path.dirname(__file__), STYLESHEETS[name])
 
 def get_stylesheet(name):
     return os.path.join(os.path.dirname(__file__), STYLESHEETS[name])
 
+
 def html_has_content(text):
     return etree.ETXPath('//p|//{%(ns)s}p|//h1|//{%(ns)s}h1' % {'ns': str(XHTMLNS)})(text)
 
 def html_has_content(text):
     return etree.ETXPath('//p|//{%(ns)s}p|//h1|//{%(ns)s}h1' % {'ns': str(XHTMLNS)})(text)
 
+
 def transform(wldoc, stylesheet='legacy', options=None, flags=None):
     """Transforms the WL document to XHTML.
 
 def transform(wldoc, stylesheet='legacy', options=None, flags=None):
     """Transforms the WL document to XHTML.
 
@@ -53,14 +56,14 @@ def transform(wldoc, stylesheet='legacy', options=None, flags=None):
         if not options:
             options = {}
         result = document.transform(style, **options)
         if not options:
             options = {}
         result = document.transform(style, **options)
-        del document # no longer needed large object :)
+        del document  # no longer needed large object :)
 
         if html_has_content(result):
             add_anchors(result.getroot())
             add_table_of_contents(result.getroot())
 
 
         if html_has_content(result):
             add_anchors(result.getroot())
             add_table_of_contents(result.getroot())
 
-            return IOFile.from_string(etree.tostring(result, method='html',
-                xml_declaration=False, pretty_print=True, encoding='utf-8'))
+            return IOFile.from_string(
+                etree.tostring(result, method='html', xml_declaration=False, pretty_print=True, encoding='utf-8'))
         else:
             return None
     except KeyError:
         else:
             return None
     except KeyError:
@@ -68,6 +71,7 @@ def transform(wldoc, stylesheet='legacy', options=None, flags=None):
     except (XMLSyntaxError, XSLTApplyError), e:
         raise ParseError(e)
 
     except (XMLSyntaxError, XSLTApplyError), e:
         raise ParseError(e)
 
+
 class Fragment(object):
     def __init__(self, id, themes):
         super(Fragment, self).__init__()
 class Fragment(object):
     def __init__(self, id, themes):
         super(Fragment, self).__init__()
@@ -96,7 +100,8 @@ class Fragment(object):
         result = []
         for event, element in self.closed_events():
             if event == 'start':
         result = []
         for event, element in self.closed_events():
             if event == 'start':
-                result.append(u'<%s %s>' % (element.tag, ' '.join('%s="%s"' % (k, v) for k, v in element.attrib.items())))
+                result.append(u'<%s %s>' % (
+                    element.tag, ' '.join('%s="%s"' % (k, v) for k, v in element.attrib.items())))
                 if element.text:
                     result.append(element.text)
             elif event == 'end':
                 if element.text:
                     result.append(element.text)
             elif event == 'end':
@@ -126,7 +131,8 @@ def extract_fragments(input_filename):
     for event, element in etree.iterparse(buf, events=('start', 'end')):
         # Process begin and end elements
         if element.get('class', '') in ('theme-begin', 'theme-end'):
     for event, element in etree.iterparse(buf, events=('start', 'end')):
         # Process begin and end elements
         if element.get('class', '') in ('theme-begin', 'theme-end'):
-            if not event == 'end': continue # Process elements only once, on end event
+            if not event == 'end':
+                continue  # Process elements only once, on end event
 
             # Open new fragment
             if element.get('class', '') == 'theme-begin':
 
             # Open new fragment
             if element.get('class', '') == 'theme-begin':
@@ -159,11 +165,10 @@ def extract_fragments(input_filename):
                 for fragment_id in open_fragments:
                     open_fragments[fragment_id].append('text', element.tail)
 
                 for fragment_id in open_fragments:
                     open_fragments[fragment_id].append('text', element.tail)
 
-
         # Process all elements except begin and end
         else:
             # Omit annotation tags
         # Process all elements except begin and end
         else:
             # Omit annotation tags
-            if (len(element.get('name', '')) or 
+            if (len(element.get('name', '')) or
                     element.get('class', '') in ('annotation', 'anchor')):
                 if event == 'end' and element.tail:
                     for fragment_id in open_fragments:
                     element.get('class', '') in ('annotation', 'anchor')):
                 if event == 'end' and element.tail:
                     for fragment_id in open_fragments:
@@ -206,10 +211,13 @@ def any_ancestor(element, test):
 
 def add_anchors(root):
     counter = 1
 
 def add_anchors(root):
     counter = 1
+
+    def is_side_text(e):
+        side_classes = ('note', 'motto', 'motto_podpis', 'dedication')
+        return e.get('class') in side_classes or e.get('id') == 'nota_red' or e.tag == 'blockquote'
+
     for element in root.iterdescendants():
     for element in root.iterdescendants():
-        if any_ancestor(element, lambda e: e.get('class') in ('note', 'motto', 'motto_podpis', 'dedication')
-        or e.get('id') == 'nota_red'
-        or e.tag == 'blockquote'):
+        if any_ancestor(element, is_side_text):
             continue
 
         if element.tag == 'p' and 'verse' in element.get('class', ''):
             continue
 
         if element.tag == 'p' and 'verse' in element.get('class', ''):
@@ -232,9 +240,13 @@ def raw_printable_text(element):
 def add_table_of_contents(root):
     sections = []
     counter = 1
 def add_table_of_contents(root):
     sections = []
     counter = 1
+
+    def is_side_text(e):
+        return e.get('id') in ('footnotes', 'nota_red') or e.get('class') == 'person-list'
+
     for element in root.iterdescendants():
         if element.tag in ('h2', 'h3'):
     for element in root.iterdescendants():
         if element.tag in ('h2', 'h3'):
-            if any_ancestor(element, lambda e: e.get('id') in ('footnotes', 'nota_red') or e.get('class') in ('person-list',)):
+            if any_ancestor(element, is_side_text):
                 continue
 
             element_text = raw_printable_text(element)
                 continue
 
             element_text = raw_printable_text(element)
@@ -257,9 +269,9 @@ def add_table_of_contents(root):
 
         if len(subsections):
             subsection_list = etree.SubElement(section_element, 'ol')
 
         if len(subsections):
             subsection_list = etree.SubElement(section_element, 'ol')
-            for n, subsection, text, _ in subsections:
+            for n1, subsection, text1, _ in subsections:
                 subsection_element = etree.SubElement(subsection_list, 'li')
                 subsection_element = etree.SubElement(subsection_list, 'li')
-                add_anchor(subsection_element, "s%d" % n, with_target=False, link_text=text)
+                add_anchor(subsection_element, "s%d" % n1, with_target=False, link_text=text1)
 
     root.insert(0, toc)
 
 
     root.insert(0, toc)
 
@@ -276,4 +288,3 @@ def extract_annotations(html_path):
             text_str = etree.tostring(footnote, method='text', encoding='utf-8').strip()
             html_str = etree.tostring(footnote, method='html', encoding='utf-8')
             yield anchor, text_str, html_str
             text_str = etree.tostring(footnote, method='text', encoding='utf-8').strip()
             html_str = etree.tostring(footnote, method='html', encoding='utf-8')
             yield anchor, text_str, html_str
-
index 9558452..104f1c0 100644 (file)
@@ -9,7 +9,6 @@ import subprocess
 from tempfile import NamedTemporaryFile
 
 from librarian import IOFile
 from tempfile import NamedTemporaryFile
 
 from librarian import IOFile
-from librarian.cover import WLCover
 from librarian import get_resource
 
 
 from librarian import get_resource
 
 
@@ -28,8 +27,8 @@ def transform(wldoc, verbose=False,
     book_info = document.book_info
 
     # provide a cover by default
     book_info = document.book_info
 
     # provide a cover by default
-    if not cover:
-        cover = WLCover
+    if not cover:
+        cover = WLCover
     cover_file = NamedTemporaryFile(suffix='.png', delete=False)
     bound_cover = cover(book_info)
     bound_cover.save(cover_file)
     cover_file = NamedTemporaryFile(suffix='.png', delete=False)
     bound_cover = cover(book_info)
     bound_cover.save(cover_file)
@@ -43,8 +42,8 @@ def transform(wldoc, verbose=False,
     if not flags:
         flags = []
     flags = list(flags) + ['without-fonts']
     if not flags:
         flags = []
     flags = list(flags) + ['without-fonts']
-    epub = document.as_epub(verbose=verbose, sample=sample, html_toc=True,
-            flags=flags, style=get_resource('mobi/style.css'))
+    epub = document.as_epub(
+        verbose=verbose, sample=sample, html_toc=True, flags=flags, style=get_resource('mobi/style.css'))
 
     if verbose:
         kwargs = {}
 
     if verbose:
         kwargs = {}
@@ -54,7 +53,8 @@ def transform(wldoc, verbose=False,
 
     output_file = NamedTemporaryFile(prefix='librarian', suffix='.mobi', delete=False)
     output_file.close()
 
     output_file = NamedTemporaryFile(prefix='librarian', suffix='.mobi', delete=False)
     output_file.close()
-    subprocess.check_call(['ebook-convert', epub.get_filename(), output_file.name,
-            '--no-inline-toc', '--cover=%s' % cover_file.name], **kwargs)
+    subprocess.check_call(
+        ['ebook-convert', epub.get_filename(), output_file.name, '--no-inline-toc', '--cover=%s' % cover_file.name],
+        **kwargs)
     os.unlink(cover_file.name)
     os.unlink(cover_file.name)
-    return IOFile.from_filename(output_file.name)
\ No newline at end of file
+    return IOFile.from_filename(output_file.name)
index ddfd7c8..0dbb6e8 100644 (file)
@@ -8,38 +8,38 @@ from copy import deepcopy
 from lxml import etree
 from librarian import pdf, epub, DirDocProvider, ParseError, cover
 from librarian.parser import WLDocument
 from lxml import etree
 from librarian import pdf, epub, DirDocProvider, ParseError, cover
 from librarian.parser import WLDocument
+from librarian.styles.wolnelektury.partners import cover
 
 
 class Packager(object):
     cover = None
     flags = None
 
 
 class Packager(object):
     cover = None
     flags = None
+    converter = NotImplemented
+    ext = NotImplemented
 
     @classmethod
 
     @classmethod
-    def prepare_file(cls, main_input, output_dir, verbose=False):
+    def prepare_file(cls, main_input, output_dir):
         path, fname = os.path.realpath(main_input).rsplit('/', 1)
         provider = DirDocProvider(path)
         slug, ext = os.path.splitext(fname)
 
         if output_dir != '':
         path, fname = os.path.realpath(main_input).rsplit('/', 1)
         provider = DirDocProvider(path)
         slug, ext = os.path.splitext(fname)
 
         if output_dir != '':
-            try:
+            if not os.path.isdir(output_dir):
                 os.makedirs(output_dir)
                 os.makedirs(output_dir)
-            except:
-                pass
         outfile = os.path.join(output_dir, slug + '.' + cls.ext)
 
         doc = WLDocument.from_file(main_input, provider=provider)
         outfile = os.path.join(output_dir, slug + '.' + cls.ext)
 
         doc = WLDocument.from_file(main_input, provider=provider)
-        output_file = cls.converter.transform(doc,
-                cover=cls.cover, flags=cls.flags)
+        output_file = cls.converter.transform(doc, cover=cls.cover, flags=cls.flags)
         doc.save_output_file(output_file, output_path=outfile)
 
         doc.save_output_file(output_file, output_path=outfile)
 
-
     @classmethod
     def prepare(cls, input_filenames, output_dir='', verbose=False):
     @classmethod
     def prepare(cls, input_filenames, output_dir='', verbose=False):
+        main_input = None
         try:
             for main_input in input_filenames:
                 if verbose:
                     print main_input
         try:
             for main_input in input_filenames:
                 if verbose:
                     print main_input
-                cls.prepare_file(main_input, output_dir, verbose)
+                cls.prepare_file(main_input, output_dir)
         except ParseError, e:
             print '%(file)s:%(name)s:%(message)s' % {
                 'file': main_input,
         except ParseError, e:
             print '%(file)s:%(name)s:%(message)s' % {
                 'file': main_input,
@@ -52,6 +52,7 @@ class EpubPackager(Packager):
     converter = epub
     ext = 'epub'
 
     converter = epub
     ext = 'epub'
 
+
 class PdfPackager(Packager):
     converter = pdf
     ext = 'pdf'
 class PdfPackager(Packager):
     converter = pdf
     ext = 'pdf'
@@ -60,16 +61,20 @@ class PdfPackager(Packager):
 class GandalfEpubPackager(EpubPackager):
     cover = cover.GandalfCover
 
 class GandalfEpubPackager(EpubPackager):
     cover = cover.GandalfCover
 
+
 class GandalfPdfPackager(PdfPackager):
     cover = cover.GandalfCover
 
 class GandalfPdfPackager(PdfPackager):
     cover = cover.GandalfCover
 
+
 class BookotekaEpubPackager(EpubPackager):
     cover = cover.BookotekaCover
 
 class BookotekaEpubPackager(EpubPackager):
     cover = cover.BookotekaCover
 
+
 class PrestigioEpubPackager(EpubPackager):
     cover = cover.PrestigioCover
     flags = ('less-advertising',)
 
 class PrestigioEpubPackager(EpubPackager):
     cover = cover.PrestigioCover
     flags = ('less-advertising',)
 
+
 class PrestigioPdfPackager(PdfPackager):
     cover = cover.PrestigioCover
     flags = ('less-advertising',)
 class PrestigioPdfPackager(PdfPackager):
     cover = cover.PrestigioCover
     flags = ('less-advertising',)
@@ -107,6 +112,7 @@ class VirtualoPackager(Packager):
                 <language>PL</language>
             </product>""")
 
                 <language>PL</language>
             </product>""")
 
+        main_input = None
         try:
             for main_input in input_filenames:
                 if verbose:
         try:
             for main_input in input_filenames:
                 if verbose:
@@ -133,17 +139,13 @@ class VirtualoPackager(Packager):
                 cover.VirtualoCover(info).save(os.path.join(outfile_dir, slug+'.jpg'))
                 outfile = os.path.join(outfile_dir, '1.epub')
                 outfile_sample = os.path.join(outfile_dir, '1.sample.epub')
                 cover.VirtualoCover(info).save(os.path.join(outfile_dir, slug+'.jpg'))
                 outfile = os.path.join(outfile_dir, '1.epub')
                 outfile_sample = os.path.join(outfile_dir, '1.sample.epub')
-                doc.save_output_file(doc.as_epub(),
-                        output_path=outfile)
-                doc.save_output_file(doc.as_epub(doc, sample=25), 
-                        output_path=outfile_sample)
+                doc.save_output_file(doc.as_epub(), output_path=outfile)
+                doc.save_output_file(doc.as_epub(doc, sample=25), output_path=outfile_sample)
                 outfile = os.path.join(outfile_dir, '1.mobi')
                 outfile_sample = os.path.join(outfile_dir, '1.sample.mobi')
                 outfile = os.path.join(outfile_dir, '1.mobi')
                 outfile_sample = os.path.join(outfile_dir, '1.sample.mobi')
-                doc.save_output_file(doc.as_mobi(cover=cover.VirtualoCover),
-                        output_path=outfile)
+                doc.save_output_file(doc.as_mobi(cover=cover.VirtualoCover), output_path=outfile)
                 doc.save_output_file(
                 doc.save_output_file(
-                        doc.as_mobi(doc, cover=cover.VirtualoCover, sample=25), 
-                        output_path=outfile_sample)
+                    doc.as_mobi(doc, cover=cover.VirtualoCover, sample=25), output_path=outfile_sample)
         except ParseError, e:
             print '%(file)s:%(name)s:%(message)s' % {
                 'file': main_input,
         except ParseError, e:
             print '%(file)s:%(name)s:%(message)s' % {
                 'file': main_input,
index 9300aa6..113fbbe 100644 (file)
@@ -3,7 +3,7 @@
 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from librarian import ValidationError, NoDublinCore,  ParseError, NoProvider
+from librarian import ValidationError, NoDublinCore,  ParseError
 from librarian import RDFNS, IOFile
 from librarian import dcparser
 
 from librarian import RDFNS, IOFile
 from librarian import dcparser
 
@@ -15,11 +15,13 @@ import os
 import re
 from StringIO import StringIO
 
 import re
 from StringIO import StringIO
 
+
 class WLDocument(object):
     LINE_SWAP_EXPR = re.compile(r'/\s', re.MULTILINE | re.UNICODE)
     provider = None
 
     _edoc = None
 class WLDocument(object):
     LINE_SWAP_EXPR = re.compile(r'/\s', re.MULTILINE | re.UNICODE)
     provider = None
 
     _edoc = None
+
     @property
     def edoc(self):
         if self._edoc is None:
     @property
     def edoc(self):
         if self._edoc is None:
@@ -28,13 +30,14 @@ class WLDocument(object):
                 data = data.decode('utf-8')
             data = data.replace(u'\ufeff', '')
             try:
                 data = data.decode('utf-8')
             data = data.replace(u'\ufeff', '')
             try:
-                parser = etree.XMLParser(remove_blank_text=False)
+                parser = etree.XMLParser()
                 self._edoc = etree.parse(StringIO(data.encode('utf-8')), parser)
             except (ExpatError, XMLSyntaxError, XSLTApplyError), e:
                 raise ParseError(e)
         return self._edoc
 
     _rdf_elem = None
                 self._edoc = etree.parse(StringIO(data.encode('utf-8')), parser)
             except (ExpatError, XMLSyntaxError, XSLTApplyError), e:
                 raise ParseError(e)
         return self._edoc
 
     _rdf_elem = None
+
     @property
     def rdf_elem(self):
         if self._rdf_elem is None:
     @property
     def rdf_elem(self):
         if self._rdf_elem is None:
@@ -45,6 +48,7 @@ class WLDocument(object):
         return self._rdf_elem
 
     _book_info = None
         return self._rdf_elem
 
     _book_info = None
+
     @property
     def book_info(self):
         if not self.parse_dublincore:
     @property
     def book_info(self):
         if not self.parse_dublincore:
@@ -54,20 +58,19 @@ class WLDocument(object):
                     self.rdf_elem, fallbacks=self.meta_fallbacks, strict=self.strict)
         return self._book_info
 
                     self.rdf_elem, fallbacks=self.meta_fallbacks, strict=self.strict)
         return self._book_info
 
-    def __init__(self, iofile, provider=None, 
-            parse_dublincore=True, # shouldn't it be in a subclass?
-            strict=False, # ?
-            meta_fallbacks=None # ?
-            ):
+    def __init__(self, iofile, provider=None, parse_dublincore=True,  # shouldn't it be in a subclass?
+                 strict=False,  # ?
+                 meta_fallbacks=None):  # ?
         self.source = iofile
         self.provider = provider
         self.parse_dublincore = parse_dublincore
         self.strict = strict
         self.meta_fallbacks = meta_fallbacks
         self.source = iofile
         self.provider = provider
         self.parse_dublincore = parse_dublincore
         self.strict = strict
         self.meta_fallbacks = meta_fallbacks
-        if self.edoc.getroot().tag != 'utwor':
+        root_elem = self.edoc.getroot()
+        if root_elem.tag != 'utwor':
             raise ValidationError("Invalid root element. Found '%s', should be 'utwor'" % root_elem.tag)
         if parse_dublincore:
             raise ValidationError("Invalid root element. Found '%s', should be 'utwor'" % root_elem.tag)
         if parse_dublincore:
-            self.book_info
+            self.book_info()
 
     @classmethod
     def from_string(cls, xml, *args, **kwargs):
 
     @classmethod
     def from_string(cls, xml, *args, **kwargs):
@@ -78,7 +81,6 @@ class WLDocument(object):
         iofile = IOFile.from_filename(xmlfile)
         return cls(iofile, *args, **kwargs)
 
         iofile = IOFile.from_filename(xmlfile)
         return cls(iofile, *args, **kwargs)
 
-
     def swap_endlines(self):
         """Converts line breaks in stanzas into <br/> tags."""
         # only swap inside stanzas
     def swap_endlines(self):
         """Converts line breaks in stanzas into <br/> tags."""
         # only swap inside stanzas
@@ -119,7 +121,7 @@ class WLDocument(object):
                 parts.append(part)
             else:
                 tag, n = match.groups()
                 parts.append(part)
             else:
                 tag, n = match.groups()
-                parts.append("*[%d][name() = '%s']" % (int(n)+1, tag) )
+                parts.append("*[%d][name() = '%s']" % (int(n)+1, tag))
 
         if parts[0] == '.':
             parts[0] = ''
 
         if parts[0] == '.':
             parts[0] = ''
@@ -132,7 +134,7 @@ class WLDocument(object):
     def update_dc(self):
         if self.book_info:
             parent = self.rdf_elem.getparent()
     def update_dc(self):
         if self.book_info:
             parent = self.rdf_elem.getparent()
-            parent.replace( self.rdf_elem, self.book_info.to_etree(parent) )
+            parent.replace(self.rdf_elem, self.book_info.to_etree(parent))
 
     def serialize(self):
         self.update_dc()
 
     def serialize(self):
         self.update_dc()
@@ -145,18 +147,19 @@ class WLDocument(object):
             try:
                 xpath = self.path_to_xpath(key)
                 node = self.edoc.xpath(xpath)[0]
             try:
                 xpath = self.path_to_xpath(key)
                 node = self.edoc.xpath(xpath)[0]
-                repl = etree.fromstring(u"<%s>%s</%s>" %(node.tag, data, node.tag) )
+                repl = etree.fromstring(u"<%s>%s</%s>" % (node.tag, data, node.tag))
                 node.getparent().replace(node, repl)
             except Exception, e:
                 node.getparent().replace(node, repl)
             except Exception, e:
-                unmerged.append( repr( (key, xpath, e) ) )
+                # WTF xpath may be unused; also: too broad except
+                unmerged.append(repr((key, xpath, e)))
 
         return unmerged
 
     def clean_ed_note(self):
         """ deletes forbidden tags from nota_red """
 
 
         return unmerged
 
     def clean_ed_note(self):
         """ deletes forbidden tags from nota_red """
 
-        for node in self.edoc.xpath('|'.join('//nota_red//%s' % tag for tag in
-                    ('pa', 'pe', 'pr', 'pt', 'begin', 'end', 'motyw'))):
+        forbidden_tags = ('pa', 'pe', 'pr', 'pt', 'begin', 'end', 'motyw')
+        for node in self.edoc.xpath('|'.join('//nota_red//%s' % tag for tag in forbidden_tags)):
             tail = node.tail
             node.clear()
             node.tag = 'span'
             tail = node.tail
             node.clear()
             node.tag = 'span'
@@ -194,15 +197,12 @@ class WLDocument(object):
             cover_class = WLCover
         return cover_class(self.book_info, *args, **kwargs).output_file()
 
             cover_class = WLCover
         return cover_class(self.book_info, *args, **kwargs).output_file()
 
-    def save_output_file(self, output_file, output_path=None,
-            output_dir_path=None, make_author_dir=False, ext=None):
+    def save_output_file(self, output_file, output_path=None, output_dir_path=None, make_author_dir=False, ext=None):
         if output_dir_path:
             save_path = output_dir_path
             if make_author_dir:
         if output_dir_path:
             save_path = output_dir_path
             if make_author_dir:
-                save_path = os.path.join(save_path,
-                        unicode(self.book_info.author).encode('utf-8'))
-            save_path = os.path.join(save_path,
-                                self.book_info.uri.slug)
+                save_path = os.path.join(save_path, unicode(self.book_info.author).encode('utf-8'))
+            save_path = os.path.join(save_path, self.book_info.uri.slug)
             if ext:
                 save_path += '.%s' % ext
         else:
             if ext:
                 save_path += '.%s' % ext
         else:
index 7889a22..2f5c209 100644 (file)
@@ -21,7 +21,6 @@ from subprocess import call, PIPE
 
 from Texml.processor import process
 from lxml import etree
 
 from Texml.processor import process
 from lxml import etree
-from lxml.etree import XMLSyntaxError, XSLTApplyError
 
 from librarian.dcparser import Person
 from librarian.parser import WLDocument
 
 from librarian.dcparser import Person
 from librarian.parser import WLDocument
@@ -39,11 +38,12 @@ STYLESHEETS = {
     'wl2tex': 'pdf/wl2tex.xslt',
 }
 
     'wl2tex': 'pdf/wl2tex.xslt',
 }
 
+
 def insert_tags(doc, split_re, tagname, exclude=None):
     """ inserts <tagname> for every occurence of `split_re' in text nodes in the `doc' tree
 
 def insert_tags(doc, split_re, tagname, exclude=None):
     """ inserts <tagname> for every occurence of `split_re' in text nodes in the `doc' tree
 
-    >>> t = etree.fromstring('<a><b>A-B-C</b>X-Y-Z</a>');
-    >>> insert_tags(t, re.compile('-'), 'd');
+    >>> t = etree.fromstring('<a><b>A-B-C</b>X-Y-Z</a>')
+    >>> insert_tags(t, re.compile('-'), 'd')
     >>> print etree.tostring(t)
     <a><b>A<d/>B<d/>C</b>X<d/>Y<d/>Z</a>
     """
     >>> print etree.tostring(t)
     <a><b>A<d/>B<d/>C</b>X<d/>Y<d/>Z</a>
     """
@@ -87,10 +87,14 @@ def fix_hanging(doc):
 
 def move_motifs_inside(doc):
     """ moves motifs to be into block elements """
 
 def move_motifs_inside(doc):
     """ moves motifs to be into block elements """
-    for master in doc.xpath('//powiesc|//opowiadanie|//liryka_l|//liryka_lp|//dramat_wierszowany_l|//dramat_wierszowany_lp|//dramat_wspolczesny'):
+    main_tags = ('powiesc', 'opowiadanie', 'liryka_l', 'liryka_lp',
+                 'dramat_wierszowany_l', 'dramat_wierszowany_lp', 'dramat_wspolczesny')
+    for master in doc.xpath('|'.join('//' + tag for tag in main_tags)):
         for motif in master.xpath('motyw'):
             for sib in motif.itersiblings():
         for motif in master.xpath('motyw'):
             for sib in motif.itersiblings():
-                if sib.tag not in ('sekcja_swiatlo', 'sekcja_asterysk', 'separator_linia', 'begin', 'end', 'motyw', 'extra', 'uwaga'):
+                special_tags = ('sekcja_swiatlo', 'sekcja_asterysk', 'separator_linia',
+                                'begin', 'end', 'motyw', 'extra', 'uwaga')
+                if sib.tag not in special_tags:
                     # motif shouldn't have a tail - it would be untagged text
                     motif.tail = None
                     motif.getparent().remove(motif)
                     # motif shouldn't have a tail - it would be untagged text
                     motif.tail = None
                     motif.getparent().remove(motif)
@@ -136,9 +140,10 @@ def parse_creator(doc):
     Finds all dc:creator and dc.contributor.translator tags
     and adds *_parsed versions with forenames first.
     """
     Finds all dc:creator and dc.contributor.translator tags
     and adds *_parsed versions with forenames first.
     """
-    for person in doc.xpath("|".join('//dc:'+(tag) for tag in (
-                    'creator', 'contributor.translator')),
-                    namespaces = {'dc': str(DCNS)})[::-1]:
+    persons = doc.xpath(
+        "|".join('//dc:' + tag for tag in ('creator', 'contributor.translator')),
+        namespaces={'dc': str(DCNS)})[::-1]
+    for person in persons:
         if not person.text:
             continue
         p = Person.from_text(person.text)
         if not person.text:
             continue
         p = Person.from_text(person.text)
@@ -193,8 +198,7 @@ def load_including_children(wldoc=None, provider=None, uri=None):
 
     text = re.sub(ur"([\u0400-\u04ff]+)", ur"<alien>\1</alien>", text)
 
 
     text = re.sub(ur"([\u0400-\u04ff]+)", ur"<alien>\1</alien>", text)
 
-    document = WLDocument.from_string(text,
-                parse_dublincore=True, provider=provider)
+    document = WLDocument.from_string(text, parse_dublincore=True, provider=provider)
     document.swap_endlines()
 
     for child_uri in document.book_info.parts:
     document.swap_endlines()
 
     for child_uri in document.book_info.parts:
@@ -246,8 +250,8 @@ class PDFFormat(Format):
         # Copy style
         shutil.copy(get_resource('pdf/wl.cls'), temp)
         shutil.copy(self.style, os.path.join(temp, 'style.sty'))
         # Copy style
         shutil.copy(get_resource('pdf/wl.cls'), temp)
         shutil.copy(self.style, os.path.join(temp, 'style.sty'))
-        #for sfile in ['wasysym.sty', 'uwasyvar.fd', 'uwasy.fd']:
-        #    shutil.copy(get_resource(os.path.join('res/wasysym', sfile)), temp)
+        # for sfile in ['wasysym.sty', 'uwasyvar.fd', 'uwasy.fd']:
+        #     shutil.copy(get_resource(os.path.join('res/wasysym', sfile)), temp)
 
         # Save attachments
         if self.cover:
 
         # Save attachments
         if self.cover:
@@ -263,13 +267,13 @@ class PDFFormat(Format):
             cwd = None
         os.chdir(temp)
 
             cwd = None
         os.chdir(temp)
 
+        p = None
         if self.verbose:
         if self.verbose:
-            for i in range(self.tex_passes):
+            for i in xrange(self.tex_passes):
                 p = call(['xelatex', tex_path])
         else:
                 p = call(['xelatex', tex_path])
         else:
-            for i in range(self.tex_passes):
-                p = call(['xelatex', '-interaction=batchmode', tex_path],
-                            stdout=PIPE, stderr=PIPE)
+            for i in xrange(self.tex_passes):
+                p = call(['xelatex', '-interaction=batchmode', tex_path], stdout=PIPE, stderr=PIPE)
         if p:
             raise ParseError("Error parsing .tex file: %s" % tex_path)
 
         if p:
             raise ParseError("Error parsing .tex file: %s" % tex_path)
 
index ee3c61d..b665a34 100644 (file)
@@ -1,5 +1,5 @@
-
-from dcparser import (as_person, as_date, Field, WorkInfo, DCNS)
+# -*- coding: utf-8 -*-
+from dcparser import Field, WorkInfo, DCNS
 from librarian import (RDFNS, ValidationError, NoDublinCore, ParseError, WLURI)
 from xml.parsers.expat import ExpatError
 from os import path
 from librarian import (RDFNS, ValidationError, NoDublinCore, ParseError, WLURI)
 from xml.parsers.expat import ExpatError
 from os import path
@@ -10,14 +10,14 @@ import re
 
 
 class WLPictureURI(WLURI):
 
 
 class WLPictureURI(WLURI):
-    _re_wl_uri = re.compile('http://wolnelektury.pl/katalog/obraz/'
-            '(?P<slug>[-a-z0-9]+)/?$')
+    _re_wl_uri = re.compile('http://wolnelektury.pl/katalog/obraz/(?P<slug>[-a-z0-9]+)/?$')
 
     @classmethod
     def from_slug(cls, slug):
         uri = 'http://wolnelektury.pl/katalog/obraz/%s/' % slug
         return cls(uri)
 
 
     @classmethod
     def from_slug(cls, slug):
         uri = 'http://wolnelektury.pl/katalog/obraz/%s/' % slug
         return cls(uri)
 
+
 def as_wlpictureuri_strict(text):
     return WLPictureURI.strict(text)
 
 def as_wlpictureuri_strict(text):
     return WLPictureURI.strict(text)
 
@@ -36,15 +36,15 @@ class PictureInfo(WorkInfo):
         Field(DCNS('description.medium'), 'medium', required=False),
         Field(DCNS('description.dimensions'), 'original_dimensions', required=False),
         Field(DCNS('format'), 'mime_type', required=False),
         Field(DCNS('description.medium'), 'medium', required=False),
         Field(DCNS('description.dimensions'), 'original_dimensions', required=False),
         Field(DCNS('format'), 'mime_type', required=False),
-        Field(DCNS('identifier.url'), 'url', WLPictureURI,
-            strict=as_wlpictureuri_strict),
-        )
+        Field(DCNS('identifier.url'), 'url', WLPictureURI, strict=as_wlpictureuri_strict),
+    )
 
 
 class ImageStore(object):
 
 
 class ImageStore(object):
-    EXT = ['gif', 'jpeg', 'png', 'swf', 'psd', 'bmp'
-            'tiff', 'tiff', 'jpc', 'jp2', 'jpf', 'jb2', 'swc',
-            'aiff', 'wbmp', 'xbm']
+    EXT = [
+        'gif', 'jpeg', 'png', 'swf', 'psd', 'bmp'
+        'tiff', 'tiff', 'jpc', 'jp2', 'jpf', 'jb2', 'swc',
+        'aiff', 'wbmp', 'xbm']
     MIME = ['image/gif', 'image/jpeg', 'image/png',
             'application/x-shockwave-flash', 'image/psd', 'image/bmp',
             'image/tiff', 'image/tiff', 'application/octet-stream',
     MIME = ['image/gif', 'image/jpeg', 'image/png',
             'application/x-shockwave-flash', 'image/psd', 'image/bmp',
             'image/tiff', 'image/tiff', 'application/octet-stream',
@@ -53,7 +53,7 @@ class ImageStore(object):
 
     def __init__(self, dir_):
         self.dir = dir_
 
     def __init__(self, dir_):
         self.dir = dir_
-        return super(ImageStore, self).__init__()
+        super(ImageStore, self).__init__()
 
     def path(self, slug, mime_type):
         """
 
     def path(self, slug, mime_type):
         """
@@ -94,20 +94,16 @@ class WLPicture(object):
         else:
             self.picture_info = None
 
         else:
             self.picture_info = None
 
-    @classmethod
-    def from_string(cls, xml, *args, **kwargs):
-        return cls.from_file(StringIO(xml), *args, **kwargs)
-
     @classmethod
     def from_file(cls, xmlfile, parse_dublincore=True, image_store=None):
 
         # first, prepare for parsing
         if isinstance(xmlfile, basestring):
     @classmethod
     def from_file(cls, xmlfile, parse_dublincore=True, image_store=None):
 
         # first, prepare for parsing
         if isinstance(xmlfile, basestring):
-            file = open(xmlfile, 'rb')
+            xmlfile = open(xmlfile, 'rb')
             try:
             try:
-                data = file.read()
+                data = xmlfile.read()
             finally:
             finally:
-                file.close()
+                xmlfile.close()
         else:
             data = xmlfile.read()
 
         else:
             data = xmlfile.read()
 
@@ -121,7 +117,7 @@ class WLPicture(object):
             image_store = ImageStore(path.dirname(xmlfile.name))
 
         try:
             image_store = ImageStore(path.dirname(xmlfile.name))
 
         try:
-            parser = etree.XMLParser(remove_blank_text=False)
+            parser = etree.XMLParser()
             tree = etree.parse(StringIO(data.encode('utf-8')), parser)
 
             return cls(tree, parse_dublincore=parse_dublincore, image_store=image_store)
             tree = etree.parse(StringIO(data.encode('utf-8')), parser)
 
             return cls(tree, parse_dublincore=parse_dublincore, image_store=image_store)
@@ -152,14 +148,11 @@ class WLPicture(object):
         Iterates the parts of this picture and returns them and their metadata
         """
         for part in self.edoc.iter("div"):
         Iterates the parts of this picture and returns them and their metadata
         """
         for part in self.edoc.iter("div"):
-            pd = {}
-            pd['type'] = part.get('type')
+            pd = {'themes': [], 'object': None, 'type': part.get('type')}
             if pd['type'] == 'area':
                 pd['coords'] = ((int(part.get('x1')), int(part.get('y1'))),
                                 (int(part.get('x2')), int(part.get('y2'))))
 
             if pd['type'] == 'area':
                 pd['coords'] = ((int(part.get('x1')), int(part.get('y1'))),
                                 (int(part.get('x2')), int(part.get('y2'))))
 
-            pd['themes'] = []
-            pd['object'] = None
             parent = part
             while True:
                 parent = parent.getparent()
             parent = part
             while True:
                 parent = parent.getparent()
index 16a2141..163d11c 100644 (file)
@@ -251,7 +251,7 @@ class EduModule(Xmill):
                     subgen = EduModule(self.options)
                     definiens_s = subgen.generate(definiens)
             else:
                     subgen = EduModule(self.options)
                     definiens_s = subgen.generate(definiens)
             else:
-                print "!! Missing definiendum in source: '%s'" % element.text
+                print ("!! Missing definiendum in source: '%s'" % element.text).encode('utf-8')
 
         return u"<dt id='%s'>" % self.naglowek_to_anchor(element), u"</dt>" + definiens_s
 
 
         return u"<dt id='%s'>" % self.naglowek_to_anchor(element), u"</dt>" + definiens_s
 
index bb2881f..9851cb1 100644 (file)
@@ -18,8 +18,7 @@ from urllib2 import urlopen
 
 from lxml import etree
 
 
 from lxml import etree
 
-from xmlutils import Xmill, tag, tagged, ifoption, tag_open_close
-from librarian.dcparser import Person
+from xmlutils import Xmill, ifoption, tag_open_close
 from librarian import DCNS, get_resource, IOFile
 from librarian import functions
 from pdf import PDFFormat, substitute_hyphens, fix_hanging
 from librarian import DCNS, get_resource, IOFile
 from librarian import functions
 from pdf import PDFFormat, substitute_hyphens, fix_hanging
@@ -33,7 +32,8 @@ def escape(really):
             prefix = (u'<TeXML escape="%d">' % (really and 1 or 0))
             postfix = u'</TeXML>'
             if isinstance(value, list):
             prefix = (u'<TeXML escape="%d">' % (really and 1 or 0))
             postfix = u'</TeXML>'
             if isinstance(value, list):
-                import pdb; pdb.set_trace()
+                import pdb
+                pdb.set_trace()
             if isinstance(value, tuple):
                 return prefix + value[0], value[1] + postfix
             else:
             if isinstance(value, tuple):
                 return prefix + value[0], value[1] + postfix
             else:
@@ -87,16 +87,15 @@ class EduModule(Xmill):
         return values
 
     def handle_rdf__RDF(self, _):
         return values
 
     def handle_rdf__RDF(self, _):
-        "skip metadata in generation"
+        """skip metadata in generation"""
         return
 
     @escape(True)
     def get_rightsinfo(self, element):
         rights_lic = self.get_dc(element, 'rights.license', True)
         return
 
     @escape(True)
     def get_rightsinfo(self, element):
         rights_lic = self.get_dc(element, 'rights.license', True)
-        return u'<cmd name="rightsinfostr">' + \
-          (rights_lic and u'<opt>%s</opt>' % rights_lic or '') +\
-          u'<parm>%s</parm>' % self.get_dc(element, 'rights', True) +\
-          u'</cmd>'
+        return u'<cmd name="rightsinfostr">' + (rights_lic and u'<opt>%s</opt>' % rights_lic or '') + \
+            u'<parm>%s</parm>' % self.get_dc(element, 'rights', True) + \
+            u'</cmd>'
 
     @escape(True)
     def get_authors(self, element, which=None):
 
     @escape(True)
     def get_authors(self, element, which=None):
@@ -116,31 +115,31 @@ class EduModule(Xmill):
     def handle_utwor(self, element):
         lines = [
             u'''
     def handle_utwor(self, element):
         lines = [
             u'''
-    <TeXML xmlns="http://getfo.sourceforge.net/texml/ns1">
-        <TeXML escape="0">
-        \\documentclass[%s]{wl}
-        \\usepackage{style}''' % self.options['customization_str'],
-    self.options['has_cover'] and '\usepackage{makecover}',
-    (self.options['morefloats'] == 'new' and '\usepackage[maxfloats=64]{morefloats}') or
-    (self.options['morefloats'] == 'old' and '\usepackage{morefloats}') or
-    (self.options['morefloats'] == 'none' and
-     u'''\\IfFileExists{morefloats.sty}{
-            \\usepackage{morefloats}
-        }{}'''),
-    u'''\\def\\authors{%s}''' % self.get_authors(element),
-    u'''\\def\\authorsexpert{%s}''' % self.get_authors(element, 'expert'),
-    u'''\\def\\authorsscenario{%s}''' % self.get_authors(element, 'scenario'),
-    u'''\\def\\authorstextbook{%s}''' % self.get_authors(element, 'textbook'),
-    
-    u'''\\author{\\authors}''',
-    u'''\\title{%s}''' % self.get_title(element),
-    u'''\\def\\bookurl{%s}''' % self.options['wldoc'].book_info.url.canonical(),
-    u'''\\def\\rightsinfo{%s}''' % self.get_rightsinfo(element),
-    u'</TeXML>']
+                <TeXML xmlns="http://getfo.sourceforge.net/texml/ns1">
+                <TeXML escape="0">
+                \\documentclass[%s]{wl}
+                \\usepackage{style}''' % self.options['customization_str'],
+            self.options['has_cover'] and '\usepackage{makecover}',
+            (self.options['morefloats'] == 'new' and '\usepackage[maxfloats=64]{morefloats}') or
+            (self.options['morefloats'] == 'old' and '\usepackage{morefloats}') or
+            (self.options['morefloats'] == 'none' and
+                u'''\\IfFileExists{morefloats.sty}{
+                \\usepackage{morefloats}
+                }{}'''),
+            u'''\\def\\authors{%s}''' % self.get_authors(element),
+            u'''\\def\\authorsexpert{%s}''' % self.get_authors(element, 'expert'),
+            u'''\\def\\authorsscenario{%s}''' % self.get_authors(element, 'scenario'),
+            u'''\\def\\authorstextbook{%s}''' % self.get_authors(element, 'textbook'),
+
+            u'''\\author{\\authors}''',
+            u'''\\title{%s}''' % self.get_title(element),
+            u'''\\def\\bookurl{%s}''' % self.options['wldoc'].book_info.url.canonical(),
+            u'''\\def\\rightsinfo{%s}''' % self.get_rightsinfo(element),
+            u'</TeXML>'
+        ]
 
         return u"".join(filter(None, lines)), u'</TeXML>'
 
 
         return u"".join(filter(None, lines)), u'</TeXML>'
 
-
     @escape(1)
     def handle_powiesc(self, element):
         return u"""
     @escape(1)
     def handle_powiesc(self, element):
         return u"""
@@ -154,45 +153,42 @@ class EduModule(Xmill):
         return u'<TeXML escape="1"><cmd name="%s"><parm>' % cmd, u'</parm></cmd></TeXML>'
 
     handle_akap = \
         return u'<TeXML escape="1"><cmd name="%s"><parm>' % cmd, u'</parm></cmd></TeXML>'
 
     handle_akap = \
-    handle_akap = \
-    handle_akap_cd = \
-    handle_akap_cd = \
-    handle_akap_dialog = \
-    handle_akap_dialog = \
-    handle_autor_utworu = \
-    handle_dedykacja = \
-    handle_didaskalia = \
-    handle_didask_tekst = \
-    handle_dlugi_cytat = \
-    handle_dzielo_nadrzedne = \
-    handle_lista_osoba = \
-    handle_mat = \
-    handle_miejsce_czas = \
-    handle_motto = \
-    handle_motto_podpis = \
-    handle_naglowek_akt = \
-    handle_naglowek_czesc = \
-    handle_naglowek_listy = \
-    handle_naglowek_osoba = \
-    handle_naglowek_scena = \
-    handle_nazwa_utworu = \
-    handle_nota = \
-    handle_osoba = \
-    handle_pa = \
-    handle_pe = \
-    handle_podtytul = \
-    handle_poezja_cyt = \
-    handle_pr = \
-    handle_pt = \
-    handle_sekcja_asterysk = \
-    handle_sekcja_swiatlo = \
-    handle_separator_linia = \
-    handle_slowo_obce = \
-    handle_srodtytul = \
-    handle_tytul_dziela = \
-    handle_wyroznienie = \
-    handle_dywiz = \
-    handle_texcommand
+        handle_akap_cd = \
+        handle_akap_dialog = \
+        handle_autor_utworu = \
+        handle_dedykacja = \
+        handle_didaskalia = \
+        handle_didask_tekst = \
+        handle_dlugi_cytat = \
+        handle_dzielo_nadrzedne = \
+        handle_lista_osoba = \
+        handle_mat = \
+        handle_miejsce_czas = \
+        handle_motto = \
+        handle_motto_podpis = \
+        handle_naglowek_akt = \
+        handle_naglowek_czesc = \
+        handle_naglowek_listy = \
+        handle_naglowek_osoba = \
+        handle_naglowek_scena = \
+        handle_nazwa_utworu = \
+        handle_nota = \
+        handle_osoba = \
+        handle_pa = \
+        handle_pe = \
+        handle_podtytul = \
+        handle_poezja_cyt = \
+        handle_pr = \
+        handle_pt = \
+        handle_sekcja_asterysk = \
+        handle_sekcja_swiatlo = \
+        handle_separator_linia = \
+        handle_slowo_obce = \
+        handle_srodtytul = \
+        handle_tytul_dziela = \
+        handle_wyroznienie = \
+        handle_dywiz = \
+        handle_texcommand
 
     def handle_naglowek_rozdzial(self, element):
         if not self.options['teacher']:
 
     def handle_naglowek_rozdzial(self, element):
         if not self.options['teacher']:
@@ -220,6 +216,7 @@ class EduModule(Xmill):
 
     def handle_uwaga(self, _e):
         return None
 
     def handle_uwaga(self, _e):
         return None
+
     def handle_extra(self, _e):
         return None
 
     def handle_extra(self, _e):
         return None
 
@@ -247,13 +244,16 @@ class EduModule(Xmill):
             opis = ''
 
         n = element.xpath('wskazowki')
             opis = ''
 
         n = element.xpath('wskazowki')
-        if n: wskazowki = submill.generate(n[0])
-
-        else: wskazowki = ''
+        if n:
+            wskazowki = submill.generate(n[0])
+        else:
+            wskazowki = ''
         n = element.xpath('pomoce')
 
         n = element.xpath('pomoce')
 
-        if n: pomoce = submill.generate(n[0])
-        else: pomoce = ''
+        if n:
+            pomoce = submill.generate(n[0])
+        else:
+            pomoce = ''
 
         forma = ''.join(element.xpath('forma/text()'))
 
 
         forma = ''.join(element.xpath('forma/text()'))
 
@@ -296,7 +296,7 @@ class EduModule(Xmill):
     def handle_forma(self, *_):
         return
 
     def handle_forma(self, *_):
         return
 
-    def handle_lista(self, element, attrs={}):
+    def handle_lista(self, element, attrs=None):
         ltype = element.attrib.get('typ', 'punkt')
         if not element.findall("punkt"):
             if ltype == 'czytelnia':
         ltype = element.attrib.get('typ', 'punkt')
         if not element.findall("punkt"):
             if ltype == 'czytelnia':
@@ -309,13 +309,15 @@ class EduModule(Xmill):
                 # print '** missing src on <slowniczek>, setting default'
                 surl = 'http://edukacjamedialna.edu.pl/lekcje/slowniczek/'
             sxml = etree.fromstring(self.options['wldoc'].provider.by_uri(surl).get_string())
                 # print '** missing src on <slowniczek>, setting default'
                 surl = 'http://edukacjamedialna.edu.pl/lekcje/slowniczek/'
             sxml = etree.fromstring(self.options['wldoc'].provider.by_uri(surl).get_string())
-            self.options = {'slowniczek': True, 'slowniczek_xml': sxml }
+            self.options = {'slowniczek': True, 'slowniczek_xml': sxml}
 
 
-        listcmd = {'num': 'enumerate',
-               'punkt': 'itemize',
-               'alfa': 'itemize',
-               'slowniczek': 'itemize',
-               'czytelnia': 'itemize'}[ltype]
+        listcmd = {
+            'num': 'enumerate',
+            'punkt': 'itemize',
+            'alfa': 'itemize',
+            'slowniczek': 'itemize',
+            'czytelnia': 'itemize'
+        }[ltype]
 
         return u'<env name="%s">' % listcmd, u'</env>'
 
 
         return u'<env name="%s">' % listcmd, u'</env>'
 
@@ -334,7 +336,7 @@ class EduModule(Xmill):
 
         typ = element.attrib['typ']
         self.exercise_counter += 1
 
         typ = element.attrib['typ']
         self.exercise_counter += 1
-        if not typ in exercise_handlers:
+        if typ not in exercise_handlers:
             return '(no handler)'
         self.options = {'exercise_counter': self.exercise_counter}
         handler = exercise_handlers[typ](self.options, self.state)
             return '(no handler)'
         self.options = {'exercise_counter': self.exercise_counter}
         handler = exercise_handlers[typ](self.options, self.state)
@@ -376,14 +378,13 @@ class EduModule(Xmill):
                 max_col = len(ks)
         self.options = {'columnts': max_col}
         # styling:
                 max_col = len(ks)
         self.options = {'columnts': max_col}
         # styling:
-                #        has_frames = int(element.attrib.get("ramki", "0"))
-                #        if has_frames: frames_c = "framed"
-                #        else: frames_c = ""
-                #        return u"""<table class="%s">""" % frames_c, u"</table>"
+        #     has_frames = int(element.attrib.get("ramki", "0"))
+        #     if has_frames: frames_c = "framed"
+        #     else: frames_c = ""
+        #     return u"""<table class="%s">""" % frames_c, u"</table>"
         return u'''
 <cmd name="begin"><parm>tabular</parm><parm>%s</parm></cmd>
         return u'''
 <cmd name="begin"><parm>tabular</parm><parm>%s</parm></cmd>
-    ''' % ('l' * max_col), \
-    u'''<cmd name="end"><parm>tabular</parm></cmd>'''
+    ''' % ('l' * max_col), u'''<cmd name="end"><parm>tabular</parm></cmd>'''
 
     @escape(1)
     def handle_wiersz(self, element):
 
     @escape(1)
     def handle_wiersz(self, element):
@@ -424,8 +425,7 @@ class EduModule(Xmill):
             print '!! unknown <video> url scheme:', url
             return
         name = m.group(1)
             print '!! unknown <video> url scheme:', url
             return
         name = m.group(1)
-        thumb = IOFile.from_string(urlopen
-            ("http://img.youtube.com/vi/%s/0.jpg" % name).read())
+        thumb = IOFile.from_string(urlopen("http://img.youtube.com/vi/%s/0.jpg" % name).read())
         img_path = "video/%s.jpg" % name.replace("_", "")
         self.options['format'].attachments[img_path] = thumb
         canon_url = "https://www.youtube.com/watch?v=%s" % name
         img_path = "video/%s.jpg" % name.replace("_", "")
         self.options['format'].attachments[img_path] = thumb
         canon_url = "https://www.youtube.com/watch?v=%s" % name
@@ -436,6 +436,7 @@ class Exercise(EduModule):
     def __init__(self, *args, **kw):
         self.question_counter = 0
         super(Exercise, self).__init__(*args, **kw)
     def __init__(self, *args, **kw):
         self.question_counter = 0
         super(Exercise, self).__init__(*args, **kw)
+        self.piece_counter = None
 
     handle_rozw_kom = ifoption(teacher=True)(cmd('akap'))
 
 
     handle_rozw_kom = ifoption(teacher=True)(cmd('akap'))
 
@@ -457,7 +458,7 @@ class Exercise(EduModule):
         # Add a single <pytanie> tag if it's not there
         if not element.xpath(".//pytanie"):
             qpre, qpost = self.handle_pytanie(element)
         # Add a single <pytanie> tag if it's not there
         if not element.xpath(".//pytanie"):
             qpre, qpost = self.handle_pytanie(element)
-            pre = pre + qpre
+            pre += qpre
             post = qpost + post
         return pre, post
 
             post = qpost + post
         return pre, post
 
@@ -493,7 +494,6 @@ class Exercise(EduModule):
             return self.solution_header() + etree.tostring(par)
 
 
             return self.solution_header() + etree.tostring(par)
 
 
-
 class Wybor(Exercise):
     def handle_cwiczenie(self, element):
         pre, post = super(Wybor, self).handle_cwiczenie(element)
 class Wybor(Exercise):
     def handle_cwiczenie(self, element):
         pre, post = super(Wybor, self).handle_cwiczenie(element)
@@ -508,7 +508,8 @@ class Wybor(Exercise):
                 break
             choices = p.xpath(".//*[@nazwa]")
             uniq = set()
                 break
             choices = p.xpath(".//*[@nazwa]")
             uniq = set()
-            for n in choices: uniq.add(n.attrib.get('nazwa', ''))
+            for n in choices:
+                uniq.add(n.attrib.get('nazwa', ''))
             if len(choices) != len(uniq):
                 is_single_choice = False
                 break
             if len(choices) != len(uniq):
                 is_single_choice = False
                 break
@@ -608,18 +609,19 @@ class PrawdaFalsz(Exercise):
         return pre, post
 
 
         return pre, post
 
 
-
 def fix_lists(tree):
     lists = tree.xpath(".//lista")
     for l in lists:
         if l.text:
             p = l.getprevious()
             if p is not None:
 def fix_lists(tree):
     lists = tree.xpath(".//lista")
     for l in lists:
         if l.text:
             p = l.getprevious()
             if p is not None:
-                if p.tail is None: p.tail = ''
+                if p.tail is None:
+                    p.tail = ''
                 p.tail += l.text
             else:
                 p = l.getparent()
                 p.tail += l.text
             else:
                 p = l.getparent()
-                if p.text is None: p.text = ''
+                if p.text is None:
+                    p.text = ''
                 p.text += l.text
             l.text = ''
     return tree
                 p.text += l.text
             l.text = ''
     return tree
@@ -652,4 +654,3 @@ class EduModulePDFFormat(PDFFormat):
 
     def get_image(self, name):
         return self.wldoc.source.attachments[name]
 
     def get_image(self, name):
         return self.wldoc.source.attachments[name]
-
index 8181890..ce85d12 100644 (file)
@@ -101,20 +101,17 @@ class WLCover(Cover):
                  font=self.author_font,
                  line_height=self.author_lineskip,
                  color=self.author_color,
                  font=self.author_font,
                  line_height=self.author_lineskip,
                  color=self.author_color,
-                 shadow_color=self.author_shadow,
-                )
+                 shadow_color=self.author_shadow)
 
         box.skip(10)
 
         box.skip(10)
-        box.draw.line((75, box.height, 275, box.height),
-                fill=self.author_color, width=2)
+        box.draw.line((75, box.height, 275, box.height), fill=self.author_color, width=2)
         box.skip(15)
 
         box.text(self.pretty_title(),
                  line_height=self.title_lineskip,
                  font=self.title_font,
                  color=epoch_color,
         box.skip(15)
 
         box.text(self.pretty_title(),
                  line_height=self.title_lineskip,
                  font=self.title_font,
                  color=epoch_color,
-                 shadow_color=self.title_shadow,
-                )
+                 shadow_color=self.title_shadow)
         box_img = box.image()
 
         if self.kind == 'Liryka':
         box_img = box.image()
 
         if self.kind == 'Liryka':
@@ -127,9 +124,9 @@ class WLCover(Cover):
             # center
             box_top = (self.height - box_img.size[1]) / 2
 
             # center
             box_top = (self.height - box_img.size[1]) / 2
 
-        box_left = self.bar_width + (self.width - self.bar_width -
-                        box_img.size[0]) / 2
-        draw.rectangle((box_left, box_top,
+        box_left = self.bar_width + (self.width - self.bar_width - box_img.size[0]) / 2
+        draw.rectangle((
+            box_left, box_top,
             box_left + box_img.size[0], box_top + box_img.size[1]),
             fill='#fff')
         img.paste(box_img, (box_left, box_top), box_img)
             box_left + box_img.size[0], box_top + box_img.size[1]),
             fill='#fff')
         img.paste(box_img, (box_left, box_top), box_img)
diff --git a/librarian/styles/wolnelektury/pdf.py b/librarian/styles/wolnelektury/pdf.py
deleted file mode 100644 (file)
index 6a43b0e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-import shutil
-from librarian import get_resource
-from librarian.pdf import PDFFormat
-from librarian.styles.wolnelektury.cover import WLCover
-
-class WLPDFFormat(PDFFormat):
-    cover_class = WLCover
-    style = get_resource('res/styles/wolnelektury/pdf/wolnelektury.sty')
-
-    def get_tex_dir(self):
-        temp = super(WLPDFFormat, self).get_tex_dir()
-        shutil.copy(get_resource('res/wl-logo.png'), temp)
-        return temp
index 70f5f01..c86b3f8 100644 (file)
@@ -29,6 +29,7 @@ Utwór opracowany został w ramach projektu Wolne Lektury przez fundację Nowocz
 %(description)s%(contributors)s
 """
 
 %(description)s%(contributors)s
 """
 
+
 def transform(wldoc, flags=None, **options):
     """
     Transforms input_file in XML to output_file in TXT.
 def transform(wldoc, flags=None, **options):
     """
     Transforms input_file in XML to output_file in TXT.
@@ -53,21 +54,28 @@ def transform(wldoc, flags=None, **options):
             parsed_dc = document.book_info
             description = parsed_dc.description
             url = document.book_info.url
             parsed_dc = document.book_info
             description = parsed_dc.description
             url = document.book_info.url
-    
+
             license_description = parsed_dc.license_description
             license = parsed_dc.license
             if license:
             license_description = parsed_dc.license_description
             license = parsed_dc.license
             if license:
-                license_description = u"Ten utwór jest udostepniony na licencji %s: \n%s" % (license_description, license)        
+                license_description = u"Ten utwór jest udostepniony na licencji %s: \n%s" % \
+                                      (license_description, license)
             else:
             else:
-                license_description = u"Ten utwór nie jest chroniony prawem autorskim i znajduje się w domenie publicznej, co oznacza że możesz go swobodnie wykorzystywać, publikować i rozpowszechniać. Jeśli utwór opatrzony jest dodatkowymi materiałami (przypisy, motywy literackie etc.), które podlegają prawu autorskiemu, to te dodatkowe materiały udostępnione są na licencji Creative Commons Uznanie Autorstwa – Na Tych Samych Warunkach 3.0 PL (http://creativecommons.org/licenses/by-sa/3.0/)"
-    
+                license_description = (
+                    u"Ten utwór nie jest chroniony prawem autorskim i znajduje się w domenie publicznej, "
+                    u"co oznacza że możesz go swobodnie wykorzystywać, publikować i rozpowszechniać. "
+                    u"Jeśli utwór opatrzony jest dodatkowymi materiałami (przypisy, motywy literackie etc.), "
+                    u"które podlegają prawu autorskiemu, to te dodatkowe materiały udostępnione są na licencji "
+                    u"Creative Commons Uznanie Autorstwa – Na Tych Samych Warunkach 3.0 PL "
+                    u"(http://creativecommons.org/licenses/by-sa/3.0/)")
+
             source = parsed_dc.source_name
             if source:
                 source = "\n\nTekst opracowany na podstawie: " + source
             else:
                 source = ''
             source = parsed_dc.source_name
             if source:
                 source = "\n\nTekst opracowany na podstawie: " + source
             else:
                 source = ''
-    
-            contributors = ', '.join(person.readable() for person in 
+
+            contributors = ', '.join(person.readable() for person in
                                      sorted(set(p for p in (parsed_dc.technical_editors + parsed_dc.editors) if p)))
             if contributors:
                 contributors = "\n\nOpracowanie redakcyjne i przypisy: %s" % contributors
                                      sorted(set(p for p in (parsed_dc.technical_editors + parsed_dc.editors) if p)))
             if contributors:
                 contributors = "\n\nOpracowanie redakcyjne i przypisy: %s" % contributors
@@ -88,4 +96,3 @@ def transform(wldoc, flags=None, **options):
         }).encode('utf-8'))
     else:
         return IOFile.from_string(unicode(result).encode('utf-8'))
         }).encode('utf-8'))
     else:
         return IOFile.from_string(unicode(result).encode('utf-8'))
-
index bbcc884..ae3512a 100644 (file)
@@ -41,7 +41,6 @@ class Xmill(object):
             output = flt(output)
         return output
 
             output = flt(output)
         return output
 
-
     def generate(self, document):
         """Generate text from node using handlers defined in class."""
         output = self._handle_element(document)
     def generate(self, document):
         """Generate text from node using handlers defined in class."""
         output = self._handle_element(document)
@@ -61,18 +60,17 @@ class Xmill(object):
         """
         self._options.append(opts)
 
         """
         self._options.append(opts)
 
-
     def _handle_for_element(self, element):
         ns = None
         tagname = None
     def _handle_for_element(self, element):
         ns = None
         tagname = None
-#        from nose.tools import set_trace
+        # from nose.tools import set_trace
 
         if element.tag[0] == '{':
             for nshort, nhref in element.nsmap.items():
                 try:
                     if element.tag.index('{%s}' % nhref) == 0:
                         ns = nshort
 
         if element.tag[0] == '{':
             for nshort, nhref in element.nsmap.items():
                 try:
                     if element.tag.index('{%s}' % nhref) == 0:
                         ns = nshort
-                        tagname  = element.tag[len('{%s}' % nhref):]
+                        tagname = element.tag[len('{%s}' % nhref):]
                         break
                 except ValueError:
                     pass
                         break
                 except ValueError:
                     pass
@@ -96,19 +94,22 @@ class Xmill(object):
 
         while True:
             sibling = element.getnext()
 
         while True:
             sibling = element.getnext()
-            if sibling is not None: return sibling  # found a new branch to dig into
+            if sibling is not None:
+                return sibling  # found a new branch to dig into
             element = element.getparent()
             element = element.getparent()
-            if element is None: return None  # end of tree
+            if element is None:
+                return None  # end of tree
 
     def _handle_element(self, element):
 
     def _handle_element(self, element):
-        if isinstance(element, etree._Comment): return None
-        
+        if isinstance(element, etree._Comment):
+            return None
+
         handler = self._handle_for_element(element)
         handler = self._handle_for_element(element)
-        if self.state.get('mute') and not getattr(handler, 'unmuter', False): return None
+        if self.state.get('mute') and not getattr(handler, 'unmuter', False):
+            return None
         # How many scopes
         # How many scopes
+        options_scopes = len(self._options)
         try:
         try:
-            options_scopes = len(self._options)
-
             if handler is None:
                 pre = [self.filter_text(element.text)]
                 post = [self.filter_text(element.tail)]
             if handler is None:
                 pre = [self.filter_text(element.text)]
                 post = [self.filter_text(element.tail)]
@@ -129,19 +130,20 @@ class Xmill(object):
         finally:
             # clean up option scopes if necessary
             self._options = self._options[0:options_scopes]
         finally:
             # clean up option scopes if necessary
             self._options = self._options[0:options_scopes]
-            
+
         return out
 
 
 def tag_open_close(name_, classes_=None, **attrs):
     u"""Creates tag beginning and end.
         return out
 
 
 def tag_open_close(name_, classes_=None, **attrs):
     u"""Creates tag beginning and end.
-    
+
     >>> tag_open_close("a", "klass", x=u"ą<")
     (u'<a x="\\u0105&lt;" class="klass">', u'</a>')
 
     """
     if classes_:
     >>> tag_open_close("a", "klass", x=u"ą<")
     (u'<a x="\\u0105&lt;" class="klass">', u'</a>')
 
     """
     if classes_:
-        if isinstance(classes_, (tuple, list)): classes_ = ' '.join(classes_)
+        if isinstance(classes_, (tuple, list)):
+            classes_ = ' '.join(classes_)
         attrs['class'] = classes_
 
     e = etree.Element(name_)
         attrs['class'] = classes_
 
     e = etree.Element(name_)
@@ -151,6 +153,7 @@ def tag_open_close(name_, classes_=None, **attrs):
     pre, post = etree.tostring(e, encoding=unicode).split(u"> <")
     return pre + u">", u"<" + post
 
     pre, post = etree.tostring(e, encoding=unicode).split(u"> <")
     return pre + u">", u"<" + post
 
+
 def tag(name_, classes_=None, **attrs):
     """Returns a handler which wraps node contents in tag `name', with class attribute
     set to `classes' and other attributes according to keyword paramters
 def tag(name_, classes_=None, **attrs):
     """Returns a handler which wraps node contents in tag `name', with class attribute
     set to `classes' and other attributes according to keyword paramters
@@ -165,13 +168,16 @@ def tagged(name, classes=None, **attrs):
     set to `classes' and other attributes according to keyword paramters
     """
     if classes:
     set to `classes' and other attributes according to keyword paramters
     """
     if classes:
-        if isinstance(classes, (tuple,list)): classes = ' '.join(classes)
+        if isinstance(classes, (tuple, list)):
+            classes = ' '.join(classes)
         attrs['class'] = classes
         attrs['class'] = classes
-    a = ''.join([' %s="%s"' % (k,v) for (k,v) in attrs.items()])
+    a = ''.join([' %s="%s"' % (k, v) for (k, v) in attrs.items()])
+
     def _decor(f):
         def _wrap(self, element):
             r = f(self, element)
     def _decor(f):
         def _wrap(self, element):
             r = f(self, element)
-            if r is None: return
+            if r is None:
+                return
 
             prepend = "<%s%s>" % (name, a)
             append = "</%s>" % name
 
             prepend = "<%s%s>" % (name, a)
             append = "</%s>" % name
@@ -196,6 +202,7 @@ def ifoption(**options):
         return _handler
     return _decor
 
         return _handler
     return _decor
 
+
 def flatten(l, ltypes=(list, tuple)):
     """flatten function from BasicPropery/BasicTypes package
     """
 def flatten(l, ltypes=(list, tuple)):
     """flatten function from BasicPropery/BasicTypes package
     """
index 0a3682f..b661226 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -8,9 +8,10 @@ import os
 import os.path
 from distutils.core import setup
 
 import os.path
 from distutils.core import setup
 
+
 def whole_tree(prefix, path):
     files = []
 def whole_tree(prefix, path):
     files = []
-    for f in (f for f in os.listdir(os.path.join(prefix, path)) if not f[0]=='.'):
+    for f in (f for f in os.listdir(os.path.join(prefix, path)) if not f[0] == '.'):
         new_path = os.path.join(path, f)
         if os.path.isdir(os.path.join(prefix, new_path)):
             files.extend(whole_tree(prefix, new_path))
         new_path = os.path.join(path, f)
         if os.path.isdir(os.path.join(prefix, new_path)):
             files.extend(whole_tree(prefix, new_path))
@@ -34,9 +35,12 @@ setup(
         'librarian.styles.wolnelektury',
         'librarian.styles.wolnelektury.partners',
     ],
         'librarian.styles.wolnelektury',
         'librarian.styles.wolnelektury.partners',
     ],
-    package_data={'librarian': ['xslt/*.xslt', 'epub/*', 'mobi/*', 'pdf/*', 'fb2/*', 'fonts/*'] +
-                                whole_tree(os.path.join(os.path.dirname(__file__), 'librarian'), 'font-optimizer') +
-                                whole_tree(os.path.join(os.path.dirname(__file__), 'librarian'), 'res')},
+    package_data={
+        'librarian': (
+            ['xslt/*.xslt', 'epub/*', 'mobi/*', 'pdf/*', 'fb2/*', 'fonts/*'] +
+            whole_tree(os.path.join(os.path.dirname(__file__), 'librarian'), 'font-optimizer') +
+            whole_tree(os.path.join(os.path.dirname(__file__), 'librarian'), 'res'))
+    },
     include_package_data=True,
     install_requires=['lxml>=2.2'],
     scripts=['scripts/book2html',
     include_package_data=True,
     install_requires=['lxml>=2.2'],
     scripts=['scripts/book2html',
index ee29bc9..1e15a28 100644 (file)
@@ -45,4 +45,3 @@ def check_serialize(xml_file):
 def test_serialize():
     for fixture in get_all_fixtures('dcparser', '*.xml'):
         yield check_serialize, fixture
 def test_serialize():
     for fixture in get_all_fixtures('dcparser', '*.xml'):
         yield check_serialize, fixture
-
index faa76e7..720fec6 100644 (file)
@@ -25,7 +25,8 @@ def test_transform():
     for par in tree.findall("//p"):
         if par.text.startswith(u'Opracowanie redakcyjne i przypisy:'):
             editors_attribution = True
     for par in tree.findall("//p"):
         if par.text.startswith(u'Opracowanie redakcyjne i przypisy:'):
             editors_attribution = True
-            assert_equal(par.text.rstrip(),
+            assert_equal(
+                par.text.rstrip(),
                 u'Opracowanie redakcyjne i przypisy: '
                 u'Adam Fikcyjny, Aleksandra Sekuła, Olga Sutkowska.')
     assert_true(editors_attribution)
                 u'Opracowanie redakcyjne i przypisy: '
                 u'Adam Fikcyjny, Aleksandra Sekuła, Olga Sutkowska.')
     assert_true(editors_attribution)
index 21adfb1..9d9b1de 100644 (file)
@@ -33,6 +33,7 @@ def test_passing_parse_dublincore_to_transform():
             parse_dublincore=False,
         ).as_html()
 
             parse_dublincore=False,
         ).as_html()
 
+
 def test_empty():
     assert not WLDocument.from_string(
             '<utwor />',
 def test_empty():
     assert not WLDocument.from_string(
             '<utwor />',
index 097a65a..a422887 100644 (file)
@@ -1,14 +1,20 @@
+# -*- coding: utf-8 -*-
+#
+# This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
 import os
 import os
-from StringIO import StringIO
 from tempfile import NamedTemporaryFile
 from nose.tools import *
 from librarian import IOFile
 
 from tempfile import NamedTemporaryFile
 from nose.tools import *
 from librarian import IOFile
 
+
 def test_iofile_from_string_reusable():
     some_file = IOFile.from_string("test")
     some_file.get_file().read()
     assert_equal(some_file.get_file().read(), "test")
 
 def test_iofile_from_string_reusable():
     some_file = IOFile.from_string("test")
     some_file.get_file().read()
     assert_equal(some_file.get_file().read(), "test")
 
+
 def test_iofile_from_filename_reusable():
     temp = NamedTemporaryFile(delete=False)
     try:
 def test_iofile_from_filename_reusable():
     temp = NamedTemporaryFile(delete=False)
     try:
index 75b73bc..f604f58 100644 (file)
@@ -3,7 +3,6 @@
 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-import re
 from tempfile import NamedTemporaryFile
 from nose.tools import *
 from librarian import DirDocProvider
 from tempfile import NamedTemporaryFile
 from nose.tools import *
 from librarian import DirDocProvider
@@ -22,7 +21,6 @@ def test_transform():
     print tex
 
     # Check contributor list.
     print tex
 
     # Check contributor list.
-    editors = re.search(ur'\\def\\editors\{'
-        ur'Opracowanie redakcyjne i przypisy: ([^}]*?)\.\s*\}', tex)
-    assert_equal(editors.group(1),
-        u"Adam Fikcyjny, Aleksandra Sekuła, Olga Sutkowska")
+    editors = re.search(
+        ur'\\def\\editors\{Opracowanie redakcyjne i przypisy: ([^}]*?)\.\s*\}', tex)
+    assert_equal(editors.group(1), u"Adam Fikcyjny, Aleksandra Sekuła, Olga Sutkowska")
index f64f624..40ca21c 100644 (file)
@@ -4,21 +4,20 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from librarian import picture, dcparser
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from librarian import picture, dcparser
-from lxml import etree
 from nose.tools import *
 from nose.tools import *
-from os.path import splitext
 from tests.utils import get_all_fixtures, get_fixture
 from tests.utils import get_all_fixtures, get_fixture
-import codecs
 from os import path
 
 from os import path
 
+
 def test_wlpictureuri():
     uri = picture.WLPictureURI('http://wolnelektury.pl/katalog/obraz/angelus-novus')
 
 def test_wlpictureuri():
     uri = picture.WLPictureURI('http://wolnelektury.pl/katalog/obraz/angelus-novus')
 
+
 def check_load(xml_file):
     pi = dcparser.parse(xml_file, picture.PictureInfo)
     assert pi is not None
     assert isinstance(pi, picture.PictureInfo)
 def check_load(xml_file):
     pi = dcparser.parse(xml_file, picture.PictureInfo)
     assert pi is not None
     assert isinstance(pi, picture.PictureInfo)
-    
+
 
 def test_load():
     for fixture in get_all_fixtures('picture', '*.xml'):
 
 def test_load():
     for fixture in get_all_fixtures('picture', '*.xml'):
@@ -35,10 +34,11 @@ def test_wlpicture():
     assert wlp.slug == 'angelus-novus'
 
     assert path.exists(wlp.image_path)
     assert wlp.slug == 'angelus-novus'
 
     assert path.exists(wlp.image_path)
-    
+
     f = wlp.image_file('r')
     f.close()
 
     f = wlp.image_file('r')
     f.close()
 
+
 def test_picture_parts():
     wlp = picture.WLPicture.from_file(open(get_fixture('picture', 'angelus-novus.xml')))
     parts = list(wlp.partiter())
 def test_picture_parts():
     wlp = picture.WLPicture.from_file(open(get_fixture('picture', 'angelus-novus.xml')))
     parts = list(wlp.partiter())
@@ -54,7 +54,5 @@ def test_picture_parts():
         if p['object']:
             names.add(p['object'])
 
         if p['object']:
             names.add(p['object'])
 
-    assert motifs == set([u'anioł historii', u'spojrzenie']), "missing motifs, got: %s" % motifs
-    assert names == set([u'obraz cały', u'skrzydło']), 'missing objects, got: %s' % names
-    
-        
+    assert motifs == {u'anioł historii', u'spojrzenie'}, "missing motifs, got: %s" % motifs
+    assert names == {u'obraz cały', u'skrzydło'}, 'missing objects, got: %s' % names
index 319baa7..0de2624 100644 (file)
@@ -1,10 +1,11 @@
-
+# -*- coding: utf-8 -*-
 from librarian import xmlutils
 from lxml import etree
 from librarian.pyhtml import EduModule
 from nose.tools import *
 from tests.utils import get_fixture
 
 from librarian import xmlutils
 from lxml import etree
 from librarian.pyhtml import EduModule
 from nose.tools import *
 from tests.utils import get_fixture
 
+
 def test_traversal():
     xml = etree.fromstring("<a><b>BBBB</b><c>CCCC</c></a>")
     hg = xmlutils.Xmill()
 def test_traversal():
     xml = etree.fromstring("<a><b>BBBB</b><c>CCCC</c></a>")
     hg = xmlutils.Xmill()
@@ -13,7 +14,6 @@ def test_traversal():
     assert_equals(hg.next(xml[1]), None)
 
 
     assert_equals(hg.next(xml[1]), None)
 
 
-
 class Foo(xmlutils.Xmill):
     def __init__(self):
         super(Foo, self).__init__()
 class Foo(xmlutils.Xmill):
     def __init__(self):
         super(Foo, self).__init__()
@@ -27,24 +27,23 @@ class Foo(xmlutils.Xmill):
 
     def handle_song(self, ele):
         if ele.getnext() is not None:
 
     def handle_song(self, ele):
         if ele.getnext() is not None:
-            return "\n","--------------------\n"
-
+            return "\n", "--------------------\n"
 
 
 def test_xml_generation():
     xml = u"""<root>
 
 
 def test_xml_generation():
     xml = u"""<root>
-<songs>
-<song>
-<title>Oursoul</title>
-<artist>Hindi Zahra</artist>
-</song>
-<song>
-<title>Visitor</title>
-<artist>Portico Quartet</artist>
-</song>
-</songs>
-</root>
-"""
+        <songs>
+        <song>
+        <title>Oursoul</title>
+        <artist>Hindi Zahra</artist>
+        </song>
+        <song>
+        <title>Visitor</title>
+        <artist>Portico Quartet</artist>
+        </song>
+        </songs>
+        </root>
+    """
     txt = Foo().generate(etree.fromstring(xml))
     print txt
 
     txt = Foo().generate(etree.fromstring(xml))
     print txt
 
index 3b1f4f5..fc87532 100644 (file)
@@ -6,7 +6,7 @@
 from __future__ import with_statement
 from os.path import realpath, join, dirname
 import glob
 from __future__ import with_statement
 from os.path import realpath, join, dirname
 import glob
-import os
+
 
 def get_fixture_dir(dir_name):
     """Returns path to fixtures directory dir_name."""
 
 def get_fixture_dir(dir_name):
     """Returns path to fixtures directory dir_name."""