from six.moves.urllib.request import FancyURLopener
from .util import makedirs
+# Compatibility imports.
+from .meta.types.wluri import WLURI
+
@six.python_2_unicode_compatible
class UnicodeException(Exception):
XMLNS = XMLNamespace('http://www.w3.org/XML/1998/namespace')
RDFNS = XMLNamespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
DCNS = XMLNamespace('http://purl.org/dc/elements/1.1/')
-XINS = XMLNamespace("http://www.w3.org/2001/XInclude")
XHTMLNS = XMLNamespace("http://www.w3.org/1999/xhtml")
-NCXNS = XMLNamespace("http://www.daisy.org/z3986/2005/ncx/")
-OPFNS = XMLNamespace("http://www.idpf.org/2007/opf")
PLMETNS = XMLNamespace("http://dl.psnc.pl/schemas/plmet/")
WLNS = EmptyNamespace()
-
-
class DocProvider(object):
"""Base class for a repository of XML files.
return open(os.path.join(self.dir, fname), 'rb')
-from . import dcparser
-from .meta.types.wluri import WLURI
-
-
-DEFAULT_BOOKINFO = dcparser.BookInfo(
- {
- RDFNS('about'): u'http://wiki.wolnepodreczniki.pl/Lektury:Template'
- },
- {
- DCNS('creator'): [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 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
-
- dcstring = etree.tostring(
- bookinfo.to_etree(), method='xml', encoding='unicode',
- pretty_print=True
- )
-
- return u'<utwor>\n' + dcstring + u'\n<plain-text>\n' + ocrtext + \
- u'\n</plain-text>\n</utwor>'
-
-
-def serialize_raw(element):
- b = u'' + (element.text or '')
-
- for child in element.iterchildren():
- e = etree.tostring(child, method='xml', encoding='unicode',
- pretty_print=True)
- b += e
-
- return b
-
-
-SERIALIZERS = {
- 'raw': serialize_raw,
-}
-
-
-def serialize_children(element, format='raw'):
- return SERIALIZERS[format](element)
-
-
def get_resource(path):
return os.path.join(os.path.dirname(__file__), path)
from librarian.fonts import strip_font
-
-
class Xhtml:
def __init__(self):
self.element = etree.XML('''<html xmlns="http://www.w3.org/1999/xhtml"><head><link rel="stylesheet" href="style.css" type="text/css"/><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>WolneLektury.pl</title></head><body/></html>''')
def forget_fragment(self, name):
del self.cursors[name]
-
-
@property
def base_url(self):
if self._base_url is not None:
class EpubBuilder(Builder):
file_extension = 'epub'
isbn_field = 'isbn_epub'
+ orphans = True
def __init__(self, *args, **kwargs):
self.chars = set()
with_footnotes = True
with_nota_red = True
no_externalities = False
+ orphans = True
def __init__(self, base_url=None):
self._base_url = base_url
file_extension = "txt"
identifier = "txt"
+ orphans = False
+
default_license_description = {
"pol": (
"Wszystkie zasoby Wolnych Lektur możesz swobodnie wykorzystywać, "
"publikować i rozpowszechniać pod warunkiem zachowania warunków "
"licencji i zgodnie z Zasadami wykorzystania Wolnych Lektur.\n"
- "Ten utwór jest w domenie publicznej. "
+ "Ten utwór jest w domenie publicznej.\n"
"Wszystkie materiały dodatkowe (przypisy, motywy literackie) są "
- "udostępnione na Licencji Wolnej Sztuki 1.3 "
- "(https://artlibre.org/licence/lal/pl/).\n"
+ "udostępnione na Licencji Wolnej Sztuki 1.3: "
+ "https://artlibre.org/licence/lal/pl/\n"
"Fundacja Nowoczesna Polska zastrzega sobie prawa do wydania "
"krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich "
- "i prawach pokrewnych. Wykorzystując zasoby z Wolnych Lektur, "
+ "i prawach pokrewnych.\nWykorzystując zasoby z Wolnych Lektur, "
"należy pamiętać o zapisach licencji oraz zasadach, które "
- "spisaliśmy w Zasadach wykorzystania Wolnych Lektur "
- "(https://wolnelektury.pl/info/zasady-wykorzystania/). Zapoznaj "
+ "spisaliśmy w Zasadach wykorzystania Wolnych Lektur: "
+ "https://wolnelektury.pl/info/zasady-wykorzystania/\nZapoznaj "
"się z nimi, zanim udostępnisz dalej nasze książki."
)
}
"licencji i zgodnie z Zasadami wykorzystania Wolnych Lektur.\n"
"Ten utwór jest jest udostępniony na licencji {meta.license_description} ({meta.license}). "
"Wszystkie materiały dodatkowe (przypisy, motywy literackie) są "
- "udostępnione na Licencji Wolnej Sztuki 1.3 "
- "(https://artlibre.org/licence/lal/pl/).\n"
+ "udostępnione na Licencji Wolnej Sztuki 1.3: "
+ "https://artlibre.org/licence/lal/pl/\n"
"Fundacja Nowoczesna Polska zastrzega sobie prawa do wydania "
"krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich "
- "i prawach pokrewnych. Wykorzystując zasoby z Wolnych Lektur, "
+ "i prawach pokrewnych.\nWykorzystując zasoby z Wolnych Lektur, "
"należy pamiętać o zapisach licencji oraz zasadach, które "
- "spisaliśmy w Zasadach wykorzystania Wolnych Lektur "
- "(https://wolnelektury.pl/info/zasady-wykorzystania/). Zapoznaj "
+ "spisaliśmy w Zasadach wykorzystania Wolnych Lektur: "
+ "https://wolnelektury.pl/info/zasady-wykorzystania/\nZapoznaj "
"się z nimi, zanim udostępnisz dalej nasze książki."
)
}
- def __init__(self):
+ def __init__(self, base_url=None):
self.fragments = {
None: TxtFragment(),
'header': TxtFragment()
from lxml.etree import XMLSyntaxError
from librarian.meta.types.bool import BoolValue
-from librarian.meta.types.date import DateValue
from librarian.meta.types.person import Person
from librarian.meta.types.wluri import WLURI
from librarian.meta.types import text
Field(DCNS('contributor.thanks'), 'thanks', required=False),
Field(DCNS('date'), 'created_at'),
- Field(DCNS('date.pd'), 'released_to_public_domain_at', DateValue,
+ Field(DCNS('date.pd'), 'released_to_public_domain_at',
required=False),
Field(DCNS('publisher'), 'publisher', multiple=True),
newt += builder.hyphenator.inserted(w, u'\u00AD')
text = newt
- text = re.sub(r'(?<=\s\w)\s+', u'\u00A0', text)
+ if builder.orphans:
+ text = re.sub(r'(?<=\s\w)\s+', u'\u00A0', text)
return text
for parent in parents:
fragment.append('start', parent)
- open_fragments[fragment.id] = fragment
+ if fragment.id not in open_fragments:
+ open_fragments[fragment.id] = fragment
# Close existing fragment
else:
+++ /dev/null
-from datetime import date
-import re
-import time
-from .base import MetaValue
-
-
-class DateValue(MetaValue):
- @classmethod
- def from_text(cls, text):
- """
- Dates for digitization of pictures. It seems we need the following:
- ranges: '1350-1450',
- centuries: "XVIII w.'
- half centuries/decades: '2 poł. XVIII w.', 'XVII w., l. 20'
- later-then: 'po 1450'
- circa 'ok. 1813-1814', 'ok.1876-ok.1886
- turn: 1893/1894
-
- For now we will translate this to some single date
- losing information of course.
- """
- try:
- # check out the "N. poł X w." syntax
- century_format = (
- "(?:([12]) *poł[.]? +)?([MCDXVI]+) *w[.,]*(?: *l[.]? *([0-9]+))?"
- )
- vague_format = "(?:po *|ok. *)?([0-9]{4})(-[0-9]{2}-[0-9]{2})?"
-
- m = re.match(century_format, text)
- m2 = re.match(vague_format, text)
- if m:
- half = m.group(1)
- decade = m.group(3)
- century = roman_to_int(m.group(2))
- if half is not None:
- if decade is not None:
- raise ValueError(
- "Bad date format. "
- "Cannot specify both half and decade of century."
- )
- half = int(half)
- t = ((century*100 + (half-1)*50), 1, 1)
- else:
- decade = int(decade or 0)
- t = ((century*100 + decade), 1, 1)
- elif m2:
- year = m2.group(1)
- mon_day = m2.group(2)
- if mon_day:
- t = time.strptime(year + mon_day, "%Y-%m-%d")
- else:
- t = time.strptime(year, '%Y')
- else:
- raise ValueError
-
- return cls(date(t[0], t[1], t[2]))
- except ValueError:
- raise ValueError("Unrecognized date format. Try YYYY-MM-DD or YYYY.")
class WLURI(MetaValue):
"""Represents a WL URI. Extracts slug from it."""
- example = 'http://wolnelektury.pl/katalog/lektura/template/'
+ template = 'http://wolnelektury.pl/katalog/lektura/%s/'
_re_wl_uri = re.compile(
r'http://(www\.)?wolnelektury.pl/katalog/lektur[ay]/'
'(?P<slug>[-a-z0-9]+)/?$'
def __init__(self, slug, uri=None):
"""Contructs an URI from slug.
- >>> print(WLURI.from_slug('a-slug').uri)
+ >>> print(WLURI('a-slug').uri)
http://wolnelektury.pl/katalog/lektura/a-slug/
"""
if uri is None:
- uri = 'http://wolnelektury.pl/katalog/lektura/%s/' % slug
+ uri = self.template % slug
self.uri = uri
return super().__init__(slug)
_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)
+ template = 'http://wolnelektury.pl/katalog/obraz/%s/'
def as_wlpictureuri_strict(text):
Utwór opracowany został w ramach projektu Wolne Lektury przez fundację Nowoczesna Polska.
-%(license_description)s.%(source)s%(publisher)s
+%(license_description)s%(source)s%(publisher)s
%(description)s%(contributors)s%(funders)s%(isbn)s
"należy pamiętać o zapisach licencji oraz zasadach, które "
"spisaliśmy w Zasadach wykorzystania Wolnych Lektur: "
"https://wolnelektury.pl/info/zasady-wykorzystania/\nZapoznaj "
- "się z nimi, zanim udostępnisz dalej nasze książki"
+ "się z nimi, zanim udostępnisz dalej nasze książki."
)
license_description = "\n".join(license_description)
'kind': u'Epika',
'source_url': u'http://www.polona.pl/dlibra/doccontent2?id=3563&dirids=4',
'translators': [u'Niewiadomska, Cecylia'],
- 'released_to_public_domain_at': u'1925-01-01',
+ 'released_to_public_domain_at': u'1925',
'epoch': u'Romantyzm',
'genre': u'Baśń',
'technical_editors': [u'Gałecki, Dariusz'],
'title': u'Pieśń VII (Trudna rada w tej mierze: przyjdzie się rozjechać...)',
'kind': u'Liryka',
'source_url': u'http://www.polona.pl/Content/1499',
- 'released_to_public_domain_at': u'1584-01-01',
+ 'released_to_public_domain_at': u'1584',
'epoch': u'Renesans',
'genre': u'Pieśń',
'technical_editors': [u'Gałecki, Dariusz'],
'title': u'Rybka',
'kind': u'Liryka',
'source_url': u'http://www.polona.pl/Content/2222',
- 'released_to_public_domain_at': u'1855-01-01',
+ 'released_to_public_domain_at': u'1855',
'epoch': u'Romantyzm',
'genre': u'Ballada',
'technical_editors': [u'Sutkowska, Olga'],
'kind': u'Dramat',
'source_url': u'http://www.polona.pl/Content/3768',
'translators': [u'Morawski, Kazimierz'],
- 'released_to_public_domain_at': u'1925-01-01',
+ 'released_to_public_domain_at': u'1925',
'epoch': u'Starożytność',
'genre': u'Tragedia',
'technical_editors': [u'Gałecki, Dariusz'],
<a name="f1" class="target"> </a><a href="#f1" class="anchor">1</a><div class="verse">Między nami <a class="theme-begin" fid="1" name="m1">Nicość</a>nic nie było!<span class="theme-end" fid="1"></span>
</div>
<div class="verse">Żadnych zwierzeń, wyznań żadnych!</div>
-<div class="verse">Nic nas z sobą nie łączyło —</div>
+<div class="verse">Nic nas z sobą nie łączyło —</div>
<div class="verse">Prócz wiosennych marzeń zdradnych;</div>
</div>
<div class="stanza" id="sec5">
<a name="f5" class="target"> </a><a href="#f5" class="anchor">5</a><div class="verse">
-<a class="theme-begin" fid="1189062528872" name="m1189062528872">Natura</a>Prócz tych woni, barw i blasków,</div>
-<div class="verse">Unoszących się w przestrzeni;</div>
+<a class="theme-begin" fid="1189062528872" name="m1189062528872">Natura</a>Prócz tych woni, barw i blasków,</div>
+<div class="verse">Unoszących się w przestrzeni;</div>
<div class="verse">Prócz szumiących śpiewem lasków</div>
<div class="verse">I tej świeżej łąk zieleni;</div>
</div>
<div class="stanza" id="sec6">
-<div class="verse">Prócz tych kaskad i potoków,</div>
+<div class="verse">Prócz tych kaskad i potoków,</div>
<a name="f10" class="target"> </a><a href="#f10" class="anchor">10</a><div class="verse">Zraszających każdy parów,</div>
<div class="verse">Prócz girlandy tęcz, obłoków,</div>
<div class="verse">Prócz natury słodkich czarów;</div>
<div class="stanza" id="sec7">
<div class="verse">Prócz tych wspólnych, jasnych zdrojów,</div>
<div class="verse">Z których serce zachwyt piło;</div>
-<a name="f15" class="target"> </a><a href="#f15" class="anchor">15</a><div class="verse">Prócz pierwiosnków i powojów,—</div>
+<a name="f15" class="target"> </a><a href="#f15" class="anchor">15</a><div class="verse">Prócz pierwiosnków i powojów,—</div>
<div class="verse">Między nami nic nie było!<span class="theme-end" fid="1189062528872"></span><span class="theme-end" fid="1189062500041"></span>
</div>
</div>
\r
Utwór opracowany został w ramach projektu Wolne Lektury przez fundację Nowoczesna Polska.\r
\r
-Ten utwór nie jest objęty majątkowym 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/).\r
+Wszystkie zasoby Wolnych Lektur możesz swobodnie wykorzystywać, publikować i rozpowszechniać pod warunkiem zachowania warunków licencji i zgodnie z Zasadami wykorzystania Wolnych Lektur.\r
+Ten utwór jest w domenie publicznej.\r
+Wszystkie materiały dodatkowe (przypisy, motywy literackie) są udostępnione na Licencji Wolnej Sztuki 1.3: https://artlibre.org/licence/lal/pl/\r
+Fundacja Nowoczesna Polska zastrzega sobie prawa do wydania krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich i prawach pokrewnych.\r
+Wykorzystując zasoby z Wolnych Lektur, należy pamiętać o zapisach licencji oraz zasadach, które spisaliśmy w Zasadach wykorzystania Wolnych Lektur: https://wolnelektury.pl/info/zasady-wykorzystania/\r
+Zapoznaj się z nimi, zanim udostępnisz dalej nasze książki.\r
\r
Tekst opracowany na podstawie: (Asnyk, Adam) El...y (1838-1897), Poezye, t. 3, Gebethner i Wolff, wyd. nowe poprzedzone słowem wstępnym St. Krzemińskiego, Warszawa, 1898\r
\r
def test_serialize():
for fixture in get_all_fixtures('dcparser', '*.xml'):
yield check_serialize, fixture
-
-
-def test_asdate():
- assert_equals(dcparser.as_date(u"2010-10-03"), date(2010, 10, 3))
- assert_equals(dcparser.as_date(u"2011"), date(2011, 1, 1))
- assert_equals(dcparser.as_date(u"2 poł. XIX w."), date(1950, 1, 1))
- assert_equals(dcparser.as_date(u"XVII w., l. 20"), date(1720, 1, 1))
- assert_equals(dcparser.as_date(u"po 1460"), date(1460, 1, 1))
- assert_equals(dcparser.as_date(u"ok. 1813-1814"), date(1813, 1, 1))
- assert_equals(dcparser.as_date(u"ok.1876-ok.1886"), date(1876, 1, 1))
- assert_equals(dcparser.as_date(u"1893/1894"), date(1893, 1, 1))
)
assert_equals(
book.get_metadata(DC, "creator"),
- [('Adam Asnyk', {"id": "creator"})]
+ [('Adam Asnyk', {"id": "creator0"})]
)
assert_equals(
book.get_metadata(DC, "publisher"),
expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_fragments.html')
closed_fragments, open_fragments = extract_fragments(
- get_fixture('text', 'asnyk_miedzy_nami_expected.html'))
+ get_fixture('text', 'asnyk_miedzy_nami_expected.legacy.html'))
assert not open_fragments
fragments_text = u"\n\n".join(u"%s: %s\n%s" % (f.id, f.themes, f) for f in sorted(closed_fragments.values(), key=lambda f: f.id))
self.assertEqual(fragments_text, open(expected_output_file_path, 'rb').read().decode('utf-8'))
#
from __future__ import unicode_literals
+import unittest
from librarian import NoDublinCore
from librarian.builders import builders
from librarian.parser import WLDocument as LegacyWLDocument
from .utils import get_fixture
-def test_transform_legacy():
- expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected.txt')
+class TextTests(unittest.TestCase):
+ maxDiff = None
- text = LegacyWLDocument.from_file(
- get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml')
- ).as_text().get_bytes()
+ def test_transform_legacy(self):
+ expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected.txt')
- assert_equal(text, open(expected_output_file_path, 'rb').read())
+ text = LegacyWLDocument.from_file(
+ get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml')
+ ).as_text().get_bytes().decode('utf-8')
+ with open(expected_output_file_path, 'rb') as f:
+ self.assertEqual(text, f.read().decode('utf-8'))
-def test_transform():
- expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected.txt')
+ def test_transform(self):
+ expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected.txt')
- text = WLDocument(
- filename=get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml')
- ).build(builders['txt']).get_bytes()
+ text = WLDocument(
+ filename=get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml')
+ ).build(builders['txt']).get_bytes().decode('utf-8')
- assert_equal(text, open(expected_output_file_path, 'rb').read())
+ with open(expected_output_file_path, 'rb') as f:
+ self.assertEqual(text, f.read().decode('utf-8'))
-def test_transform_raw():
- expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected_raw.txt')
+ def test_transform_raw(self):
+ expected_output_file_path = get_fixture('text', 'asnyk_miedzy_nami_expected_raw.txt')
- text = LegacyWLDocument.from_file(
+ text = LegacyWLDocument.from_file(
get_fixture('text', 'miedzy-nami-nic-nie-bylo.xml')
- ).as_text(flags=['raw-text']).get_bytes()
+ ).as_text(flags=['raw-text']).get_bytes().decode('utf-8')
- assert_equal(text, open(expected_output_file_path, 'rb').read())
+ with open(expected_output_file_path, 'rb') as f:
+ self.assertEqual(text, f.read().decode('utf-8'))
@raises(NoDublinCore)
[tox]
envlist =
clean,
- py{27,35,36,37,38},
+ py{36,37,38,39},
stats
[testenv]