Loading opds_catalog/FB2_22_xhtml.xsl 0 → 100644 +322 −0 Original line number Diff line number Diff line <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fb="http://www.gribuser.ru/xml/fictionbook/2.0"> <xsl:output method="xml" encoding="UTF-8"/> <xsl:key name="note-link" match="fb:section" use="@id"/> <xsl:template match="/*"> <html> <head> <xsl:if test="fb:description/fb:title-info/fb:lang = 'ru'"> <meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/> </xsl:if> <title> <xsl:value-of select="fb:description/fb:title-info/fb:book-title"/> </title> <style type="text/x-oeb1-css"> A { color : #0002CC } A:HOVER { color : #BF0000 } BODY { background-color : #FEFEFE; color : #000000; font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; text-align : justify } H1{ font-size : 160%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Black; background-color : #E7E7E7; margin-left : 0px; page-break-before : always; } H2{ font-size : 130%; font-style : normal; font-weight : bold; text-align : left; background-color : #EEEEEE; border : 1px solid Gray; page-break-before : always; } H3{ font-size : 110%; font-style : normal; font-weight : bold; text-align : left; background-color : #F1F1F1; border : 1px solid Silver;} H4{ font-size : 100%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;} H5{ font-size : 100%; font-style : italic; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;} H6{ font-size : 100%; font-style : italic; font-weight : normal; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;} SMALL{ font-size : 80% } BLOCKQUOTE{ margin-left :4em; margin-top:1em; margin-right:0.2em;} HR{ color : Black } UL{margin-left: 0} .epigraph{width:50%; margin-left : 35%;} </style> </head> <body> <h4 align="center"> <xsl:value-of select="fb:description/fb:title-info/fb:book-title"/> </h4> <xsl:for-each select="fb:description/fb:title-info/fb:coverpage/fb:image"> <xsl:call-template name="image"/> </xsl:for-each> <xsl:for-each select="fb:description/fb:title-info/fb:annotation"> <div> <xsl:call-template name="annotation"/> </div> <hr/> </xsl:for-each> <!-- BUILD TOC --> <ul> <xsl:apply-templates select="fb:body" mode="toc"/> </ul> <hr/> <!-- BUILD BOOK --> <xsl:for-each select="fb:body"> <xsl:if test="position()!=1"> <hr/> </xsl:if> <xsl:if test="@name"> <h4 align="center"> <xsl:value-of select="@name"/> </h4> </xsl:if> <!-- <xsl:apply-templates /> --> <xsl:apply-templates/> </xsl:for-each> </body> </html> </xsl:template> <!-- author template --> <xsl:template name="author"> <xsl:value-of select="fb:first-name"/> <xsl:text disable-output-escaping="no"> </xsl:text> <xsl:value-of select="fb:middle-name"/>  <xsl:text disable-output-escaping="no"> </xsl:text> <xsl:value-of select="fb:last-name"/> <br/> </xsl:template> <!-- secuence template --> <xsl:template name="sequence"> <LI/> <xsl:value-of select="@name"/> <xsl:if test="@number"> <xsl:text disable-output-escaping="no">, #</xsl:text> <xsl:value-of select="@number"/> </xsl:if> <xsl:if test="fb:sequence"> <ul> <xsl:for-each select="fb:sequence"> <xsl:call-template name="sequence"/> </xsl:for-each> </ul> </xsl:if> <!-- <br/> --> </xsl:template> <!-- toc template --> <xsl:template match="fb:section|fb:body" mode="toc"> <xsl:choose> <xsl:when test="name()='body' and position()=1 and not(fb:title)"> <xsl:apply-templates select="fb:section" mode="toc"/> </xsl:when> <xsl:otherwise> <li> <a href="#TOC_{position()}"><xsl:value-of select="normalize-space(fb:title/fb:p[1] | @name)"/></a> <xsl:if test="fb:section"> <ul><xsl:apply-templates select="fb:section" mode="toc"/></ul> </xsl:if> </li> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- description --> <xsl:template match="fb:description"> <xsl:apply-templates/> </xsl:template> <!-- body --> <xsl:template match="fb:body"> <div><xsl:apply-templates/></div> </xsl:template> <xsl:template match="fb:section" name="section"> <a name="TOC_{position()}"></a> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </xsl:template> <!-- section/title --> <xsl:template match="fb:section/fb:title|fb:poem/fb:title"> <xsl:choose> <xsl:when test="count(ancestor::node()) < 9"> <xsl:element name="{concat('h',count(ancestor::node())-3)}"> <a name="TOC_{position()}"></a> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </xsl:element> </xsl:when> <xsl:otherwise> <xsl:element name="h6"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </xsl:element> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- section/title --> <xsl:template match="fb:body/fb:title"> <h1><xsl:apply-templates mode="title"/></h1> </xsl:template> <xsl:template match="fb:title/fb:p"> <xsl:apply-templates/><xsl:text disable-output-escaping="no"> </xsl:text><br/> </xsl:template> <!-- subtitle --> <xsl:template match="fb:subtitle"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <h5> <xsl:apply-templates/> </h5> </xsl:template> <!-- p --> <xsl:template match="fb:p"> <xsl:variable name="count"> <xsl:number/> </xsl:variable> <div id="{1+count(ancestor::fb:section/preceding-sibling::fb:section)}.{$count}" align="justify"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if>    <xsl:apply-templates/> </div> </xsl:template> <!-- strong --> <xsl:template match="fb:strong"> <b><xsl:apply-templates/></b> </xsl:template> <!-- emphasis --> <xsl:template match="fb:emphasis"> <i> <xsl:apply-templates/></i> </xsl:template> <!-- style --> <xsl:template match="fb:style"> <span class="{@name}"><xsl:apply-templates/></span> </xsl:template> <!-- empty-line --> <xsl:template match="fb:empty-line"> <br/> </xsl:template> <!-- link --> <xsl:template match="fb:a"> <xsl:element name="a"> <xsl:attribute name="href"><xsl:value-of select="@xlink:href"/></xsl:attribute> <xsl:attribute name="title"> <xsl:choose> <xsl:when test="starts-with(@xlink:href,'#')"><xsl:value-of select="key('note-link',substring-after(@xlink:href,'#'))/fb:p"/></xsl:when> <xsl:otherwise><xsl:value-of select="key('note-link',@xlink:href)/fb:p"/></xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:choose> <xsl:when test="(@type) = 'note'"> <sup> <xsl:apply-templates/> </sup> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:element> </xsl:template> <!-- annotation --> <xsl:template name="annotation"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <h3>Annotation</h3> <xsl:apply-templates/> </xsl:template> <!-- epigraph --> <xsl:template match="fb:epigraph"> <blockquote class="epigraph"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </blockquote> </xsl:template> <!-- epigraph/text-author --> <xsl:template match="fb:epigraph/fb:text-author"> <blockquote> <i><xsl:apply-templates/></i> </blockquote> </xsl:template> <!-- cite --> <xsl:template match="fb:cite"> <blockquote> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </blockquote> </xsl:template> <!-- cite/text-author --> <xsl:template match="fb:text-author"> <blockquote> <i> <xsl:apply-templates/></i></blockquote> </xsl:template> <!-- date --> <xsl:template match="fb:date"> <xsl:choose> <xsl:when test="not(@value)">    <xsl:apply-templates/> <br/> </xsl:when> <xsl:otherwise>    <xsl:value-of select="@value"/> <br/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- poem --> <xsl:template match="fb:poem"> <blockquote> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </blockquote> </xsl:template> <!-- stanza --> <xsl:template match="fb:stanza"> <xsl:apply-templates/> <br/> </xsl:template> <!-- v --> <xsl:template match="fb:v"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/><br/> </xsl:template> <!-- image --> <xsl:template match="fb:image" name="image"> <div align="center"> <img border="1"> <xsl:choose> <xsl:when test="starts-with(@xlink:href,'#')"> <xsl:attribute name="src"><xsl:text>data:</xsl:text><xsl:variable name="href" select="substring-after(@xlink:href,'#')" /><set variable="href" expression="substring-after(@xlink:href,'#')"/><xsl:value-of select="//fb:binary[@id=$href]/@content-type" disable-output-escaping="yes" /><xsl:text>;base64,</xsl:text><!--<xsl:value-of select="substring-after(@xlink:href,'#')"/>--><xsl:value-of select="//fb:binary[@id=$href]" disable-output-escaping="yes"/></xsl:attribute> </xsl:when> <xsl:otherwise> <xsl:attribute name="src"><xsl:value-of select="@xlink:href"/></xsl:attribute> </xsl:otherwise> </xsl:choose> </img> </div> </xsl:template> </xsl:stylesheet> opds_catalog/dl.py +64 −1 Original line number Diff line number Diff line # -*- coding: utf-8 -*- import os import codecs import base64 import io import subprocess import lxml.etree as ET from django.http import HttpResponse, Http404 Loading Loading @@ -286,3 +286,66 @@ def ConvertFB2(request, book_id, convert_type): pass return response def ReadFB2(request, book_id): """ Загрузка книги """ book = Book.objects.get(id=book_id) if config.SOPDS_AUTH and request.user.is_authenticated(): bookshelf.objects.get_or_create(user=request.user, book=book) full_path=os.path.join(config.SOPDS_ROOT_LIB,book.path) if book.cat_type==opdsdb.CAT_INP: # Убираем из пути INPX файл inpx_path, zip_name = os.path.split(full_path) path, inpx_file = os.path.split(inpx_path) full_path = os.path.join(path,zip_name) if config.SOPDS_TITLE_AS_FILENAME: transname=utils.translit(book.title+'.'+book.format) else: transname=utils.translit(book.filename) transname = utils.to_ascii(transname) dlfilename=transname content_type = mime_detector.fmt(book.format) response = HttpResponse() response["Content-Type"]='text/html; charset=utf-8' z = None fz = None s = None book_size = book.filesize if book.cat_type==opdsdb.CAT_NORMAL: file_path=os.path.join(full_path, book.filename) book_size=os.path.getsize(file_path) try: fo=codecs.open(file_path, "rb") except FileNotFoundError: raise Http404 s=fo.read() elif book.cat_type in [opdsdb.CAT_ZIP, opdsdb.CAT_INP]: try: fz=codecs.open(full_path, "rb") except FileNotFoundError: raise Http404 z = zipfile.ZipFile(fz, 'r', allowZip64=True) book_size=z.getinfo(book.filename).file_size fo= z.open(book.filename) dom = ET.parse(fo) xslt = ET.parse('%s/FB2_22_xhtml.xsl' % os.path.dirname(os.path.realpath(__file__))) transform = ET.XSLT(xslt) newdom = transform(dom) book_content = ET.tostring(newdom, pretty_print=True) response.write(book_content) fo.close() if z: z.close() if fz: fz.close() return response No newline at end of file opds_catalog/locale/ru/LC_MESSAGES/django.mo (4.63 KiB) File changed.No diff preview for this file type. View original file View changed file opds_catalog/locale/ru/LC_MESSAGES/django.po +289 −290 Original line number Diff line number Diff line Loading @@ -8,99 +8,99 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-02-28 21:12+0300\n" "POT-Creation-Date: 2017-03-23 22:58+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%" "100>=11 && n%100<=14)? 2 : 3);\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" "%100>=11 && n%100<=14)? 2 : 3);\n" #: .\opds_catalog\feeds.py:129 #: opds_catalog/feeds.py:131 #, python-format msgid "All books by %(author)s" msgstr "Все книги автора %(author)s" #: .\opds_catalog\feeds.py:141 #: opds_catalog/feeds.py:143 msgid "Book doublicates" msgstr "Дубликаты книги" #: .\opds_catalog\feeds.py:162 .\opds_catalog\feeds.py:247 #: .\opds_catalog\feeds.py:249 .\opds_catalog\tests\test_feeds.py:24 #: opds_catalog/feeds.py:164 opds_catalog/feeds.py:249 #: opds_catalog/feeds.py:251 opds_catalog/tests/test_feeds.py:24 msgid "By catalogs" msgstr "По каталогам" #: .\opds_catalog\feeds.py:163 .\opds_catalog\tests\test_feeds.py:25 #: opds_catalog/feeds.py:165 opds_catalog/tests/test_feeds.py:25 #, python-format msgid "Catalogs: %(catalogs)s, books: %(books)s." msgstr "Каталогов: %(catalogs)s, книг: %(books)s." #: .\opds_catalog\feeds.py:164 #: opds_catalog/feeds.py:166 msgid "By authors" msgstr "По авторам" #: .\opds_catalog\feeds.py:165 .\opds_catalog\tests\test_feeds.py:26 #: opds_catalog/feeds.py:167 opds_catalog/tests/test_feeds.py:26 #, python-format msgid "Authors: %(authors)s." msgstr "Авторов: %(authors)s." #: .\opds_catalog\feeds.py:166 #: opds_catalog/feeds.py:168 msgid "By titles" msgstr "По наименованиям" #: .\opds_catalog\feeds.py:167 #: opds_catalog/feeds.py:169 #, python-format msgid "Books: %(books)s." msgstr "Книг: %(books)s." #: .\opds_catalog\feeds.py:168 #: opds_catalog/feeds.py:170 msgid "By genres" msgstr "По жанрам" #: .\opds_catalog\feeds.py:169 .\opds_catalog\tests\test_feeds.py:27 #: opds_catalog/feeds.py:171 opds_catalog/tests/test_feeds.py:27 #, python-format msgid "Genres: %(genres)s." msgstr "Жанров: %(genres)s." #: .\opds_catalog\feeds.py:170 #: opds_catalog/feeds.py:172 msgid "By series" msgstr "По сериям" #: .\opds_catalog\feeds.py:171 #: opds_catalog/feeds.py:173 #, python-format msgid "Series: %(series)s." msgstr "Серий: %(series)s." #: .\opds_catalog\feeds.py:175 #: opds_catalog/feeds.py:177 #, python-format msgid "%(username)s Book shelf" msgstr "Книжная полка (%(username)s)" #: .\opds_catalog\feeds.py:176 #: opds_catalog/feeds.py:178 #, python-format msgid "%(username)s books readed: %(bookshelf)s." msgstr "Книг прочитано (%(username)s): %(bookshelf)s." #: .\opds_catalog\feeds.py:308 .\opds_catalog\feeds.py:554 #: opds_catalog/feeds.py:318 opds_catalog/feeds.py:568 #, python-format msgid "<b>Authors: </b>%(authors)s<br/>" msgstr "<b>Авторов: </b>%(authors)s<br/>" #: .\opds_catalog\feeds.py:309 .\opds_catalog\feeds.py:555 #: opds_catalog/feeds.py:319 opds_catalog/feeds.py:569 #, python-format msgid "<b>Genres: </b>%(genres)s<br/>" msgstr "<b>Жанров: </b>%(genres)s<br/>" #: .\opds_catalog\feeds.py:310 .\opds_catalog\feeds.py:556 #: opds_catalog/feeds.py:320 opds_catalog/feeds.py:570 #, python-format msgid "<b>Series: </b>%(series)s<br/>" msgstr "<b>Серий: </b>%(series)s<br/>" #: .\opds_catalog\feeds.py:311 .\opds_catalog\feeds.py:557 #: opds_catalog/feeds.py:321 opds_catalog/feeds.py:571 #, python-format msgid "" "<b>File: </b>%(filename)s<br/><b>File size: </b>%(filesize)s<br/><b>Changes " Loading @@ -109,155 +109,154 @@ msgstr "" "<b>Файл: </b>%(filename)s<br/><b>Размер файла: </b>%(filesize)s<br/><b>Дата " "изменения: </b>%(docdate)s<br/>" #: .\opds_catalog\feeds.py:344 .\opds_catalog\tests\test_feeds.py:60 #: opds_catalog/feeds.py:354 opds_catalog/tests/test_feeds.py:60 msgid "Search by titles" msgstr "Поиск по наименованиям" #: .\opds_catalog\feeds.py:344 #: opds_catalog/feeds.py:354 msgid "Search books by title" msgstr "Поиск книг по наименованию" #: .\opds_catalog\feeds.py:345 #: opds_catalog/feeds.py:355 msgid "Search by authors" msgstr "Поиск авторов" #: .\opds_catalog\feeds.py:345 #: opds_catalog/feeds.py:355 msgid "Search authors by name" msgstr "Поиск авторов по имени" #: .\opds_catalog\feeds.py:346 #: opds_catalog/feeds.py:356 msgid "Search series" msgstr "Поиск серий" #: .\opds_catalog\feeds.py:378 #: opds_catalog/feeds.py:388 msgid "Books found" msgstr "Найдены книги" #: .\opds_catalog\feeds.py:378 #: opds_catalog/feeds.py:388 msgid "doubles hide" msgstr "дубликаты скрыты" #: .\opds_catalog\feeds.py:378 #: opds_catalog/feeds.py:388 msgid "doubles show" msgstr "дубликаты показаны" #: .\opds_catalog\feeds.py:558 #: opds_catalog/feeds.py:572 #, python-format msgid "<b>Doubles count: </b>%(doubles)s<br/>" msgstr "<b>Число дубликатов: </b>%(doubles)s<br/>" #: .\opds_catalog\feeds.py:572 #: opds_catalog/feeds.py:586 msgid "Series by authors select" msgstr "Выбор серий у автора" #: .\opds_catalog\feeds.py:593 #: opds_catalog/feeds.py:607 msgid "Books by series" msgstr "Книги по сериям" #: .\opds_catalog\feeds.py:593 #: opds_catalog/feeds.py:607 msgid "Books by author and series" msgstr "Книги по авторам и сериям" #: .\opds_catalog\feeds.py:594 #: opds_catalog/feeds.py:608 msgid "Books outside series" msgstr "Книги вне серий" #: .\opds_catalog\feeds.py:594 #: opds_catalog/feeds.py:608 msgid "Books by author outside series" msgstr "Книги автора вне серий" #: .\opds_catalog\feeds.py:595 #: opds_catalog/feeds.py:609 msgid "Books by alphabet" msgstr "Книги по алфавиту" #: .\opds_catalog\feeds.py:595 #: opds_catalog/feeds.py:609 msgid "Books by author alphabetical order" msgstr "Книги автора в алфавитном порядке" #: .\opds_catalog\feeds.py:626 #: opds_catalog/feeds.py:640 msgid "Authors found" msgstr "Найдены авторы" #: .\opds_catalog\feeds.py:679 .\opds_catalog\feeds.py:757 #: opds_catalog/feeds.py:693 opds_catalog/feeds.py:771 #, python-format msgid "Books count: %s" msgstr "Всего: %s книг" #: .\opds_catalog\feeds.py:695 #: opds_catalog/feeds.py:709 msgid "Series found" msgstr "Найдены серии" #: .\opds_catalog\feeds.py:781 #: opds_catalog/feeds.py:795 msgid "Select language" msgstr "Выбор алфавита" #: .\opds_catalog\feeds.py:793 .\opds_catalog\tests\test_feeds.py:106 #: .\opds_catalog\tests\test_feeds.py:119 #: .\opds_catalog\tests\test_feeds.py:130 #: opds_catalog/feeds.py:807 opds_catalog/tests/test_feeds.py:106 #: opds_catalog/tests/test_feeds.py:119 opds_catalog/tests/test_feeds.py:130 msgid "Cyrillic" msgstr "Кириллица (РУС)" #: .\opds_catalog\feeds.py:794 .\opds_catalog\tests\test_feeds.py:107 #: opds_catalog/feeds.py:808 opds_catalog/tests/test_feeds.py:107 msgid "Latin" msgstr "Латинница (LAT)" #: .\opds_catalog\feeds.py:795 .\opds_catalog\tests\test_feeds.py:108 #: opds_catalog/feeds.py:809 opds_catalog/tests/test_feeds.py:108 msgid "Digits" msgstr "Цифры (0..9)" #: .\opds_catalog\feeds.py:796 .\opds_catalog\tests\test_feeds.py:109 #: opds_catalog/feeds.py:810 opds_catalog/tests/test_feeds.py:109 msgid "Other symbols" msgstr "Другие символы" #: .\opds_catalog\feeds.py:797 .\opds_catalog\tests\test_feeds.py:110 #: opds_catalog/feeds.py:811 opds_catalog/tests/test_feeds.py:110 msgid "Show all" msgstr "Показать все" #: .\opds_catalog\feeds.py:827 #: opds_catalog/feeds.py:841 msgid "Select books by substring" msgstr "Поиск книг по подстроке" #: .\opds_catalog\feeds.py:864 .\opds_catalog\feeds.py:1030 #: opds_catalog/feeds.py:878 opds_catalog/feeds.py:1044 #, python-format msgid "Found: %s books" msgstr "Найдено %s книг" #: .\opds_catalog\feeds.py:885 #: opds_catalog/feeds.py:899 msgid "Select authors by substring" msgstr "Поиск авторов по подстроке" #: .\opds_catalog\feeds.py:922 #: opds_catalog/feeds.py:936 #, python-format msgid "Found: %s authors" msgstr "Найдено %s авторов" #: .\opds_catalog\feeds.py:943 #: opds_catalog/feeds.py:957 msgid "Select series by substring" msgstr "Поиск серий по подстроке" #: .\opds_catalog\feeds.py:980 #: opds_catalog/feeds.py:994 #, python-format msgid "Found: %s series" msgstr "Найдено %s серий" #: .\opds_catalog\feeds.py:1001 #: opds_catalog/feeds.py:1015 #, python-format msgid "Select genres (%s)" msgstr "Выбор жанра (%s)" #: .\opds_catalog\feeds.py:1001 #: opds_catalog/feeds.py:1015 msgid "section" msgstr "секция" #: .\opds_catalog\feeds.py:1001 #: opds_catalog/feeds.py:1015 msgid "subsection" msgstr "подсекция" #: .\opds_catalog\sopdscan.py:232 #: opds_catalog/sopdscan.py:232 msgid "Unknown author" msgstr "Неизвестный автор" #: .\opds_catalog\tests\test_feeds.py:78 #: opds_catalog/tests/test_feeds.py:78 #, python-format msgid "All books by %(full_name)s" msgstr "Все книги автора %(full_name)s" Loading opds_catalog/migrations/0006_bookshelf_position.py 0 → 100644 +20 −0 Original line number Diff line number Diff line # -*- coding: utf-8 -*- # Generated by Django 1.10 on 2017-03-27 16:10 from __future__ import unicode_literals from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('opds_catalog', '0005_auto_20161204_2138'), ] operations = [ migrations.AddField( model_name='bookshelf', name='position', field=models.FloatField(default=None, null=True), ), ] Loading
opds_catalog/FB2_22_xhtml.xsl 0 → 100644 +322 −0 Original line number Diff line number Diff line <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fb="http://www.gribuser.ru/xml/fictionbook/2.0"> <xsl:output method="xml" encoding="UTF-8"/> <xsl:key name="note-link" match="fb:section" use="@id"/> <xsl:template match="/*"> <html> <head> <xsl:if test="fb:description/fb:title-info/fb:lang = 'ru'"> <meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/> </xsl:if> <title> <xsl:value-of select="fb:description/fb:title-info/fb:book-title"/> </title> <style type="text/x-oeb1-css"> A { color : #0002CC } A:HOVER { color : #BF0000 } BODY { background-color : #FEFEFE; color : #000000; font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; text-align : justify } H1{ font-size : 160%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Black; background-color : #E7E7E7; margin-left : 0px; page-break-before : always; } H2{ font-size : 130%; font-style : normal; font-weight : bold; text-align : left; background-color : #EEEEEE; border : 1px solid Gray; page-break-before : always; } H3{ font-size : 110%; font-style : normal; font-weight : bold; text-align : left; background-color : #F1F1F1; border : 1px solid Silver;} H4{ font-size : 100%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;} H5{ font-size : 100%; font-style : italic; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;} H6{ font-size : 100%; font-style : italic; font-weight : normal; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;} SMALL{ font-size : 80% } BLOCKQUOTE{ margin-left :4em; margin-top:1em; margin-right:0.2em;} HR{ color : Black } UL{margin-left: 0} .epigraph{width:50%; margin-left : 35%;} </style> </head> <body> <h4 align="center"> <xsl:value-of select="fb:description/fb:title-info/fb:book-title"/> </h4> <xsl:for-each select="fb:description/fb:title-info/fb:coverpage/fb:image"> <xsl:call-template name="image"/> </xsl:for-each> <xsl:for-each select="fb:description/fb:title-info/fb:annotation"> <div> <xsl:call-template name="annotation"/> </div> <hr/> </xsl:for-each> <!-- BUILD TOC --> <ul> <xsl:apply-templates select="fb:body" mode="toc"/> </ul> <hr/> <!-- BUILD BOOK --> <xsl:for-each select="fb:body"> <xsl:if test="position()!=1"> <hr/> </xsl:if> <xsl:if test="@name"> <h4 align="center"> <xsl:value-of select="@name"/> </h4> </xsl:if> <!-- <xsl:apply-templates /> --> <xsl:apply-templates/> </xsl:for-each> </body> </html> </xsl:template> <!-- author template --> <xsl:template name="author"> <xsl:value-of select="fb:first-name"/> <xsl:text disable-output-escaping="no"> </xsl:text> <xsl:value-of select="fb:middle-name"/>  <xsl:text disable-output-escaping="no"> </xsl:text> <xsl:value-of select="fb:last-name"/> <br/> </xsl:template> <!-- secuence template --> <xsl:template name="sequence"> <LI/> <xsl:value-of select="@name"/> <xsl:if test="@number"> <xsl:text disable-output-escaping="no">, #</xsl:text> <xsl:value-of select="@number"/> </xsl:if> <xsl:if test="fb:sequence"> <ul> <xsl:for-each select="fb:sequence"> <xsl:call-template name="sequence"/> </xsl:for-each> </ul> </xsl:if> <!-- <br/> --> </xsl:template> <!-- toc template --> <xsl:template match="fb:section|fb:body" mode="toc"> <xsl:choose> <xsl:when test="name()='body' and position()=1 and not(fb:title)"> <xsl:apply-templates select="fb:section" mode="toc"/> </xsl:when> <xsl:otherwise> <li> <a href="#TOC_{position()}"><xsl:value-of select="normalize-space(fb:title/fb:p[1] | @name)"/></a> <xsl:if test="fb:section"> <ul><xsl:apply-templates select="fb:section" mode="toc"/></ul> </xsl:if> </li> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- description --> <xsl:template match="fb:description"> <xsl:apply-templates/> </xsl:template> <!-- body --> <xsl:template match="fb:body"> <div><xsl:apply-templates/></div> </xsl:template> <xsl:template match="fb:section" name="section"> <a name="TOC_{position()}"></a> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </xsl:template> <!-- section/title --> <xsl:template match="fb:section/fb:title|fb:poem/fb:title"> <xsl:choose> <xsl:when test="count(ancestor::node()) < 9"> <xsl:element name="{concat('h',count(ancestor::node())-3)}"> <a name="TOC_{position()}"></a> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </xsl:element> </xsl:when> <xsl:otherwise> <xsl:element name="h6"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </xsl:element> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- section/title --> <xsl:template match="fb:body/fb:title"> <h1><xsl:apply-templates mode="title"/></h1> </xsl:template> <xsl:template match="fb:title/fb:p"> <xsl:apply-templates/><xsl:text disable-output-escaping="no"> </xsl:text><br/> </xsl:template> <!-- subtitle --> <xsl:template match="fb:subtitle"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <h5> <xsl:apply-templates/> </h5> </xsl:template> <!-- p --> <xsl:template match="fb:p"> <xsl:variable name="count"> <xsl:number/> </xsl:variable> <div id="{1+count(ancestor::fb:section/preceding-sibling::fb:section)}.{$count}" align="justify"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if>    <xsl:apply-templates/> </div> </xsl:template> <!-- strong --> <xsl:template match="fb:strong"> <b><xsl:apply-templates/></b> </xsl:template> <!-- emphasis --> <xsl:template match="fb:emphasis"> <i> <xsl:apply-templates/></i> </xsl:template> <!-- style --> <xsl:template match="fb:style"> <span class="{@name}"><xsl:apply-templates/></span> </xsl:template> <!-- empty-line --> <xsl:template match="fb:empty-line"> <br/> </xsl:template> <!-- link --> <xsl:template match="fb:a"> <xsl:element name="a"> <xsl:attribute name="href"><xsl:value-of select="@xlink:href"/></xsl:attribute> <xsl:attribute name="title"> <xsl:choose> <xsl:when test="starts-with(@xlink:href,'#')"><xsl:value-of select="key('note-link',substring-after(@xlink:href,'#'))/fb:p"/></xsl:when> <xsl:otherwise><xsl:value-of select="key('note-link',@xlink:href)/fb:p"/></xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:choose> <xsl:when test="(@type) = 'note'"> <sup> <xsl:apply-templates/> </sup> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:element> </xsl:template> <!-- annotation --> <xsl:template name="annotation"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <h3>Annotation</h3> <xsl:apply-templates/> </xsl:template> <!-- epigraph --> <xsl:template match="fb:epigraph"> <blockquote class="epigraph"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </blockquote> </xsl:template> <!-- epigraph/text-author --> <xsl:template match="fb:epigraph/fb:text-author"> <blockquote> <i><xsl:apply-templates/></i> </blockquote> </xsl:template> <!-- cite --> <xsl:template match="fb:cite"> <blockquote> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </blockquote> </xsl:template> <!-- cite/text-author --> <xsl:template match="fb:text-author"> <blockquote> <i> <xsl:apply-templates/></i></blockquote> </xsl:template> <!-- date --> <xsl:template match="fb:date"> <xsl:choose> <xsl:when test="not(@value)">    <xsl:apply-templates/> <br/> </xsl:when> <xsl:otherwise>    <xsl:value-of select="@value"/> <br/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- poem --> <xsl:template match="fb:poem"> <blockquote> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/> </blockquote> </xsl:template> <!-- stanza --> <xsl:template match="fb:stanza"> <xsl:apply-templates/> <br/> </xsl:template> <!-- v --> <xsl:template match="fb:v"> <xsl:if test="@id"> <xsl:element name="a"> <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute> </xsl:element> </xsl:if> <xsl:apply-templates/><br/> </xsl:template> <!-- image --> <xsl:template match="fb:image" name="image"> <div align="center"> <img border="1"> <xsl:choose> <xsl:when test="starts-with(@xlink:href,'#')"> <xsl:attribute name="src"><xsl:text>data:</xsl:text><xsl:variable name="href" select="substring-after(@xlink:href,'#')" /><set variable="href" expression="substring-after(@xlink:href,'#')"/><xsl:value-of select="//fb:binary[@id=$href]/@content-type" disable-output-escaping="yes" /><xsl:text>;base64,</xsl:text><!--<xsl:value-of select="substring-after(@xlink:href,'#')"/>--><xsl:value-of select="//fb:binary[@id=$href]" disable-output-escaping="yes"/></xsl:attribute> </xsl:when> <xsl:otherwise> <xsl:attribute name="src"><xsl:value-of select="@xlink:href"/></xsl:attribute> </xsl:otherwise> </xsl:choose> </img> </div> </xsl:template> </xsl:stylesheet>
opds_catalog/dl.py +64 −1 Original line number Diff line number Diff line # -*- coding: utf-8 -*- import os import codecs import base64 import io import subprocess import lxml.etree as ET from django.http import HttpResponse, Http404 Loading Loading @@ -286,3 +286,66 @@ def ConvertFB2(request, book_id, convert_type): pass return response def ReadFB2(request, book_id): """ Загрузка книги """ book = Book.objects.get(id=book_id) if config.SOPDS_AUTH and request.user.is_authenticated(): bookshelf.objects.get_or_create(user=request.user, book=book) full_path=os.path.join(config.SOPDS_ROOT_LIB,book.path) if book.cat_type==opdsdb.CAT_INP: # Убираем из пути INPX файл inpx_path, zip_name = os.path.split(full_path) path, inpx_file = os.path.split(inpx_path) full_path = os.path.join(path,zip_name) if config.SOPDS_TITLE_AS_FILENAME: transname=utils.translit(book.title+'.'+book.format) else: transname=utils.translit(book.filename) transname = utils.to_ascii(transname) dlfilename=transname content_type = mime_detector.fmt(book.format) response = HttpResponse() response["Content-Type"]='text/html; charset=utf-8' z = None fz = None s = None book_size = book.filesize if book.cat_type==opdsdb.CAT_NORMAL: file_path=os.path.join(full_path, book.filename) book_size=os.path.getsize(file_path) try: fo=codecs.open(file_path, "rb") except FileNotFoundError: raise Http404 s=fo.read() elif book.cat_type in [opdsdb.CAT_ZIP, opdsdb.CAT_INP]: try: fz=codecs.open(full_path, "rb") except FileNotFoundError: raise Http404 z = zipfile.ZipFile(fz, 'r', allowZip64=True) book_size=z.getinfo(book.filename).file_size fo= z.open(book.filename) dom = ET.parse(fo) xslt = ET.parse('%s/FB2_22_xhtml.xsl' % os.path.dirname(os.path.realpath(__file__))) transform = ET.XSLT(xslt) newdom = transform(dom) book_content = ET.tostring(newdom, pretty_print=True) response.write(book_content) fo.close() if z: z.close() if fz: fz.close() return response No newline at end of file
opds_catalog/locale/ru/LC_MESSAGES/django.mo (4.63 KiB) File changed.No diff preview for this file type. View original file View changed file
opds_catalog/locale/ru/LC_MESSAGES/django.po +289 −290 Original line number Diff line number Diff line Loading @@ -8,99 +8,99 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-02-28 21:12+0300\n" "POT-Creation-Date: 2017-03-23 22:58+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%" "100>=11 && n%100<=14)? 2 : 3);\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" "%100>=11 && n%100<=14)? 2 : 3);\n" #: .\opds_catalog\feeds.py:129 #: opds_catalog/feeds.py:131 #, python-format msgid "All books by %(author)s" msgstr "Все книги автора %(author)s" #: .\opds_catalog\feeds.py:141 #: opds_catalog/feeds.py:143 msgid "Book doublicates" msgstr "Дубликаты книги" #: .\opds_catalog\feeds.py:162 .\opds_catalog\feeds.py:247 #: .\opds_catalog\feeds.py:249 .\opds_catalog\tests\test_feeds.py:24 #: opds_catalog/feeds.py:164 opds_catalog/feeds.py:249 #: opds_catalog/feeds.py:251 opds_catalog/tests/test_feeds.py:24 msgid "By catalogs" msgstr "По каталогам" #: .\opds_catalog\feeds.py:163 .\opds_catalog\tests\test_feeds.py:25 #: opds_catalog/feeds.py:165 opds_catalog/tests/test_feeds.py:25 #, python-format msgid "Catalogs: %(catalogs)s, books: %(books)s." msgstr "Каталогов: %(catalogs)s, книг: %(books)s." #: .\opds_catalog\feeds.py:164 #: opds_catalog/feeds.py:166 msgid "By authors" msgstr "По авторам" #: .\opds_catalog\feeds.py:165 .\opds_catalog\tests\test_feeds.py:26 #: opds_catalog/feeds.py:167 opds_catalog/tests/test_feeds.py:26 #, python-format msgid "Authors: %(authors)s." msgstr "Авторов: %(authors)s." #: .\opds_catalog\feeds.py:166 #: opds_catalog/feeds.py:168 msgid "By titles" msgstr "По наименованиям" #: .\opds_catalog\feeds.py:167 #: opds_catalog/feeds.py:169 #, python-format msgid "Books: %(books)s." msgstr "Книг: %(books)s." #: .\opds_catalog\feeds.py:168 #: opds_catalog/feeds.py:170 msgid "By genres" msgstr "По жанрам" #: .\opds_catalog\feeds.py:169 .\opds_catalog\tests\test_feeds.py:27 #: opds_catalog/feeds.py:171 opds_catalog/tests/test_feeds.py:27 #, python-format msgid "Genres: %(genres)s." msgstr "Жанров: %(genres)s." #: .\opds_catalog\feeds.py:170 #: opds_catalog/feeds.py:172 msgid "By series" msgstr "По сериям" #: .\opds_catalog\feeds.py:171 #: opds_catalog/feeds.py:173 #, python-format msgid "Series: %(series)s." msgstr "Серий: %(series)s." #: .\opds_catalog\feeds.py:175 #: opds_catalog/feeds.py:177 #, python-format msgid "%(username)s Book shelf" msgstr "Книжная полка (%(username)s)" #: .\opds_catalog\feeds.py:176 #: opds_catalog/feeds.py:178 #, python-format msgid "%(username)s books readed: %(bookshelf)s." msgstr "Книг прочитано (%(username)s): %(bookshelf)s." #: .\opds_catalog\feeds.py:308 .\opds_catalog\feeds.py:554 #: opds_catalog/feeds.py:318 opds_catalog/feeds.py:568 #, python-format msgid "<b>Authors: </b>%(authors)s<br/>" msgstr "<b>Авторов: </b>%(authors)s<br/>" #: .\opds_catalog\feeds.py:309 .\opds_catalog\feeds.py:555 #: opds_catalog/feeds.py:319 opds_catalog/feeds.py:569 #, python-format msgid "<b>Genres: </b>%(genres)s<br/>" msgstr "<b>Жанров: </b>%(genres)s<br/>" #: .\opds_catalog\feeds.py:310 .\opds_catalog\feeds.py:556 #: opds_catalog/feeds.py:320 opds_catalog/feeds.py:570 #, python-format msgid "<b>Series: </b>%(series)s<br/>" msgstr "<b>Серий: </b>%(series)s<br/>" #: .\opds_catalog\feeds.py:311 .\opds_catalog\feeds.py:557 #: opds_catalog/feeds.py:321 opds_catalog/feeds.py:571 #, python-format msgid "" "<b>File: </b>%(filename)s<br/><b>File size: </b>%(filesize)s<br/><b>Changes " Loading @@ -109,155 +109,154 @@ msgstr "" "<b>Файл: </b>%(filename)s<br/><b>Размер файла: </b>%(filesize)s<br/><b>Дата " "изменения: </b>%(docdate)s<br/>" #: .\opds_catalog\feeds.py:344 .\opds_catalog\tests\test_feeds.py:60 #: opds_catalog/feeds.py:354 opds_catalog/tests/test_feeds.py:60 msgid "Search by titles" msgstr "Поиск по наименованиям" #: .\opds_catalog\feeds.py:344 #: opds_catalog/feeds.py:354 msgid "Search books by title" msgstr "Поиск книг по наименованию" #: .\opds_catalog\feeds.py:345 #: opds_catalog/feeds.py:355 msgid "Search by authors" msgstr "Поиск авторов" #: .\opds_catalog\feeds.py:345 #: opds_catalog/feeds.py:355 msgid "Search authors by name" msgstr "Поиск авторов по имени" #: .\opds_catalog\feeds.py:346 #: opds_catalog/feeds.py:356 msgid "Search series" msgstr "Поиск серий" #: .\opds_catalog\feeds.py:378 #: opds_catalog/feeds.py:388 msgid "Books found" msgstr "Найдены книги" #: .\opds_catalog\feeds.py:378 #: opds_catalog/feeds.py:388 msgid "doubles hide" msgstr "дубликаты скрыты" #: .\opds_catalog\feeds.py:378 #: opds_catalog/feeds.py:388 msgid "doubles show" msgstr "дубликаты показаны" #: .\opds_catalog\feeds.py:558 #: opds_catalog/feeds.py:572 #, python-format msgid "<b>Doubles count: </b>%(doubles)s<br/>" msgstr "<b>Число дубликатов: </b>%(doubles)s<br/>" #: .\opds_catalog\feeds.py:572 #: opds_catalog/feeds.py:586 msgid "Series by authors select" msgstr "Выбор серий у автора" #: .\opds_catalog\feeds.py:593 #: opds_catalog/feeds.py:607 msgid "Books by series" msgstr "Книги по сериям" #: .\opds_catalog\feeds.py:593 #: opds_catalog/feeds.py:607 msgid "Books by author and series" msgstr "Книги по авторам и сериям" #: .\opds_catalog\feeds.py:594 #: opds_catalog/feeds.py:608 msgid "Books outside series" msgstr "Книги вне серий" #: .\opds_catalog\feeds.py:594 #: opds_catalog/feeds.py:608 msgid "Books by author outside series" msgstr "Книги автора вне серий" #: .\opds_catalog\feeds.py:595 #: opds_catalog/feeds.py:609 msgid "Books by alphabet" msgstr "Книги по алфавиту" #: .\opds_catalog\feeds.py:595 #: opds_catalog/feeds.py:609 msgid "Books by author alphabetical order" msgstr "Книги автора в алфавитном порядке" #: .\opds_catalog\feeds.py:626 #: opds_catalog/feeds.py:640 msgid "Authors found" msgstr "Найдены авторы" #: .\opds_catalog\feeds.py:679 .\opds_catalog\feeds.py:757 #: opds_catalog/feeds.py:693 opds_catalog/feeds.py:771 #, python-format msgid "Books count: %s" msgstr "Всего: %s книг" #: .\opds_catalog\feeds.py:695 #: opds_catalog/feeds.py:709 msgid "Series found" msgstr "Найдены серии" #: .\opds_catalog\feeds.py:781 #: opds_catalog/feeds.py:795 msgid "Select language" msgstr "Выбор алфавита" #: .\opds_catalog\feeds.py:793 .\opds_catalog\tests\test_feeds.py:106 #: .\opds_catalog\tests\test_feeds.py:119 #: .\opds_catalog\tests\test_feeds.py:130 #: opds_catalog/feeds.py:807 opds_catalog/tests/test_feeds.py:106 #: opds_catalog/tests/test_feeds.py:119 opds_catalog/tests/test_feeds.py:130 msgid "Cyrillic" msgstr "Кириллица (РУС)" #: .\opds_catalog\feeds.py:794 .\opds_catalog\tests\test_feeds.py:107 #: opds_catalog/feeds.py:808 opds_catalog/tests/test_feeds.py:107 msgid "Latin" msgstr "Латинница (LAT)" #: .\opds_catalog\feeds.py:795 .\opds_catalog\tests\test_feeds.py:108 #: opds_catalog/feeds.py:809 opds_catalog/tests/test_feeds.py:108 msgid "Digits" msgstr "Цифры (0..9)" #: .\opds_catalog\feeds.py:796 .\opds_catalog\tests\test_feeds.py:109 #: opds_catalog/feeds.py:810 opds_catalog/tests/test_feeds.py:109 msgid "Other symbols" msgstr "Другие символы" #: .\opds_catalog\feeds.py:797 .\opds_catalog\tests\test_feeds.py:110 #: opds_catalog/feeds.py:811 opds_catalog/tests/test_feeds.py:110 msgid "Show all" msgstr "Показать все" #: .\opds_catalog\feeds.py:827 #: opds_catalog/feeds.py:841 msgid "Select books by substring" msgstr "Поиск книг по подстроке" #: .\opds_catalog\feeds.py:864 .\opds_catalog\feeds.py:1030 #: opds_catalog/feeds.py:878 opds_catalog/feeds.py:1044 #, python-format msgid "Found: %s books" msgstr "Найдено %s книг" #: .\opds_catalog\feeds.py:885 #: opds_catalog/feeds.py:899 msgid "Select authors by substring" msgstr "Поиск авторов по подстроке" #: .\opds_catalog\feeds.py:922 #: opds_catalog/feeds.py:936 #, python-format msgid "Found: %s authors" msgstr "Найдено %s авторов" #: .\opds_catalog\feeds.py:943 #: opds_catalog/feeds.py:957 msgid "Select series by substring" msgstr "Поиск серий по подстроке" #: .\opds_catalog\feeds.py:980 #: opds_catalog/feeds.py:994 #, python-format msgid "Found: %s series" msgstr "Найдено %s серий" #: .\opds_catalog\feeds.py:1001 #: opds_catalog/feeds.py:1015 #, python-format msgid "Select genres (%s)" msgstr "Выбор жанра (%s)" #: .\opds_catalog\feeds.py:1001 #: opds_catalog/feeds.py:1015 msgid "section" msgstr "секция" #: .\opds_catalog\feeds.py:1001 #: opds_catalog/feeds.py:1015 msgid "subsection" msgstr "подсекция" #: .\opds_catalog\sopdscan.py:232 #: opds_catalog/sopdscan.py:232 msgid "Unknown author" msgstr "Неизвестный автор" #: .\opds_catalog\tests\test_feeds.py:78 #: opds_catalog/tests/test_feeds.py:78 #, python-format msgid "All books by %(full_name)s" msgstr "Все книги автора %(full_name)s" Loading
opds_catalog/migrations/0006_bookshelf_position.py 0 → 100644 +20 −0 Original line number Diff line number Diff line # -*- coding: utf-8 -*- # Generated by Django 1.10 on 2017-03-27 16:10 from __future__ import unicode_literals from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('opds_catalog', '0005_auto_20161204_2138'), ] operations = [ migrations.AddField( model_name='bookshelf', name='position', field=models.FloatField(default=None, null=True), ), ]