├── cps ├── __init__.py ├── static │ ├── favicon.ico │ ├── img │ │ ├── close.png │ │ ├── loader.gif │ │ ├── save.png │ │ ├── saved.png │ │ ├── star.png │ │ ├── settings.png │ │ ├── fullscreen.png │ │ ├── menu-icon.png │ │ ├── settings-s.png │ │ ├── apple-touch-icon.png │ │ ├── cancelfullscreen.png │ │ ├── annotator-icon-sprite.png │ │ ├── annotator-glyph-sprite.png │ │ └── goodreads.svg │ ├── css │ │ ├── images │ │ │ ├── grab.cur │ │ │ ├── shadow.png │ │ │ ├── grabbing.cur │ │ │ ├── texture.png │ │ │ ├── loading-icon.gif │ │ │ ├── loading-small.png │ │ │ ├── loading-small@2x.png │ │ │ ├── findbarButton-next.png │ │ │ ├── toolbarButton-print.png │ │ │ ├── treeitem-collapsed.png │ │ │ ├── treeitem-expanded.png │ │ │ ├── findbarButton-next@2x.png │ │ │ ├── toolbarButton-pageUp.png │ │ │ ├── toolbarButton-search.png │ │ │ ├── toolbarButton-zoomIn.png │ │ │ ├── toolbarButton-zoomOut.png │ │ │ ├── treeitem-collapsed@2x.png │ │ │ ├── treeitem-expanded@2x.png │ │ │ ├── findbarButton-next-rtl.png │ │ │ ├── findbarButton-previous.png │ │ │ ├── toolbarButton-bookmark.png │ │ │ ├── toolbarButton-download.png │ │ │ ├── toolbarButton-menuArrows.png │ │ │ ├── toolbarButton-openFile.png │ │ │ ├── toolbarButton-pageDown.png │ │ │ ├── toolbarButton-pageUp-rtl.png │ │ │ ├── toolbarButton-pageUp@2x.png │ │ │ ├── toolbarButton-print@2x.png │ │ │ ├── toolbarButton-search@2x.png │ │ │ ├── toolbarButton-zoomIn@2x.png │ │ │ ├── toolbarButton-zoomOut@2x.png │ │ │ ├── treeitem-collapsed-rtl.png │ │ │ ├── findbarButton-next-rtl@2x.png │ │ │ ├── findbarButton-previous-rtl.png │ │ │ ├── findbarButton-previous@2x.png │ │ │ ├── toolbarButton-bookmark@2x.png │ │ │ ├── toolbarButton-download@2x.png │ │ │ ├── toolbarButton-openFile@2x.png │ │ │ ├── toolbarButton-pageDown-rtl.png │ │ │ ├── toolbarButton-pageDown@2x.png │ │ │ ├── toolbarButton-viewOutline.png │ │ │ ├── treeitem-collapsed-rtl@2x.png │ │ │ ├── findbarButton-previous-rtl@2x.png │ │ │ ├── toolbarButton-menuArrows@2x.png │ │ │ ├── toolbarButton-pageDown-rtl@2x.png │ │ │ ├── toolbarButton-pageUp-rtl@2x.png │ │ │ ├── toolbarButton-sidebarToggle.png │ │ │ ├── toolbarButton-viewAttachments.png │ │ │ ├── toolbarButton-viewOutline-rtl.png │ │ │ ├── toolbarButton-viewOutline@2x.png │ │ │ ├── toolbarButton-viewThumbnail.png │ │ │ ├── secondaryToolbarButton-handTool.png │ │ │ ├── secondaryToolbarButton-lastPage.png │ │ │ ├── secondaryToolbarButton-rotateCw.png │ │ │ ├── toolbarButton-presentationMode.png │ │ │ ├── toolbarButton-sidebarToggle-rtl.png │ │ │ ├── toolbarButton-sidebarToggle@2x.png │ │ │ ├── toolbarButton-viewThumbnail@2x.png │ │ │ ├── secondaryToolbarButton-firstPage.png │ │ │ ├── secondaryToolbarButton-handTool@2x.png │ │ │ ├── secondaryToolbarButton-lastPage@2x.png │ │ │ ├── secondaryToolbarButton-rotateCcw.png │ │ │ ├── secondaryToolbarButton-rotateCw@2x.png │ │ │ ├── toolbarButton-presentationMode@2x.png │ │ │ ├── toolbarButton-sidebarToggle-rtl@2x.png │ │ │ ├── toolbarButton-viewAttachments@2x.png │ │ │ ├── toolbarButton-viewOutline-rtl@2x.png │ │ │ ├── secondaryToolbarButton-firstPage@2x.png │ │ │ ├── secondaryToolbarButton-rotateCcw@2x.png │ │ │ ├── toolbarButton-secondaryToolbarToggle.png │ │ │ ├── toolbarButton-secondaryToolbarToggle@2x.png │ │ │ ├── secondaryToolbarButton-documentProperties.png │ │ │ ├── toolbarButton-secondaryToolbarToggle-rtl.png │ │ │ ├── secondaryToolbarButton-documentProperties@2x.png │ │ │ ├── toolbarButton-secondaryToolbarToggle-rtl@2x.png │ │ │ ├── annotation-noicon.svg │ │ │ ├── annotation-insert.svg │ │ │ ├── annotation-check.svg │ │ │ ├── annotation-newparagraph.svg │ │ │ ├── annotation-comment.svg │ │ │ ├── annotation-paragraph.svg │ │ │ ├── annotation-note.svg │ │ │ ├── annotation-key.svg │ │ │ └── annotation-help.svg │ │ ├── fonts │ │ │ ├── fontello.eot │ │ │ ├── fontello.ttf │ │ │ ├── fontello.woff │ │ │ ├── GrandHotel-Regular.ttf │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── popup.css │ │ └── kthoom.css │ ├── generic_cover.jpg │ ├── js │ │ ├── libs │ │ │ ├── tinymce │ │ │ │ ├── skins │ │ │ │ │ └── lightgray │ │ │ │ │ │ ├── img │ │ │ │ │ │ ├── anchor.gif │ │ │ │ │ │ ├── loader.gif │ │ │ │ │ │ ├── object.gif │ │ │ │ │ │ └── trans.gif │ │ │ │ │ │ ├── fonts │ │ │ │ │ │ ├── tinymce.eot │ │ │ │ │ │ ├── tinymce.ttf │ │ │ │ │ │ ├── tinymce.woff │ │ │ │ │ │ ├── tinymce-small.eot │ │ │ │ │ │ ├── tinymce-small.ttf │ │ │ │ │ │ └── tinymce-small.woff │ │ │ │ │ │ ├── content.inline.min.css │ │ │ │ │ │ └── content.min.css │ │ │ │ └── langs │ │ │ │ │ └── readme.md │ │ │ ├── bootstrap-datepicker │ │ │ │ └── locales │ │ │ │ │ ├── bootstrap-datepicker.zh-CN.min.js │ │ │ │ │ ├── bootstrap-datepicker.es.min.js │ │ │ │ │ ├── bootstrap-datepicker.de.min.js │ │ │ │ │ ├── bootstrap-datepicker.nl.min.js │ │ │ │ │ ├── bootstrap-datepicker.it.min.js │ │ │ │ │ ├── bootstrap-datepicker.ru.min.js │ │ │ │ │ ├── bootstrap-datepicker.fr.min.js │ │ │ │ │ └── bootstrap-datepicker.pl.min.js │ │ │ ├── bootstrap-table │ │ │ │ ├── locale │ │ │ │ │ ├── bootstrap-table-vi-VN.min.js │ │ │ │ │ ├── bootstrap-table-fr-BE.min.js │ │ │ │ │ ├── bootstrap-table-el-GR.min.js │ │ │ │ │ ├── bootstrap-table-es-AR.min.js │ │ │ │ │ ├── bootstrap-table-ko-KR.min.js │ │ │ │ │ ├── bootstrap-table-da-DK.min.js │ │ │ │ │ ├── bootstrap-table-nb-NO.min.js │ │ │ │ │ ├── bootstrap-table-ur-PK.min.js │ │ │ │ │ ├── bootstrap-table-sv-SE.min.js │ │ │ │ │ ├── bootstrap-table-zh-TW.min.js │ │ │ │ │ ├── bootstrap-table-pl-PL.min.js │ │ │ │ │ ├── bootstrap-table-th-TH.min.js │ │ │ │ │ ├── bootstrap-table-ja-JP.min.js │ │ │ │ │ ├── bootstrap-table-ar-SA.min.js │ │ │ │ │ ├── bootstrap-table-es-SP.min.js │ │ │ │ │ ├── bootstrap-table-tr-TR.min.js │ │ │ │ │ ├── bootstrap-table-af-ZA.min.js │ │ │ │ │ ├── bootstrap-table-es-CR.min.js │ │ │ │ │ ├── bootstrap-table-es-NI.min.js │ │ │ │ │ ├── bootstrap-table-he-IL.min.js │ │ │ │ │ ├── bootstrap-table-pt-BR.min.js │ │ │ │ │ ├── bootstrap-table-zh-CN.min.js │ │ │ │ │ ├── bootstrap-table-fa-IR.min.js │ │ │ │ │ ├── bootstrap-table-ka-GE.min.js │ │ │ │ │ ├── bootstrap-table-es-CL.min.js │ │ │ │ │ ├── bootstrap-table-hu-HU.min.js │ │ │ │ │ ├── bootstrap-table-ca-ES.min.js │ │ │ │ │ ├── bootstrap-table-cs-CZ.min.js │ │ │ │ │ ├── bootstrap-table-eu-EU.min.js │ │ │ │ │ ├── bootstrap-table-hr-HR.min.js │ │ │ │ │ ├── bootstrap-table-ro-RO.min.js │ │ │ │ │ ├── bootstrap-table-es-ES.min.js │ │ │ │ │ ├── bootstrap-table-et-EE.min.js │ │ │ │ │ ├── bootstrap-table-pt-PT.min.js │ │ │ │ │ ├── bootstrap-table-ms-MY.min.js │ │ │ │ │ ├── bootstrap-table-en-US.min.js │ │ │ │ │ ├── bootstrap-table-sk-SK.min.js │ │ │ │ │ ├── bootstrap-table-id-ID.min.js │ │ │ │ │ ├── bootstrap-table-it-IT.min.js │ │ │ │ │ ├── bootstrap-table-uz-Latn-UZ.min.js │ │ │ │ │ ├── bootstrap-table-es-MX.min.js │ │ │ │ │ ├── bootstrap-table-nl-NL.min.js │ │ │ │ │ ├── bootstrap-table-de-DE.min.js │ │ │ │ │ ├── bootstrap-table-ru-RU.min.js │ │ │ │ │ ├── bootstrap-table-uk-UA.min.js │ │ │ │ │ └── bootstrap-table-fr-FR.min.js │ │ │ │ └── bootstrap-table-editable.min.js │ │ │ ├── context.min.js │ │ │ ├── screenfull.min.js │ │ │ ├── bootstrap-rating-input.min.js │ │ │ ├── hooks.min.js │ │ │ └── context.js │ │ ├── shelforder.js │ │ ├── reading │ │ │ └── epub.js │ │ ├── details.js │ │ └── table.js │ └── locale │ │ ├── ta-LK │ │ └── viewer.properties │ │ ├── mn │ │ └── viewer.properties │ │ ├── rw │ │ └── viewer.properties │ │ ├── tn │ │ └── viewer.properties │ │ └── tl │ │ └── viewer.properties ├── translations │ ├── iso639.pickle │ ├── de │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ ├── es │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ ├── fr │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ ├── it │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ ├── ja │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ ├── km │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ ├── nl │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ ├── pl │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ ├── ru │ │ └── LC_MESSAGES │ │ │ └── messages.mo │ └── zh_Hans_CN │ │ └── LC_MESSAGES │ │ └── messages.mo ├── templates │ ├── fragment.html │ ├── list.html │ ├── languages.html │ ├── osd.xml │ ├── shelf_order.html │ ├── shelf_edit.html │ ├── register.html │ ├── stats.html │ ├── login.html │ ├── remote_login.html │ ├── discover.html │ ├── json.txt │ ├── tasks.html │ ├── shelf.html │ ├── search.html │ ├── feed.xml │ ├── index.html │ ├── author.html │ ├── read.html │ └── email_edit.html ├── redirect.py ├── uploader.py ├── comic.py ├── cli.py ├── converter.py ├── fb2.py ├── cache_buster.py └── server.py ├── babel.cfg ├── .gitattributes ├── .editorconfig ├── requirements.txt ├── optional-requirements.txt ├── .gitignore ├── cps.py └── .eslintrc /cps/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | -------------------------------------------------------------------------------- /cps/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/favicon.ico -------------------------------------------------------------------------------- /cps/static/img/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/close.png -------------------------------------------------------------------------------- /cps/static/img/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/loader.gif -------------------------------------------------------------------------------- /cps/static/img/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/save.png -------------------------------------------------------------------------------- /cps/static/img/saved.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/saved.png -------------------------------------------------------------------------------- /cps/static/img/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/star.png -------------------------------------------------------------------------------- /babel.cfg: -------------------------------------------------------------------------------- 1 | [python: **.py] 2 | [jinja2: **/templates/**.*ml] 3 | extensions=jinja2.ext.autoescape,jinja2.ext.with_ -------------------------------------------------------------------------------- /cps/static/img/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/settings.png -------------------------------------------------------------------------------- /cps/static/css/images/grab.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/grab.cur -------------------------------------------------------------------------------- /cps/static/generic_cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/generic_cover.jpg -------------------------------------------------------------------------------- /cps/static/img/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/fullscreen.png -------------------------------------------------------------------------------- /cps/static/img/menu-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/menu-icon.png -------------------------------------------------------------------------------- /cps/static/img/settings-s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/settings-s.png -------------------------------------------------------------------------------- /cps/translations/iso639.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/iso639.pickle -------------------------------------------------------------------------------- /cps/static/css/images/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/shadow.png -------------------------------------------------------------------------------- /cps/static/css/fonts/fontello.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/fonts/fontello.eot -------------------------------------------------------------------------------- /cps/static/css/fonts/fontello.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/fonts/fontello.ttf -------------------------------------------------------------------------------- /cps/static/css/fonts/fontello.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/fonts/fontello.woff -------------------------------------------------------------------------------- /cps/static/css/images/grabbing.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/grabbing.cur -------------------------------------------------------------------------------- /cps/static/css/images/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/texture.png -------------------------------------------------------------------------------- /cps/static/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/apple-touch-icon.png -------------------------------------------------------------------------------- /cps/static/img/cancelfullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/cancelfullscreen.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | web.py ident export-subst 2 | cps/static/css/libs/* linguist-vendored 3 | cps/static/js/libs/* linguist-vendored 4 | -------------------------------------------------------------------------------- /cps/static/css/images/loading-icon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/loading-icon.gif -------------------------------------------------------------------------------- /cps/static/css/images/loading-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/loading-small.png -------------------------------------------------------------------------------- /cps/static/img/annotator-icon-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/annotator-icon-sprite.png -------------------------------------------------------------------------------- /cps/static/css/images/loading-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/loading-small@2x.png -------------------------------------------------------------------------------- /cps/static/img/annotator-glyph-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/img/annotator-glyph-sprite.png -------------------------------------------------------------------------------- /cps/templates/fragment.html: -------------------------------------------------------------------------------- 1 |
2 | {% block body %}{% endblock %} 3 |
4 | {% block js %}{% endblock %} 5 | -------------------------------------------------------------------------------- /cps/static/css/fonts/GrandHotel-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/fonts/GrandHotel-Regular.ttf -------------------------------------------------------------------------------- /cps/static/css/images/findbarButton-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/findbarButton-next.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-print.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-print.png -------------------------------------------------------------------------------- /cps/static/css/images/treeitem-collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/treeitem-collapsed.png -------------------------------------------------------------------------------- /cps/static/css/images/treeitem-expanded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/treeitem-expanded.png -------------------------------------------------------------------------------- /cps/translations/de/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/de/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/translations/es/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/es/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/translations/fr/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/fr/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/translations/it/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/it/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/translations/ja/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/ja/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/translations/km/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/km/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/translations/nl/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/nl/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/translations/pl/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/pl/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/translations/ru/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/ru/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/static/css/images/findbarButton-next@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/findbarButton-next@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-pageUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-pageUp.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-search.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-zoomIn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-zoomIn.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-zoomOut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-zoomOut.png -------------------------------------------------------------------------------- /cps/static/css/images/treeitem-collapsed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/treeitem-collapsed@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/treeitem-expanded@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/treeitem-expanded@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/findbarButton-next-rtl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/findbarButton-next-rtl.png -------------------------------------------------------------------------------- /cps/static/css/images/findbarButton-previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/findbarButton-previous.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-bookmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-bookmark.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-download.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-menuArrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-menuArrows.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-openFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-openFile.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-pageDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-pageDown.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-pageUp-rtl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-pageUp-rtl.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-pageUp@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-pageUp@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-print@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-print@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-search@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-zoomIn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-zoomIn@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-zoomOut@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-zoomOut@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/treeitem-collapsed-rtl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/treeitem-collapsed-rtl.png -------------------------------------------------------------------------------- /cps/static/css/images/findbarButton-next-rtl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/findbarButton-next-rtl@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/findbarButton-previous-rtl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/findbarButton-previous-rtl.png -------------------------------------------------------------------------------- /cps/static/css/images/findbarButton-previous@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/findbarButton-previous@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-bookmark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-bookmark@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-download@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-download@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-openFile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-openFile@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-pageDown-rtl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-pageDown-rtl.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-pageDown@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-pageDown@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-viewOutline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-viewOutline.png -------------------------------------------------------------------------------- /cps/static/css/images/treeitem-collapsed-rtl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/treeitem-collapsed-rtl@2x.png -------------------------------------------------------------------------------- /cps/translations/zh_Hans_CN/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /cps/static/css/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /cps/static/css/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /cps/static/css/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /cps/static/css/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /cps/static/css/images/findbarButton-previous-rtl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/findbarButton-previous-rtl@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-menuArrows@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-menuArrows@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-pageDown-rtl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-pageDown-rtl@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-pageUp-rtl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-pageUp-rtl@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-sidebarToggle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-sidebarToggle.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-viewAttachments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-viewAttachments.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-viewOutline-rtl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-viewOutline-rtl.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-viewOutline@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-viewOutline@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-viewThumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-viewThumbnail.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | 8 | [*.{js,py}] 9 | indent_size = 4 10 | -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-handTool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-handTool.png -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-lastPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-lastPage.png -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-rotateCw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-rotateCw.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-presentationMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-presentationMode.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-sidebarToggle-rtl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-sidebarToggle-rtl.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-sidebarToggle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-sidebarToggle@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-viewThumbnail@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-viewThumbnail@2x.png -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/img/anchor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/img/anchor.gif -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/img/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/img/loader.gif -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/img/object.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/img/object.gif -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/img/trans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/img/trans.gif -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-firstPage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-firstPage.png -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-handTool@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-handTool@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-lastPage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-lastPage@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-rotateCcw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-rotateCcw.png -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-rotateCw@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-rotateCw@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-presentationMode@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-presentationMode@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-sidebarToggle-rtl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-sidebarToggle-rtl@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-viewAttachments@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-viewAttachments@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-viewOutline-rtl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-viewOutline-rtl@2x.png -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce.eot -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce.ttf -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-firstPage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-firstPage@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-rotateCcw@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-rotateCcw@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-secondaryToolbarToggle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-secondaryToolbarToggle.png -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce.woff -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-secondaryToolbarToggle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-secondaryToolbarToggle@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-documentProperties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-documentProperties.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-secondaryToolbarToggle-rtl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-secondaryToolbarToggle-rtl.png -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce-small.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce-small.eot -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce-small.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce-small.ttf -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce-small.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/js/libs/tinymce/skins/lightgray/fonts/tinymce-small.woff -------------------------------------------------------------------------------- /cps/static/css/images/secondaryToolbarButton-documentProperties@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/secondaryToolbarButton-documentProperties@2x.png -------------------------------------------------------------------------------- /cps/static/css/images/toolbarButton-secondaryToolbarToggle-rtl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkoivuneva/calibre-web/HEAD/cps/static/css/images/toolbarButton-secondaryToolbarToggle-rtl@2x.png -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/langs/readme.md: -------------------------------------------------------------------------------- 1 | This is where language files should be placed. 2 | 3 | Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/ 4 | -------------------------------------------------------------------------------- /cps/static/css/images/annotation-noicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Babel>=1.3 2 | Flask-Babel>=0.11.1 3 | Flask-Login>=0.3.2 4 | Flask-Principal>=0.3.2 5 | singledispatch>=3.4.0.0 6 | backports_abc>=0.4 7 | Flask>=0.11 8 | iso-639>=0.4.5 9 | PyPDF2==1.26.0 10 | pytz>=2016.10 11 | requests>=2.11.1 12 | SQLAlchemy>=1.1.0 13 | tornado>=4.1 14 | Wand>=0.4.4 15 | unidecode>=0.04.19 16 | -------------------------------------------------------------------------------- /optional-requirements.txt: -------------------------------------------------------------------------------- 1 | # GDrive Integration 2 | google-api-python-client==1.6.1 3 | gevent==1.2.1 4 | greenlet==0.4.12 5 | httplib2==0.9.2 6 | oauth2client==4.0.0 7 | uritemplate==3.0.0 8 | pyasn1-modules==0.0.8 9 | pyasn1==0.1.9 10 | PyDrive==1.3.1 11 | PyYAML==3.12 12 | rsa==3.4.2 13 | six==1.10.0 14 | # goodreads 15 | goodreads>=0.3.2 16 | python-Levenshtein>=0.12.0 17 | # other 18 | lxml==3.7.2 19 | rarfile>=2.7 20 | natsort>=2.2.0 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Python ### 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # Distribution / packaging 8 | .Python 9 | env/ 10 | eggs/ 11 | .eggs/ 12 | *.egg-info/ 13 | .installed.cfg 14 | *.egg 15 | 16 | # calibre-web 17 | *.db 18 | *.log 19 | config.ini 20 | cps/static/[0-9]* 21 | 22 | .idea/ 23 | *.bak 24 | *.log.* 25 | tags 26 | 27 | settings.yaml 28 | gdrive_credentials 29 | 30 | vendor 31 | client_secrets.json 32 | -------------------------------------------------------------------------------- /cps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | 7 | base_path = os.path.dirname(os.path.abspath(__file__)) 8 | # Insert local directories into path 9 | sys.path.append(base_path) 10 | sys.path.append(os.path.join(base_path, 'cps')) 11 | sys.path.append(os.path.join(base_path, 'vendor')) 12 | 13 | from cps.server import Server 14 | 15 | if __name__ == '__main__': 16 | Server.startServer() 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.datepicker.dates["zh-CN"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["周日","周一","周二","周三","周四","周五","周六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今日",clear:"清除",format:"yyyy年mm月dd日",titleFormat:"yyyy年mm月",weekStart:1}}(jQuery); -------------------------------------------------------------------------------- /cps/static/css/images/annotation-insert.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /cps/static/css/images/annotation-check.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /cps/static/css/images/annotation-newparagraph.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.es.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.datepicker.dates.es={days:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"],daysShort:["Dom","Lun","Mar","Mié","Jue","Vie","Sáb"],daysMin:["Do","Lu","Ma","Mi","Ju","Vi","Sa"],months:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],monthsShort:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],today:"Hoy",monthsTitle:"Meses",clear:"Borrar",weekStart:1,format:"dd/mm/yyyy"}}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.de.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.datepicker.dates.de={days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],daysShort:["Son","Mon","Die","Mit","Don","Fre","Sam"],daysMin:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",monthsTitle:"Monate",clear:"Löschen",weekStart:1,format:"dd.mm.yyyy"}}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.nl.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.datepicker.dates.nl={days:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],daysShort:["zo","ma","di","wo","do","vr","za"],daysMin:["zo","ma","di","wo","do","vr","za"],months:["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"],monthsShort:["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec"],today:"Vandaag",monthsTitle:"Maanden",clear:"Wissen",weekStart:1,format:"dd-mm-yyyy"}}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.it.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.datepicker.dates.it={days:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],daysShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],daysMin:["Do","Lu","Ma","Me","Gi","Ve","Sa"],months:["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],monthsShort:["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],today:"Oggi",monthsTitle:"Mesi",clear:"Cancella",weekStart:1,format:"dd/mm/yyyy"}}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.ru.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.datepicker.dates.ru={days:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],daysShort:["Вск","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],today:"Сегодня",clear:"Очистить",format:"dd.mm.yyyy",weekStart:1,monthsTitle:"Месяцы"}}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.fr.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.datepicker.dates.fr={days:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],daysShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],daysMin:["d","l","ma","me","j","v","s"],months:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthsShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],today:"Aujourd'hui",monthsTitle:"Mois",clear:"Effacer",weekStart:1,format:"dd/mm/yyyy"}}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.pl.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.datepicker.dates.pl={days:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],daysShort:["Niedz.","Pon.","Wt.","Śr.","Czw.","Piąt.","Sob."],daysMin:["Ndz.","Pn.","Wt.","Śr.","Czw.","Pt.","Sob."],months:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthsShort:["Sty.","Lut.","Mar.","Kwi.","Maj","Cze.","Lip.","Sie.","Wrz.","Paź.","Lis.","Gru."],today:"Dzisiaj",weekStart:1,clear:"Wyczyść",format:"dd.mm.yyyy"}}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-vi-VN.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["vi-VN"]={formatLoadingMessage:function(){return"Đang tải..."},formatRecordsPerPage:function(a){return a+" bản ghi mỗi trang"},formatShowingRows:function(a,b,c){return"Hiển thị từ trang "+a+" đến "+b+" của "+c+" bảng ghi"},formatSearch:function(){return"Tìm kiếm"},formatNoMatches:function(){return"Không có dữ liệu"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["vi-VN"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fr-BE.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["fr-BE"]={formatLoadingMessage:function(){return"Chargement en cours..."},formatRecordsPerPage:function(a){return a+" entrées par page"},formatShowingRows:function(a,b,c){return"Affiche de"+a+" à "+b+" sur "+c+" lignes"},formatSearch:function(){return"Recherche"},formatNoMatches:function(){return"Pas de fichiers trouvés"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["fr-BE"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-el-GR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["el-GR"]={formatLoadingMessage:function(){return"Φορτώνει, παρακαλώ περιμένετε..."},formatRecordsPerPage:function(a){return a+" αποτελέσματα ανά σελίδα"},formatShowingRows:function(a,b,c){return"Εμφανίζονται από την "+a+" ως την "+b+" από σύνολο "+c+" σειρών"},formatSearch:function(){return"Αναζητήστε"},formatNoMatches:function(){return"Δεν βρέθηκαν αποτελέσματα"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["el-GR"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-es-AR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["es-AR"]={formatLoadingMessage:function(){return"Cargando, espere por favor..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Mostrando "+a+" a "+b+" de "+c+" filas"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-AR"])}(jQuery); -------------------------------------------------------------------------------- /cps/templates/list.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |

{{title}}

4 |
5 |
6 | {% for entry in entries %} 7 | {% if loop.index0 == (loop.length/2)|int and loop.length > 20 %} 8 |
9 |
10 | {% endif %} 11 |
12 |
{{entry.count}}
13 | 14 |
15 | {% endfor %} 16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /cps/templates/languages.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |

{{title}}

4 |
5 |
6 | {% for lang in languages %} 7 | {% if loop.index0 == (loop.length/2)|int and loop.length > 20 %} 8 |
9 |
10 | {% endif %} 11 |
12 |
{{lang_counter[loop.index0].bookcount}}
13 | 14 |
15 | {% endfor %} 16 |
17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ko-KR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ko-KR"]={formatLoadingMessage:function(){return"데이터를 불러오는 중입니다..."},formatRecordsPerPage:function(a){return"페이지 당 "+a+"개 데이터 출력"},formatShowingRows:function(a,b,c){return"전체 "+c+"개 중 "+a+"~"+b+"번째 데이터 출력,"},formatSearch:function(){return"검색"},formatNoMatches:function(){return"조회된 데이터가 없습니다."},formatRefresh:function(){return"새로 고침"},formatToggle:function(){return"전환"},formatColumns:function(){return"컬럼 필터링"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ko-KR"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-da-DK.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["da-DK"]={formatLoadingMessage:function(){return"Indlæser, vent venligst..."},formatRecordsPerPage:function(a){return a+" poster pr side"},formatShowingRows:function(a,b,c){return"Viser "+a+" til "+b+" af "+c+" rækker"},formatSearch:function(){return"Søg"},formatNoMatches:function(){return"Ingen poster fundet"},formatRefresh:function(){return"Opdater"},formatToggle:function(){return"Skift"},formatColumns:function(){return"Kolonner"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["da-DK"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-nb-NO.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["nb-NO"]={formatLoadingMessage:function(){return"Oppdaterer, vennligst vent..."},formatRecordsPerPage:function(a){return a+" poster pr side"},formatShowingRows:function(a,b,c){return"Viser "+a+" til "+b+" av "+c+" rekker"},formatSearch:function(){return"Søk"},formatNoMatches:function(){return"Ingen poster funnet"},formatRefresh:function(){return"Oppdater"},formatToggle:function(){return"Endre"},formatColumns:function(){return"Kolonner"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["nb-NO"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ur-PK.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ur-PK"]={formatLoadingMessage:function(){return"براۓ مہربانی انتظار کیجئے"},formatRecordsPerPage:function(a){return a+" ریکارڈز فی صفہ "},formatShowingRows:function(a,b,c){return"دیکھیں "+a+" سے "+b+" کے "+c+"ریکارڈز"},formatSearch:function(){return"تلاش"},formatNoMatches:function(){return"کوئی ریکارڈ نہیں ملا"},formatRefresh:function(){return"تازہ کریں"},formatToggle:function(){return"تبدیل کریں"},formatColumns:function(){return"کالم"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ur-PK"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-sv-SE.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["sv-SE"]={formatLoadingMessage:function(){return"Laddar, vänligen vänta..."},formatRecordsPerPage:function(a){return a+" rader per sida"},formatShowingRows:function(a,b,c){return"Visa "+a+" till "+b+" av "+c+" rader"},formatSearch:function(){return"Sök"},formatNoMatches:function(){return"Inga matchande resultat funna."},formatRefresh:function(){return"Uppdatera"},formatToggle:function(){return"Skifta"},formatColumns:function(){return"kolumn"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["sv-SE"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-zh-TW.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["zh-TW"]={formatLoadingMessage:function(){return"正在努力地載入資料,請稍候……"},formatRecordsPerPage:function(a){return"每頁顯示 "+a+" 項記錄"},formatShowingRows:function(a,b,c){return"顯示第 "+a+" 到第 "+b+" 項記錄,總共 "+c+" 項記錄"},formatSearch:function(){return"搜尋"},formatNoMatches:function(){return"沒有找到符合的結果"},formatPaginationSwitch:function(){return"隱藏/顯示分頁"},formatRefresh:function(){return"重新整理"},formatToggle:function(){return"切換"},formatColumns:function(){return"列"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["zh-TW"])}(jQuery); -------------------------------------------------------------------------------- /cps/templates/osd.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{instance}} 4 | {{instance}} 5 | {{_('Calibre-Web ebook catalog')}} 6 | Janeczku 7 | https://github.com/janeczku/calibre-web 8 | 10 | 12 | open 13 | {{lang}} 14 | UTF-8 15 | UTF-8 16 | 17 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-pl-PL.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["pl-PL"]={formatLoadingMessage:function(){return"Ładowanie, proszę czekać..."},formatRecordsPerPage:function(a){return a+" rekordów na stronę"},formatShowingRows:function(a,b,c){return"Wyświetlanie rekordów od "+a+" do "+b+" z "+c},formatSearch:function(){return"Szukaj"},formatNoMatches:function(){return"Niestety, nic nie znaleziono"},formatRefresh:function(){return"Odśwież"},formatToggle:function(){return"Przełącz"},formatColumns:function(){return"Kolumny"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["pl-PL"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-th-TH.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["th-TH"]={formatLoadingMessage:function(){return"กำลังโหลดข้อมูล, กรุณารอสักครู่..."},formatRecordsPerPage:function(a){return a+" รายการต่อหน้า"},formatShowingRows:function(a,b,c){return"รายการที่ "+a+" ถึง "+b+" จากทั้งหมด "+c+" รายการ"},formatSearch:function(){return"ค้นหา"},formatNoMatches:function(){return"ไม่พบรายการที่ค้นหา !"},formatRefresh:function(){return"รีเฟรส"},formatToggle:function(){return"สลับมุมมอง"},formatColumns:function(){return"คอลัมน์"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["th-TH"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ja-JP.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ja-JP"]={formatLoadingMessage:function(){return"読み込み中です。少々お待ちください。"},formatRecordsPerPage:function(a){return"ページ当たり最大"+a+"件"},formatShowingRows:function(a,b,c){return"全"+c+"件から、"+a+"から"+b+"件目まで表示しています"},formatSearch:function(){return"検索"},formatNoMatches:function(){return"該当するレコードが見つかりません"},formatPaginationSwitch:function(){return"ページ数を表示・非表示"},formatRefresh:function(){return"更新"},formatToggle:function(){return"トグル"},formatColumns:function(){return"列"},formatAllRows:function(){return"すべて"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ja-JP"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ar-SA.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ar-SA"]={formatLoadingMessage:function(){return"جاري التحميل, يرجى الإنتظار..."},formatRecordsPerPage:function(a){return a+" سجل لكل صفحة"},formatShowingRows:function(a,b,c){return"الظاهر "+a+" إلى "+b+" من "+c+" سجل"},formatSearch:function(){return"بحث"},formatNoMatches:function(){return"لا توجد نتائج مطابقة للبحث"},formatPaginationSwitch:function(){return"إخفاءإظهار ترقيم الصفحات"},formatRefresh:function(){return"تحديث"},formatToggle:function(){return"تغيير"},formatColumns:function(){return"أعمدة"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ar-SA"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-es-SP.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["es-SP"]={formatLoadingMessage:function(){return"Cargando, por favor espera..."},formatRecordsPerPage:function(a){return a+" registros por página."},formatShowingRows:function(a,b,c){return a+" - "+b+" de "+c+" registros."},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se han encontrado registros."},formatRefresh:function(){return"Actualizar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-SP"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-tr-TR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["tr-TR"]={formatLoadingMessage:function(){return"Yükleniyor, lütfen bekleyin..."},formatRecordsPerPage:function(a){return"Sayfa başına "+a+" kayıt."},formatShowingRows:function(a,b,c){return c+" kayıttan "+a+"-"+b+" arası gösteriliyor."},formatSearch:function(){return"Ara"},formatNoMatches:function(){return"Eşleşen kayıt bulunamadı."},formatRefresh:function(){return"Yenile"},formatToggle:function(){return"Değiştir"},formatColumns:function(){return"Sütunlar"},formatAllRows:function(){return"Tüm Satırlar"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["tr-TR"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-af-ZA.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["af-ZA"]={formatLoadingMessage:function(){return"Besig om te laai, wag asseblief ..."},formatRecordsPerPage:function(a){return a+" rekords per bladsy"},formatShowingRows:function(a,b,c){return"Resultate "+a+" tot "+b+" van "+c+" rye"},formatSearch:function(){return"Soek"},formatNoMatches:function(){return"Geen rekords gevind nie"},formatPaginationSwitch:function(){return"Wys/verberg bladsy nummering"},formatRefresh:function(){return"Herlaai"},formatToggle:function(){return"Wissel"},formatColumns:function(){return"Kolomme"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["af-ZA"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-es-CR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["es-CR"]={formatLoadingMessage:function(){return"Cargando, por favor espere..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Mostrando de "+a+" a "+b+" registros de "+c+" registros en total"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatRefresh:function(){return"Refrescar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-CR"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-es-NI.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["es-NI"]={formatLoadingMessage:function(){return"Cargando, por favor espere..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Mostrando de "+a+" a "+b+" registros de "+c+" registros en total"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatRefresh:function(){return"Refrescar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-NI"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-he-IL.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["he-IL"]={formatLoadingMessage:function(){return"טוען, נא להמתין..."},formatRecordsPerPage:function(a){return a+" שורות בעמוד"},formatShowingRows:function(a,b,c){return"מציג "+a+" עד "+b+" מ-"+c+" שורות"},formatSearch:function(){return"חיפוש"},formatNoMatches:function(){return"לא נמצאו רשומות תואמות"},formatPaginationSwitch:function(){return"הסתר/הצג מספור דפים"},formatRefresh:function(){return"רענן"},formatToggle:function(){return"החלף תצוגה"},formatColumns:function(){return"עמודות"},formatAllRows:function(){return"הכל"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["he-IL"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-pt-BR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["pt-BR"]={formatLoadingMessage:function(){return"Carregando, aguarde..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Exibindo "+a+" até "+b+" de "+c+" linhas"},formatSearch:function(){return"Pesquisar"},formatRefresh:function(){return"Recarregar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Colunas"},formatPaginationSwitch:function(){return"Ocultar/Exibir paginação"},formatNoMatches:function(){return"Nenhum registro encontrado"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["pt-BR"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-zh-CN.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["zh-CN"]={formatLoadingMessage:function(){return"正在努力地加载数据中,请稍候……"},formatRecordsPerPage:function(a){return"每页显示 "+a+" 条记录"},formatShowingRows:function(a,b,c){return"显示第 "+a+" 到第 "+b+" 条记录,总共 "+c+" 条记录"},formatSearch:function(){return"搜索"},formatNoMatches:function(){return"没有找到匹配的记录"},formatPaginationSwitch:function(){return"隐藏/显示分页"},formatRefresh:function(){return"刷新"},formatToggle:function(){return"切换"},formatColumns:function(){return"列"},formatExport:function(){return"导出数据"},formatClearFilters:function(){return"清空过滤"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["zh-CN"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fa-IR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["fa-IR"]={formatLoadingMessage:function(){return"در حال بارگذاری, لطفا صبر کنید..."},formatRecordsPerPage:function(a){return a+" رکورد در صفحه"},formatShowingRows:function(a,b,c){return"نمایش "+a+" تا "+b+" از "+c+" ردیف"},formatSearch:function(){return"جستجو"},formatNoMatches:function(){return"رکوردی یافت نشد."},formatPaginationSwitch:function(){return"نمایش/مخفی صفحه بندی"},formatRefresh:function(){return"به روز رسانی"},formatToggle:function(){return"تغییر نمایش"},formatColumns:function(){return"سطر ها"},formatAllRows:function(){return"همه"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["fa-IR"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ka-GE.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ka-GE"]={formatLoadingMessage:function(){return"იტვირთება, გთხოვთ მოიცადოთ..."},formatRecordsPerPage:function(a){return a+" ჩანაწერი თითო გვერდზე"},formatShowingRows:function(a,b,c){return"ნაჩვენებია "+a+"-დან "+b+"-მდე ჩანაწერი ჯამური "+c+"-დან"},formatSearch:function(){return"ძებნა"},formatNoMatches:function(){return"მონაცემები არ არის"},formatPaginationSwitch:function(){return"გვერდების გადამრთველის დამალვა/გამოჩენა"},formatRefresh:function(){return"განახლება"},formatToggle:function(){return"ჩართვა/გამორთვა"},formatColumns:function(){return"სვეტები"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ka-GE"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-es-CL.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["es-CL"]={formatLoadingMessage:function(){return"Cargando, espere por favor..."},formatRecordsPerPage:function(a){return a+" filas por página"},formatShowingRows:function(a,b,c){return"Mostrando "+a+" a "+b+" de "+c+" filas"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros"},formatPaginationSwitch:function(){return"Ocultar/Mostrar paginación"},formatRefresh:function(){return"Refrescar"},formatToggle:function(){return"Cambiar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-CL"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-hu-HU.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["hu-HU"]={formatLoadingMessage:function(){return"Betöltés, kérem várjon..."},formatRecordsPerPage:function(a){return a+" rekord per oldal"},formatShowingRows:function(a,b,c){return"Megjelenítve "+a+" - "+b+" / "+c+" összesen"},formatSearch:function(){return"Keresés"},formatNoMatches:function(){return"Nincs találat"},formatPaginationSwitch:function(){return"Lapozó elrejtése/megjelenítése"},formatRefresh:function(){return"Frissítés"},formatToggle:function(){return"Összecsuk/Kinyit"},formatColumns:function(){return"Oszlopok"},formatAllRows:function(){return"Összes"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["hu-HU"])}(jQuery); -------------------------------------------------------------------------------- /cps/redirect.py: -------------------------------------------------------------------------------- 1 | # http://flask.pocoo.org/snippets/62/ 2 | 3 | try: 4 | from urllib.parse import urlparse, urljoin 5 | except ImportError: 6 | from urlparse import urlparse, urljoin 7 | from flask import request, url_for, redirect 8 | 9 | 10 | def is_safe_url(target): 11 | ref_url = urlparse(request.host_url) 12 | test_url = urlparse(urljoin(request.host_url, target)) 13 | return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc 14 | 15 | 16 | def get_redirect_target(): 17 | for target in request.values.get('next'), request.referrer: 18 | if not target: 19 | continue 20 | if is_safe_url(target): 21 | return target 22 | 23 | 24 | def redirect_back(endpoint, **values): 25 | target = request.form['next'] 26 | if not target or not is_safe_url(target): 27 | target = url_for(endpoint, **values) 28 | return redirect(target) 29 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ca-ES.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ca-ES"]={formatLoadingMessage:function(){return"Espereu, si us plau..."},formatRecordsPerPage:function(a){return a+" resultats per pàgina"},formatShowingRows:function(a,b,c){return"Mostrant de "+a+" fins "+b+" - total "+c+" resultats"},formatSearch:function(){return"Cerca"},formatNoMatches:function(){return"No s'han trobat resultats"},formatPaginationSwitch:function(){return"Amaga/Mostra paginació"},formatRefresh:function(){return"Refresca"},formatToggle:function(){return"Alterna formatació"},formatColumns:function(){return"Columnes"},formatAllRows:function(){return"Tots"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ca-ES"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-cs-CZ.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["cs-CZ"]={formatLoadingMessage:function(){return"Čekejte, prosím..."},formatRecordsPerPage:function(a){return a+" položek na stránku"},formatShowingRows:function(a,b,c){return"Zobrazena "+a+". - "+b+". položka z celkových "+c},formatSearch:function(){return"Vyhledávání"},formatNoMatches:function(){return"Nenalezena žádná vyhovující položka"},formatPaginationSwitch:function(){return"Skrýt/Zobrazit stránkování"},formatRefresh:function(){return"Aktualizovat"},formatToggle:function(){return"Přepni"},formatColumns:function(){return"Sloupce"},formatAllRows:function(){return"Vše"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["cs-CZ"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-eu-EU.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["eu-EU"]={formatLoadingMessage:function(){return"Itxaron mesedez..."},formatRecordsPerPage:function(a){return a+" emaitza orriko."},formatShowingRows:function(a,b,c){return c+" erregistroetatik "+a+"etik "+b+"erakoak erakusten."},formatSearch:function(){return"Bilatu"},formatNoMatches:function(){return"Ez da emaitzarik aurkitu"},formatPaginationSwitch:function(){return"Ezkutatu/Erakutsi orrikatzea"},formatRefresh:function(){return"Eguneratu"},formatToggle:function(){return"Ezkutatu/Erakutsi"},formatColumns:function(){return"Zutabeak"},formatAllRows:function(){return"Guztiak"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["eu-EU"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-hr-HR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["hr-HR"]={formatLoadingMessage:function(){return"Molimo pričekajte ..."},formatRecordsPerPage:function(a){return a+" broj zapisa po stranici"},formatShowingRows:function(a,b,c){return"Prikazujem "+a+". - "+b+". od ukupnog broja zapisa "+c},formatSearch:function(){return"Pretraži"},formatNoMatches:function(){return"Nije pronađen niti jedan zapis"},formatPaginationSwitch:function(){return"Prikaži/sakrij stranice"},formatRefresh:function(){return"Osvježi"},formatToggle:function(){return"Promijeni prikaz"},formatColumns:function(){return"Kolone"},formatAllRows:function(){return"Sve"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["hr-HR"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ro-RO.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ro-RO"]={formatLoadingMessage:function(){return"Se incarca, va rugam asteptati..."},formatRecordsPerPage:function(a){return a+" inregistrari pe pagina"},formatShowingRows:function(a,b,c){return"Arata de la "+a+" pana la "+b+" din "+c+" randuri"},formatSearch:function(){return"Cauta"},formatNoMatches:function(){return"Nu au fost gasite inregistrari"},formatPaginationSwitch:function(){return"Ascunde/Arata paginatia"},formatRefresh:function(){return"Reincarca"},formatToggle:function(){return"Comuta"},formatColumns:function(){return"Coloane"},formatAllRows:function(){return"Toate"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ro-RO"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-es-ES.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["es-ES"]={formatLoadingMessage:function(){return"Por favor espere..."},formatRecordsPerPage:function(a){return a+" resultados por página"},formatShowingRows:function(a,b,c){return"Mostrando desde "+a+" hasta "+b+" - En total "+c+" resultados"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron resultados"},formatPaginationSwitch:function(){return"Ocultar/Mostrar paginación"},formatRefresh:function(){return"Refrescar"},formatToggle:function(){return"Ocultar/Mostrar"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todos"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-ES"])}(jQuery); -------------------------------------------------------------------------------- /cps/uploader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | from tempfile import gettempdir 6 | import hashlib 7 | from collections import namedtuple 8 | import book_formats 9 | 10 | BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, description, tags, series, series_id, languages') 11 | 12 | """ 13 | :rtype: BookMeta 14 | """ 15 | 16 | 17 | def upload(uploadfile): 18 | tmp_dir = os.path.join(gettempdir(), 'calibre_web') 19 | 20 | if not os.path.isdir(tmp_dir): 21 | os.mkdir(tmp_dir) 22 | 23 | filename = uploadfile.filename 24 | filename_root, file_extension = os.path.splitext(filename) 25 | md5 = hashlib.md5() 26 | md5.update(filename.encode('utf-8')) 27 | tmp_file_path = os.path.join(tmp_dir, md5.hexdigest()) 28 | uploadfile.save(tmp_file_path) 29 | meta = book_formats.process(tmp_file_path, filename_root, file_extension) 30 | return meta 31 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-et-EE.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["et-EE"]={formatLoadingMessage:function(){return"Päring käib, palun oota..."},formatRecordsPerPage:function(a){return a+" rida lehe kohta"},formatShowingRows:function(a,b,c){return"Näitan tulemusi "+a+" kuni "+b+" - kokku "+c+" tulemust"},formatSearch:function(){return"Otsi"},formatNoMatches:function(){return"Päringu tingimustele ei vastanud ühtegi tulemust"},formatPaginationSwitch:function(){return"Näita/Peida lehtedeks jagamine"},formatRefresh:function(){return"Värskenda"},formatToggle:function(){return"Lülita"},formatColumns:function(){return"Veerud"},formatAllRows:function(){return"Kõik"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["et-EE"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-pt-PT.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["pt-PT"]={formatLoadingMessage:function(){return"A carregar, por favor aguarde..."},formatRecordsPerPage:function(a){return a+" registos por página"},formatShowingRows:function(a,b,c){return"A mostrar "+a+" até "+b+" de "+c+" linhas"},formatSearch:function(){return"Pesquisa"},formatNoMatches:function(){return"Nenhum registo encontrado"},formatPaginationSwitch:function(){return"Esconder/Mostrar paginação"},formatRefresh:function(){return"Atualizar"},formatToggle:function(){return"Alternar"},formatColumns:function(){return"Colunas"},formatAllRows:function(){return"Tudo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["pt-PT"])}(jQuery); -------------------------------------------------------------------------------- /cps/templates/shelf_order.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |

{{title}}

5 |
{{_('Drag \'n drop to rearrange order')}}
6 |
7 | {% for entry in entries %} 8 |
{{entry.title}}
9 | {% endfor %} 10 |
11 | 12 | {{_('Back')}} 13 |
14 | {% endblock %} 15 | 16 | {% block js %} 17 | 18 | 19 | {% endblock %} 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /cps/templates/shelf_edit.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |

{{title}}

5 |
6 |
7 | 8 | 9 |
10 | {% if g.user.role_edit_shelfs() %} 11 |
12 | 15 |
16 | {% endif %} 17 | 18 | {% if shelf.id != None %} 19 | {{_('Back')}} 20 | {% endif %} 21 |
22 |
23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /cps/static/css/images/annotation-comment.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ms-MY.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ms-MY"]={formatLoadingMessage:function(){return"Permintaan sedang dimuatkan. Sila tunggu sebentar..."},formatRecordsPerPage:function(a){return a+" rekod setiap muka surat"},formatShowingRows:function(a,b,c){return"Sedang memaparkan rekod "+a+" hingga "+b+" daripada jumlah "+c+" rekod"},formatSearch:function(){return"Cari"},formatNoMatches:function(){return"Tiada rekod yang menyamai permintaan"},formatPaginationSwitch:function(){return"Tunjuk/sembunyi muka surat"},formatRefresh:function(){return"Muatsemula"},formatToggle:function(){return"Tukar"},formatColumns:function(){return"Lajur"},formatAllRows:function(){return"Semua"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ms-MY"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-en-US.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["en-US"]={formatLoadingMessage:function(){return"Loading, please wait..."},formatRecordsPerPage:function(a){return a+" rows per page"},formatShowingRows:function(a,b,c){return"Showing "+a+" to "+b+" of "+c+" rows"},formatSearch:function(){return"Search"},formatNoMatches:function(){return"No matching records found"},formatPaginationSwitch:function(){return"Hide/Show pagination"},formatRefresh:function(){return"Refresh"},formatToggle:function(){return"Toggle"},formatColumns:function(){return"Columns"},formatAllRows:function(){return"All"},formatExport:function(){return"Export data"},formatClearFilters:function(){return"Clear filters"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["en-US"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-sk-SK.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["sk-SK"]={formatLoadingMessage:function(){return"Prosím čakajte ..."},formatRecordsPerPage:function(a){return a+" záznamov na stranu"},formatShowingRows:function(a,b,c){return"Zobrazená "+a+". - "+b+". položka z celkových "+c},formatSearch:function(){return"Vyhľadávanie"},formatNoMatches:function(){return"Nenájdená žiadna vyhovujúca položka"},formatPaginationSwitch:function(){return"Skry/Zobraz stránkovanie"},formatRefresh:function(){return"Obnoviť"},formatToggle:function(){return"Prepni"},formatColumns:function(){return"Stĺpce"},formatAllRows:function(){return"Všetky"},formatExport:function(){return"Exportuj dáta"},formatClearFilters:function(){return"Odstráň filtre"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["sk-SK"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-id-ID.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["id-ID"]={formatLoadingMessage:function(){return"Memuat, mohon tunggu..."},formatRecordsPerPage:function(a){return a+" baris per halaman"},formatShowingRows:function(a,b,c){return"Menampilkan "+a+" sampai "+b+" dari "+c+" baris"},formatSearch:function(){return"Pencarian"},formatNoMatches:function(){return"Tidak ditemukan data yang cocok"},formatPaginationSwitch:function(){return"Sembunyikan/Tampilkan halaman"},formatRefresh:function(){return"Muat ulang"},formatToggle:function(){return"Beralih"},formatColumns:function(){return"kolom"},formatAllRows:function(){return"Semua"},formatExport:function(){return"Ekspor data"},formatClearFilters:function(){return"Bersihkan filter"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["id-ID"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-it-IT.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["it-IT"]={formatLoadingMessage:function(){return"Caricamento in corso..."},formatRecordsPerPage:function(a){return a+" elementi per pagina"},formatShowingRows:function(a,b,c){return"Elementi mostrati da "+a+" a "+b+" (Numero totali di elementi "+c+")"},formatSearch:function(){return"Cerca"},formatNoMatches:function(){return"Nessun elemento trovato"},formatPaginationSwitch:function(){return"Nascondi/Mostra paginazione"},formatRefresh:function(){return"Aggiorna"},formatToggle:function(){return"Attiva/Disattiva"},formatColumns:function(){return"Colonne"},formatAllRows:function(){return"Tutto"},formatExport:function(){return"Esporta dati"},formatClearFilters:function(){return"Pulisci filtri"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["it-IT"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-uz-Latn-UZ.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["uz-Latn-UZ"]={formatLoadingMessage:function(){return"Yuklanyapti, iltimos kuting..."},formatRecordsPerPage:function(a){return a+" qator har sahifada"},formatShowingRows:function(a,b,c){return"Ko'rsatypati "+a+" dan "+b+" gacha "+c+" qatorlarni"},formatSearch:function(){return"Qidirish"},formatNoMatches:function(){return"Hech narsa topilmadi"},formatPaginationSwitch:function(){return"Sahifalashni yashirish/ko'rsatish"},formatRefresh:function(){return"Yangilash"},formatToggle:function(){return"Ko'rinish"},formatColumns:function(){return"Ustunlar"},formatAllRows:function(){return"Hammasi"},formatExport:function(){return"Eksport"},formatClearFilters:function(){return"Filtrlarni tozalash"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["uz-Latn-UZ"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-es-MX.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["es-MX"]={formatLoadingMessage:function(){return"Cargando, espere por favor..."},formatRecordsPerPage:function(a){return a+" registros por página"},formatShowingRows:function(a,b,c){return"Mostrando "+a+" a "+b+" de "+c+" filas"},formatDetailPagination:function(a){return"Mostrando "+a+" filas"},formatSearch:function(){return"Buscar"},formatNoMatches:function(){return"No se encontraron registros que coincidan"},formatPaginationSwitch:function(){return"Mostrar/ocultar paginación"},formatRefresh:function(){return"Actualizar"},formatToggle:function(){return"Cambiar vista"},formatFullscreen:function(){return"Pantalla completa"},formatColumns:function(){return"Columnas"},formatAllRows:function(){return"Todo"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["es-MX"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/shelforder.js: -------------------------------------------------------------------------------- 1 | /* global Sortable,sortTrue */ 2 | 3 | Sortable.create(sortTrue, { 4 | group: "sorting", 5 | sort: true 6 | }); 7 | 8 | // eslint-disable-next-line no-unused-vars 9 | function sendData(path) { 10 | var elements; 11 | var counter; 12 | var maxElements; 13 | var tmp = []; 14 | 15 | elements = Sortable.utils.find(sortTrue, "div"); 16 | maxElements = elements.length; 17 | 18 | var form = document.createElement("form"); 19 | form.setAttribute("method", "post"); 20 | form.setAttribute("action", path); 21 | 22 | for (counter = 0;counter < maxElements;counter++) { 23 | tmp[counter] = elements[counter].getAttribute("id"); 24 | var hiddenField = document.createElement("input"); 25 | hiddenField.setAttribute("type", "hidden"); 26 | hiddenField.setAttribute("name", elements[counter].getAttribute("id")); 27 | hiddenField.setAttribute("value", String(counter + 1)); 28 | form.appendChild(hiddenField); 29 | } 30 | document.body.appendChild(form); 31 | form.submit(); 32 | } 33 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-nl-NL.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["nl-NL"]={formatLoadingMessage:function(){return"Laden, even geduld..."},formatRecordsPerPage:function(a){return a+" records per pagina"},formatShowingRows:function(a,b,c){return"Toon "+a+" tot "+b+" van "+c+" record"+(c>1?"s":"")},formatDetailPagination:function(a){return"Toon "+a+" record"+(a>1?"s":"")},formatSearch:function(){return"Zoeken"},formatNoMatches:function(){return"Geen resultaten gevonden"},formatRefresh:function(){return"Vernieuwen"},formatToggle:function(){return"Omschakelen"},formatColumns:function(){return"Kolommen"},formatAllRows:function(){return"Alle"},formatPaginationSwitch:function(){return"Verberg/Toon paginatie"},formatExport:function(){return"Exporteer data"},formatClearFilters:function(){return"Verwijder filters"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["nl-NL"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-de-DE.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["de-DE"]={formatLoadingMessage:function(){return"Lade, bitte warten..."},formatRecordsPerPage:function(a){return a+" Zeilen pro Seite."},formatShowingRows:function(a,b,c){return"Zeige Zeile "+a+" bis "+b+" von "+c+" Zeilen"+(c>1?"n":"")+"."},formatDetailPagination:function(a){return"Zeige "+a+" Zeile"+(a>1?"n":"")+"."},formatSearch:function(){return"Suchen"},formatNoMatches:function(){return"Keine passenden Ergebnisse gefunden"},formatPaginationSwitch:function(){return"Verstecke/Zeige Nummerierung"},formatRefresh:function(){return"Neu laden"},formatToggle:function(){return"Umschalten"},formatColumns:function(){return"Spalten"},formatAllRows:function(){return"Alle"},formatExport:function(){return"Datenexport"},formatClearFilters:function(){return"Lösche Filter"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["de-DE"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/css/images/annotation-paragraph.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /cps/templates/register.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |

{{_('Register a new account')}}

5 |
6 |
7 | 8 | 9 |
10 | 14 |
15 | 16 | 17 |
18 | 19 |
20 |
21 | {% if error %} 22 |
23 |
{{error}}
24 |
25 | {% endif %} 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /cps/static/css/images/annotation-note.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 14 | 21 | 28 | 35 | 42 | 43 | -------------------------------------------------------------------------------- /cps/templates/stats.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |

{{_('About')}}

4 |

{{instance}} powered by 5 | Calibre-Web. 6 |

7 |

{{_('Calibre library statistics')}}

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
{{bookcounter}}{{_('Books in this Library')}}
{{authorcounter}}{{_('Authors in this Library')}}
{{categorycounter}}{{_('Categories in this Library')}}
{{seriecounter}}{{_('Series in this Library')}}
28 |

{{_('Linked libraries')}}

29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {% for library,version in versions.items() %} 38 | 39 | 40 | 41 | 42 | {% endfor %} 43 | 44 |
{{_('Program library')}}{{_('Installed Version')}}
{{library}}{{version}}
45 | {% endblock %} 46 | -------------------------------------------------------------------------------- /cps/templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |

{{_('Login')}}

5 |
6 | 7 |
8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 |
16 | 19 |
20 | 21 | {% if remote_login %} 22 | {{_('Log in with magic link')}} 23 | {% endif %} 24 |
25 |
26 | {% if error %} 27 |
28 |
{{error}}
29 |
30 | {% endif %} 31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /cps/templates/remote_login.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |

{{_('Remote login')}}

5 |

6 | {{_('Using your another device, visit')}} {{verify_url}} {{_('and log in')}}. 7 |

8 |

9 | {{_('Once you do so, you will automatically get logged in on this device.')}} 10 |

11 |

12 | {{_('The link will expire after %s minutes.' % 10)}} 13 |

14 |
15 | {% endblock %} 16 | 17 | {% block js %} 18 | 40 | {% endblock %} 41 | -------------------------------------------------------------------------------- /cps/comic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import zipfile 5 | import tarfile 6 | import os 7 | import uploader 8 | 9 | 10 | def extractCover(tmp_file_name, original_file_extension): 11 | if original_file_extension.upper() == '.CBZ': 12 | cf = zipfile.ZipFile(tmp_file_name) 13 | compressed_name = cf.namelist()[0] 14 | cover_data = cf.read(compressed_name) 15 | elif original_file_extension.upper() == '.CBT': 16 | cf = tarfile.TarFile(tmp_file_name) 17 | compressed_name = cf.getnames()[0] 18 | cover_data = cf.extractfile(compressed_name).read() 19 | 20 | prefix = os.path.dirname(tmp_file_name) 21 | 22 | tmp_cover_name = prefix + '/cover' + os.path.splitext(compressed_name)[1] 23 | image = open(tmp_cover_name, 'wb') 24 | image.write(cover_data) 25 | image.close() 26 | return tmp_cover_name 27 | 28 | 29 | def get_comic_info(tmp_file_path, original_file_name, original_file_extension): 30 | 31 | coverfile = extractCover(tmp_file_path, original_file_extension) 32 | 33 | return uploader.BookMeta( 34 | file_path=tmp_file_path, 35 | extension=original_file_extension, 36 | title=original_file_name, 37 | author=u"Unknown", 38 | cover=coverfile, 39 | description="", 40 | tags="", 41 | series="", 42 | series_id="", 43 | languages="") 44 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-ru-RU.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["ru-RU"]={formatLoadingMessage:function(){return"Пожалуйста, подождите, идёт загрузка..."},formatRecordsPerPage:function(a){return a+" записей на страницу"},formatShowingRows:function(a,b,c){return"Записи с "+a+" по "+b+" из "+c},formatSearch:function(){return"Поиск"},formatNoMatches:function(){return"Ничего не найдено"},formatRefresh:function(){return"Обновить"},formatToggle:function(){return"Переключить"},formatColumns:function(){return"Колонки"},formatClearFilters:function(){return"Очистить фильтры"},formatMultipleSort:function(){return"Множественная сортировка"},formatAddLevel:function(){return"Добавить уровень"},formatDeleteLevel:function(){return"Удалить уровень"},formatColumn:function(){return"Колонка"},formatOrder:function(){return"Порядок"},formatSortBy:function(){return"Сортировать по"},formatThenBy:function(){return"затем по"},formatSort:function(){return"Сортировать"},formatCancel:function(){return"Отмена"},formatDuplicateAlertTitle:function(){return"Дублирование колонок!"},formatDuplicateAlertDescription:function(){return"Удалите, пожалуйста, дублирующую колонку, или замените ее на другую."}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["ru-RU"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-uk-UA.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["uk-UA"]={formatLoadingMessage:function(){return"Завантаження, будь ласка, зачекайте..."},formatRecordsPerPage:function(a){return a+" записів на сторінку"},formatShowingRows:function(a,b,c){return"Показано з "+a+" по "+b+". Всього: "+c},formatSearch:function(){return"Пошук"},formatNoMatches:function(){return"Не знайдено жодного запису"},formatRefresh:function(){return"Оновити"},formatToggle:function(){return"Змінити"},formatColumns:function(){return"Стовпці"},formatClearFilters:function(){return"Очистити фільтри"},formatMultipleSort:function(){return"Сортування за кількома стовпцями"},formatAddLevel:function(){return"Додати рівень"},formatDeleteLevel:function(){return"Видалити рівень"},formatColumn:function(){return"Стовпець"},formatOrder:function(){return"Порядок"},formatSortBy:function(){return"Сортувати за"},formatThenBy:function(){return"потім за"},formatSort:function(){return"Сортувати"},formatCancel:function(){return"Скасувати"},formatDuplicateAlertTitle:function(){return"Дублювання стовпців!"},formatDuplicateAlertDescription:function(){return"Видаліть, будь ласка, дублюючий стовпець, або замініть його на інший."}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["uk-UA"])}(jQuery); -------------------------------------------------------------------------------- /cps/static/css/images/annotation-key.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /cps/static/js/reading/epub.js: -------------------------------------------------------------------------------- 1 | /* global $, calibre, EPUBJS, ePubReader */ 2 | 3 | (function() { 4 | "use strict"; 5 | 6 | EPUBJS.filePath = calibre.filePath; 7 | EPUBJS.cssPath = calibre.cssPath; 8 | 9 | var reader = ePubReader(calibre.bookUrl, { 10 | restore: true, 11 | bookmarks: calibre.bookmark ? [calibre.bookmark] : [] 12 | }); 13 | 14 | if (calibre.useBookmarks) { 15 | reader.on("reader:bookmarked", updateBookmark.bind(reader, "add")); 16 | reader.on("reader:unbookmarked", updateBookmark.bind(reader, "remove")); 17 | } else { 18 | $("#bookmark, #show-Bookmarks").remove(); 19 | } 20 | 21 | /** 22 | * @param {string} action - Add or remove bookmark 23 | * @param {string|int} location - Location or zero 24 | */ 25 | function updateBookmark(action, location) { 26 | // Remove other bookmarks (there can only be one) 27 | if (action === "add") { 28 | this.settings.bookmarks.filter(function (bookmark) { 29 | return bookmark && bookmark !== location; 30 | }).map(function (bookmark) { 31 | this.removeBookmark(bookmark); 32 | }.bind(this)); 33 | } 34 | 35 | // Save to database 36 | $.ajax(calibre.bookmarkUrl, { 37 | method: "post", 38 | data: { bookmark: location || "" } 39 | }).fail(function (xhr, status, error) { 40 | alert(error); 41 | }); 42 | } 43 | })(); 44 | -------------------------------------------------------------------------------- /cps/static/js/libs/context.min.js: -------------------------------------------------------------------------------- 1 | /*! intention.js v0.9.7.3 2 | * http://intentionjs.com/ 3 | * 4 | * context.js 5 | * 6 | * Copyright 2011, 2013 Dowjones and other contributors 7 | * Released under the MIT license 8 | * 9 | */ 10 | !function(){"use strict";var a=function(a,b){function c(a,b){var c=new Date,d=null;return function(e){var f=new Date;if(b>f-c){d&&window.clearTimeout(d);var g=function(b){return function(){a(b)}};return d=window.setTimeout(g(e),b),!1}a(e),c=f}}var d,e,f=new b;return f.responsive([{name:"base"}]).respond("base"),d=f.responsive({ID:"width",contexts:[{name:"standard",min:840},{name:"tablet",min:510},{name:"mobile",min:0}],matcher:function(a,b){return"string"==typeof a?a===b.name:a>=b.min},measure:function(b){return"string"==typeof b?b:a(window).width()}}),e=f.responsive({ID:"orientation",contexts:[{name:"portrait",rotation:0},{name:"landscape",rotation:90}],matcher:function(a,b){return a===b.rotation},measure:function(){var a=Math.abs(window.orientation);return a>0&&(a=180-a),a}}),f.responsive({ID:"touch",contexts:[{name:"touch"}],matcher:function(){return"ontouchstart"in window}}).respond(),f.responsive({ID:"highres",contexts:[{name:"highres"}],matcher:function(){return window.devicePixelRatio>1}}).respond(),a(window).on("resize",c(d.respond,100)).on("orientationchange",d.respond).on("orientationchange",e.respond),d.respond(),e.respond(),a(function(){f.elements(document)}),f};!function(a,b){"function"==typeof define&&define.amd?define("context",["jquery","intention"],b):a.intent=b(a.jQuery,a.Intention)}(this,function(b,c){return a(b,c)})}.call(this); -------------------------------------------------------------------------------- /cps/templates/discover.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |

{{title}}

5 |
6 | 7 | {% for entry in entries %} 8 |
9 |
10 | {% if entry.has_cover is defined %} 11 | 12 | {{ entry.title }} 13 | 14 | {% endif %} 15 |
16 |
17 |

{{entry.title|shortentitle}}

18 |

19 | {% for author in entry.authors %} 20 | {{author.name.replace('|',',')|shortentitle(30)}} 21 | {% if not loop.last %} 22 | & 23 | {% endif %} 24 | {% endfor %} 25 |

26 | {% if entry.ratings.__len__() > 0 %} 27 |
28 | {% for number in range((entry.ratings[0].rating/2)|int(2)) %} 29 | 30 | {% if loop.last and loop.index < 5 %} 31 | {% for numer in range(5 - loop.index) %} 32 | 33 | {% endfor %} 34 | {% endif %} 35 | {% endfor %} 36 |
37 | {% endif %} 38 |
39 |
40 | {% endfor %} 41 |
42 |
43 | {% endblock %} 44 | -------------------------------------------------------------------------------- /cps/cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import argparse 5 | import os 6 | import sys 7 | 8 | parser = argparse.ArgumentParser(description='Calibre Web is a web app' 9 | ' providing a interface for browsing, reading and downloading eBooks\n', prog='cps.py') 10 | parser.add_argument('-p', metavar='path', help='path and name to settings db, e.g. /opt/cw.db') 11 | parser.add_argument('-g', metavar='path', help='path and name to gdrive db, e.g. /opt/gd.db') 12 | parser.add_argument('-c', metavar='path', help='path and name to SSL certfile, e.g. /opt/test.cert, works only in combination with keyfile') 13 | parser.add_argument('-k', metavar='path', help='path and name to SSL keyfile, e.g. /opt/test.key, works only in combination with certfile') 14 | args = parser.parse_args() 15 | 16 | generalPath = os.path.normpath(os.getenv("CALIBRE_DBPATH", 17 | os.path.dirname(os.path.realpath(__file__)) + os.sep + ".." + os.sep)) 18 | if args.p: 19 | settingspath = args.p 20 | else: 21 | settingspath = os.path.join(generalPath, "app.db") 22 | 23 | if args.g: 24 | gdpath = args.g 25 | else: 26 | gdpath = os.path.join(generalPath, "gdrive.db") 27 | 28 | certfilepath = None 29 | keyfilepath = None 30 | if args.c: 31 | if os.path.isfile(args.c): 32 | certfilepath = args.c 33 | else: 34 | print("Certfilepath is invalid. Exiting...") 35 | sys.exit(1) 36 | 37 | if args.c is "": 38 | certfilepath = "" 39 | 40 | if args.k: 41 | if os.path.isfile(args.k): 42 | keyfilepath = args.k 43 | else: 44 | print("Keyfilepath is invalid. Exiting...") 45 | sys.exit(1) 46 | 47 | if args.k is "": 48 | keyfilepath = "" 49 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fr-FR.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["fr-FR"]={formatLoadingMessage:function(){return"Chargement en cours, patientez, s´il vous plaît ..."},formatRecordsPerPage:function(a){return a+" lignes par page"},formatShowingRows:function(a,b,c){return"Affichage des lignes "+a+" à "+b+" sur "+c+" lignes au total"},formatSearch:function(){return"Rechercher"},formatNoMatches:function(){return"Aucun résultat trouvé"},formatPaginationSwitch:function(){return"Montrer/Masquer pagination"},formatRefresh:function(){return"Rafraîchir"},formatToggle:function(){return"Alterner"},formatColumns:function(){return"Colonnes"},formatAllRows:function(){return"Tous"},formatExport:function(){return"Exporter les données"},formatClearFilters:function(){return"Vider les filtres"},formatMultipleSort:function(){return"Tri avancé"},formatAddLevel:function(){return"Ajouter un niveau"},formatDeleteLevel:function(){return"Supprimer un niveau"},formatColumn:function(){return"Colonne"},formatOrder:function(){return"Ordre"},formatSortBy:function(){return"Trier par"},formatThenBy:function(){return"Puis par"},formatSort:function(){return"Trier"},formatCancel:function(){return"Annuler"},formatDuplicateAlertTitle:function(){return"Doublon(s) détecté(s)!"},formatDuplicateAlertDescription:function(){return"Supprimez ou changez les colonnes dupliquées."},formatSortOrders:function(){return{asc:"Croissant",desc:"Décroissant"}},formatAdvancedSearch:function(){return"Recherche avancée"},formatAdvancedCloseButton:function(){return"Fermer"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["fr-FR"])}(jQuery); -------------------------------------------------------------------------------- /cps/converter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | import subprocess 5 | import ub 6 | import re 7 | from flask_babel import gettext as _ 8 | 9 | 10 | def versionKindle(): 11 | versions = _(u'not installed') 12 | if os.path.exists(ub.config.config_converterpath): 13 | try: 14 | p = subprocess.Popen(ub.config.config_converterpath, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 15 | p.wait() 16 | for lines in p.stdout.readlines(): 17 | if isinstance(lines, bytes): 18 | lines = lines.decode('utf-8') 19 | if re.search('Amazon kindlegen\(', lines): 20 | versions = lines 21 | except Exception: 22 | versions = _(u'Excecution permissions missing') 23 | return {'kindlegen' : versions} 24 | 25 | 26 | def versionCalibre(): 27 | versions = _(u'not installed') 28 | if os.path.exists(ub.config.config_converterpath): 29 | try: 30 | p = subprocess.Popen([ub.config.config_converterpath, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 31 | p.wait() 32 | for lines in p.stdout.readlines(): 33 | if isinstance(lines, bytes): 34 | lines = lines.decode('utf-8') 35 | if re.search('ebook-convert.*\(calibre', lines): 36 | versions = lines 37 | except Exception: 38 | versions = _(u'Excecution permissions missing') 39 | return {'Calibre converter' : versions} 40 | 41 | 42 | def versioncheck(): 43 | if ub.config.config_ebookconverter == 1: 44 | return versionKindle() 45 | elif ub.config.config_ebookconverter == 2: 46 | return versionCalibre() 47 | else: 48 | return {'ebook_converter':''} 49 | 50 | -------------------------------------------------------------------------------- /cps/static/css/popup.css: -------------------------------------------------------------------------------- 1 | /* http://davidwalsh.name/css-tooltips */ 2 | /* base CSS element */ 3 | .popup { 4 | background: #eee; 5 | border: 1px solid #ccc; 6 | padding: 10px; 7 | border-radius: 8px; 8 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); 9 | position: fixed; 10 | max-width: 300px; 11 | font-size: 12px; 12 | 13 | display: none; 14 | margin-left: 2px; 15 | 16 | margin-top: 30px; 17 | } 18 | 19 | .popup.above { 20 | margin-top: -10px; 21 | } 22 | 23 | .popup.left { 24 | margin-left: -20px; 25 | } 26 | 27 | .popup.right { 28 | margin-left: 40px; 29 | } 30 | 31 | .pop_content { 32 | max-height: 225px; 33 | overflow-y: auto; 34 | } 35 | 36 | .pop_content > p { 37 | margin-top: 0; 38 | } 39 | 40 | /* below */ 41 | .popup:before { 42 | position: absolute; 43 | display: inline-block; 44 | border-bottom: 10px solid #eee; 45 | border-right: 10px solid transparent; 46 | border-left: 10px solid transparent; 47 | border-bottom-color: rgba(0, 0, 0, 0.2); 48 | left: 50%; 49 | top: -10px; 50 | margin-left: -6px; 51 | content: ''; 52 | } 53 | 54 | .popup:after { 55 | position: absolute; 56 | display: inline-block; 57 | border-bottom: 9px solid #eee; 58 | border-right: 9px solid transparent; 59 | border-left: 9px solid transparent; 60 | left: 50%; 61 | top: -9px; 62 | margin-left: -5px; 63 | content: ''; 64 | } 65 | 66 | /* above */ 67 | .popup.above:before { 68 | border-bottom: none; 69 | border-top: 10px solid #eee; 70 | border-top-color: rgba(0, 0, 0, 0.2); 71 | top: 100%; 72 | } 73 | 74 | .popup.above:after { 75 | border-bottom: none; 76 | border-top: 9px solid #eee; 77 | top: 100%; 78 | } 79 | 80 | .popup.left:before, 81 | .popup.left:after 82 | { 83 | left: 20px; 84 | } 85 | 86 | .popup.right:before, 87 | .popup.right:after 88 | { 89 | left: auto; 90 | right: 20px; 91 | } 92 | 93 | 94 | .popup.show, .popup.on { 95 | display: block; 96 | } -------------------------------------------------------------------------------- /cps/static/js/libs/screenfull.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * screenfull 3 | * v3.3.0 - 2017-07-06 4 | * (c) Sindre Sorhus; MIT License 5 | */ 6 | 7 | !function(){"use strict";var a="undefined"!=typeof window&&void 0!==window.document?window.document:{},b="undefined"!=typeof module&&module.exports,c="undefined"!=typeof Element&&"ALLOW_KEYBOARD_INPUT"in Element,d=function(){for(var b,c=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],d=0,e=c.length,f={};d", { "class": "text-danger"}).text(xhr.responseText); 51 | $("#shelf-action-status").html($msg); 52 | 53 | setTimeout(function() { 54 | $msg.remove(); 55 | }, 10000); 56 | }); 57 | }); 58 | })(); 59 | -------------------------------------------------------------------------------- /cps/static/js/table.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | $("#domain_submit").click(function(event){ 4 | event.preventDefault(); 5 | $("#domain_add").ajaxForm(); 6 | $(this).closest("form").submit(); 7 | $.ajax({ 8 | method:"get", 9 | url: window.location.pathname + "/../../ajax/domainlist", 10 | async: true, 11 | timeout: 900, 12 | success:function(data){ 13 | $('#domain-table').bootstrapTable("load", data); 14 | } 15 | }); 16 | }); 17 | $('#domain-table').bootstrapTable({ 18 | formatNoMatches: function () { 19 | return ''; 20 | }, 21 | striped: false 22 | }); 23 | $("#btndeletedomain").click(function() { 24 | //get data-id attribute of the clicked element 25 | var domainId = $(this).data('domainId'); 26 | $.ajax({ 27 | method:"post", 28 | url: window.location.pathname + "/../../ajax/deletedomain", 29 | data: {"domainid":domainId} 30 | }); 31 | $('#DeleteDomain').modal('hide'); 32 | $.ajax({ 33 | method:"get", 34 | url: window.location.pathname + "/../../ajax/domainlist", 35 | async: true, 36 | timeout: 900, 37 | success:function(data){ 38 | $('#domain-table').bootstrapTable("load", data); 39 | } 40 | }); 41 | 42 | }); 43 | //triggered when modal is about to be shown 44 | $('#DeleteDomain').on('show.bs.modal', function(e) { 45 | //get data-id attribute of the clicked element and store in button 46 | var domainId = $(e.relatedTarget).data('domain-id'); 47 | $(e.currentTarget).find("#btndeletedomain").data('domainId',domainId); 48 | }); 49 | }); 50 | 51 | function TableActions (value, row, index) { 52 | return [ 53 | '', 54 | '', 55 | '' 56 | ].join(''); 57 | } 58 | -------------------------------------------------------------------------------- /cps/templates/json.txt: -------------------------------------------------------------------------------- 1 | { 2 | "pubdate": "{{entry.pubdate}}", 3 | "title": "{{entry.title}}", 4 | "format_metadata": { 5 | {% for format in entry.data %} 6 | "{{format.format}}": { 7 | "mtime": "{{entry.last_modified}}", 8 | "size": {{format.uncompressed_size}}, 9 | "path": "" 10 | }{% if not loop.last %},{% endif %} 11 | {% endfor %} 12 | }, 13 | "formats": [ 14 | {% for format in entry.data %} 15 | "{{format.format}}"{% if not loop.last %},{% endif %} 16 | {% endfor %} 17 | ], 18 | "series": null, 19 | "cover": "{{url_for('feed_get_cover', book_id=entry.id)}}", 20 | "languages": [ 21 | {% for lang in entry.languages %} 22 | "{{lang.lang_code}}"{% if not loop.last %},{% endif %} 23 | {% endfor %} 24 | ], 25 | "comments": "{% if entry.comments|length > 0 %}{{entry.comments[0].text.replace('"', '\\"')|safe}}{% endif %}", 26 | "tags": [ 27 | {% for tag in entry.tags %} 28 | "{{tag.name}}"{% if not loop.last %},{% endif %} 29 | {% endfor %} 30 | ], 31 | "application_id": {{entry.id}}, 32 | "series_index": {% if entry.series|length > 0 %}"{{entry.series_index}}"{% else %}null{% endif %}, 33 | "last_modified": "{{entry.last_modified}}", 34 | "author_sort": "{{entry.author_sort}}", 35 | "uuid": "{{entry.uuid}}", 36 | "timestamp": "{{entry.timestamp}}", 37 | "thumbnail": "{{url_for('feed_get_cover', book_id=entry.id)}}", 38 | "main_format": { 39 | "{{entry.data[0].format|lower}}": "{{ url_for('get_opds_download_link', book_id=entry.id, book_format=entry.data[0].format|lower)}}" 40 | }, 41 | "rating":{% if entry.ratings.__len__() > 0 %} "{{entry.ratings[0].rating}}.0"{% else %}0.0{% endif %}, 42 | "authors": [ 43 | {% for author in entry.authors %} 44 | "{{author.name.replace('|',',')}}"{% if not loop.last %},{% endif %} 45 | {% endfor %} 46 | ], 47 | "other_formats": { 48 | {% if entry.data.__len__() > 1 %} 49 | {% for format in entry.data[1:] %} 50 | "{{format.format|lower}}": "{{ url_for('get_opds_download_link', book_id=entry.id, book_format=format.format|lower)}}"{% if not loop.last %},{% endif %} 51 | {% endfor %} 52 | {% endif %} }, 53 | "title_sort": "{{entry.sort}}" 54 | } 55 | -------------------------------------------------------------------------------- /cps/static/css/images/annotation-help.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 16 | 18 | 21 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "jquery": true 5 | }, 6 | "globals": { 7 | "alert": true 8 | }, 9 | "rules": { 10 | "arrow-parens": 2, 11 | "block-scoped-var": 1, 12 | "brace-style": 2, 13 | "camelcase": 1, 14 | "comma-spacing": 2, 15 | "curly": [2, "multi-line", "consistent"], 16 | "eqeqeq": 2, 17 | "indent": [ 18 | 2, 19 | 4, 20 | { 21 | "SwitchCase": 1 22 | } 23 | ], 24 | "keyword-spacing": 2, 25 | "linebreak-style": 2, 26 | "new-cap": 2, 27 | "no-dupe-args": 2, 28 | "no-dupe-class-members": 2, 29 | "no-dupe-keys": 2, 30 | "no-duplicate-case": 2, 31 | "no-caller": 2, 32 | "no-class-assign": 2, 33 | "no-cond-assign": 2, 34 | "no-const-assign": 2, 35 | "no-console": 2, 36 | "no-debugger": 2, 37 | "no-delete-var": 2, 38 | "no-empty": 2, 39 | "no-eval": 2, 40 | "no-extend-native": 2, 41 | "no-extra-boolean-cast": 2, 42 | "no-extra-semi": 2, 43 | "no-fallthrough": [ 44 | 2, 45 | { 46 | "commentPattern": "break[\\s\\w]*omitted" 47 | } 48 | ], 49 | "no-implied-eval": 2, 50 | "no-invalid-regexp": 2, 51 | "no-irregular-whitespace": 2, 52 | "no-iterator": 2, 53 | "no-loop-func": 2, 54 | "no-mixed-operators": 2, 55 | "no-mixed-spaces-and-tabs": 2, 56 | "no-multi-str": 2, 57 | "no-new": 2, 58 | "no-obj-calls": 2, 59 | "no-octal": 2, 60 | "no-redeclare": 2, 61 | "no-regex-spaces": 2, 62 | "no-script-url": 2, 63 | "no-sparse-arrays": 2, 64 | "no-undef": 2, 65 | "no-undefined": 2, 66 | "no-unreachable": 2, 67 | "no-unsafe-negation": 2, 68 | "no-unused-vars": 2, 69 | "no-use-before-define": [ 70 | 2, 71 | { 72 | "classes": false, 73 | "functions": false 74 | } 75 | ], 76 | "quotes": [ 77 | 2, 78 | "double" 79 | ], 80 | "require-yield": 2, 81 | "semi": [ 82 | 2, 83 | "always" 84 | ], 85 | "space-before-blocks": 2, 86 | "space-infix-ops": 2, 87 | "space-unary-ops": 2, 88 | "use-isnan": 2, 89 | "valid-typeof": 2, 90 | "wrap-iife": [ 91 | 2, 92 | "any" 93 | ], 94 | "yield-star-spacing": 2 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /cps/fb2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lxml import etree 5 | import uploader 6 | 7 | 8 | def get_fb2_info(tmp_file_path, original_file_extension): 9 | 10 | ns = { 11 | 'fb': 'http://www.gribuser.ru/xml/fictionbook/2.0', 12 | 'l': 'http://www.w3.org/1999/xlink', 13 | } 14 | 15 | fb2_file = open(tmp_file_path) 16 | tree = etree.fromstring(fb2_file.read()) 17 | 18 | authors = tree.xpath('/fb:FictionBook/fb:description/fb:title-info/fb:author', namespaces=ns) 19 | 20 | def get_author(element): 21 | last_name = element.xpath('fb:last-name/text()', namespaces=ns) 22 | if len(last_name): 23 | last_name = last_name[0].encode('utf-8') 24 | else: 25 | last_name = u'' 26 | middle_name = element.xpath('fb:middle-name/text()', namespaces=ns) 27 | if len(middle_name): 28 | middle_name = middle_name[0].encode('utf-8') 29 | else: 30 | middle_name = u'' 31 | first_name = element.xpath('fb:first-name/text()', namespaces=ns) 32 | if len(first_name): 33 | first_name = first_name[0].encode('utf-8') 34 | else: 35 | first_name = u'' 36 | return (first_name.decode('utf-8') + u' ' 37 | + middle_name.decode('utf-8') + u' ' 38 | + last_name.decode('utf-8')).encode('utf-8') 39 | 40 | author = str(", ".join(map(get_author, authors))) 41 | 42 | title = tree.xpath('/fb:FictionBook/fb:description/fb:title-info/fb:book-title/text()', namespaces=ns) 43 | if len(title): 44 | title = str(title[0].encode('utf-8')) 45 | else: 46 | title = u'' 47 | description = tree.xpath('/fb:FictionBook/fb:description/fb:publish-info/fb:book-name/text()', namespaces=ns) 48 | if len(description): 49 | description = str(description[0].encode('utf-8')) 50 | else: 51 | description = u'' 52 | 53 | return uploader.BookMeta( 54 | file_path=tmp_file_path, 55 | extension=original_file_extension, 56 | title=title.decode('utf-8'), 57 | author=author.decode('utf-8'), 58 | cover=None, 59 | description=description.decode('utf-8'), 60 | tags="", 61 | series="", 62 | series_id="", 63 | languages="") 64 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-rating-input.min.js: -------------------------------------------------------------------------------- 1 | /** @link https://github.com/javiertoledo/bootstrap-rating-input */ 2 | !function(a){"use strict";function n(a){return"[data-value"+(a?"="+a:"")+"]"}function e(a,n,e){var i=e.activeIcon,t=e.inactiveIcon;a.removeClass(n?t:i).addClass(n?i:t)}function i(n,e){var i=a.extend({},s,n.data(),e);return i.inline=""===i.inline||i.inline,i.readonly=""===i.readonly||i.readonly,!1===i.clearable?i.clearableLabel="":i.clearableLabel=i.clearable,i.clearable=""===i.clearable||i.clearable,i}function t(n,e){if(e.inline)i=a('');else var i=a('
');i.addClass(n.attr("class")),i.removeClass("rating");for(var t=e.min;t<=e.max;t++)i.append('');return e.clearable&&!e.readonly&&i.append(" ").append(''+e.clearableLabel+""),i}var l="rating-clear",o="."+l,s={min:1,max:5,"empty-value":0,iconLib:"glyphicon",activeIcon:"glyphicon-star",inactiveIcon:"glyphicon-star-empty",clearable:!1,clearableIcon:"glyphicon-remove",clearableRemain:!1,inline:!1,readonly:!1},r=function(a,n){var e=this.$input=a;this.options=i(e,n);var l=this.$el=t(e,this.options);e.addClass("hidden").before(l),e.attr("type","hidden"),this.highlight(e.val())};r.VERSION="0.4.0",r.DEFAULTS=s,r.prototype={clear:function(){this.setValue(this.options["empty-value"])},setValue:function(a){this.highlight(a),this.updateInput(a)},highlight:function(a,i){var t=this.options,l=this.$el;if(a>=this.options.min&&a<=this.options.max){var s=l.find(n(a));e(s.prevAll("i").addBack(),!0,t),e(s.nextAll("i"),!1,t)}else e(l.find(n()),!1,t);i||(this.options.clearableRemain?l.find(o).removeClass("hidden"):a&&a!=this.options["empty-value"]?l.find(o).removeClass("hidden"):l.find(o).addClass("hidden"))},updateInput:function(a){var n=this.$input;n.val()!=a&&n.val(a).change()}},(a.fn.rating=function(e){return this.filter("input[type=number]").each(function(){var i=a(this),t=new r(i,"object"==typeof e&&e||{});t.options.readonly||(t.$el.on("mouseenter",n(),function(){t.highlight(a(this).data("value"),!0)}).on("mouseleave",n(),function(){t.highlight(i.val(),!0)}).on("click",n(),function(){t.setValue(a(this).data("value"))}).on("click",o,function(){t.clear()}),i.data("rating",t))})}).Constructor=r,a(function(){a("input.rating[type=number]").each(function(){a(this).rating()})})}(jQuery); 3 | -------------------------------------------------------------------------------- /cps/cache_buster.py: -------------------------------------------------------------------------------- 1 | # Inspired by https://github.com/ChrisTM/Flask-CacheBust 2 | # Uses query strings so CSS font files are found without having to resort to absolute URLs 3 | 4 | import hashlib 5 | import os 6 | 7 | 8 | def init_cache_busting(app): 9 | """ 10 | Configure `app` to so that `url_for` adds a unique query string to URLs generated 11 | for the `'static'` endpoint. 12 | 13 | This allows setting long cache expiration values on static resources 14 | because whenever the resource changes, so does its URL. 15 | """ 16 | 17 | static_folder = os.path.join(app.static_folder, '') # path to the static file folder, with trailing slash 18 | 19 | hash_table = {} # map of file hashes 20 | 21 | app.logger.debug('Computing cache-busting values...') 22 | # compute file hashes 23 | for dirpath, __, filenames in os.walk(static_folder): 24 | for filename in filenames: 25 | # compute version component 26 | rooted_filename = os.path.join(dirpath, filename) 27 | with open(rooted_filename, 'rb') as f: 28 | file_hash = hashlib.md5(f.read()).hexdigest()[:7] 29 | 30 | # save version to tables 31 | file_path = rooted_filename.replace(static_folder, "") 32 | file_path = file_path.replace("\\", "/") # Convert Windows path to web path 33 | hash_table[file_path] = file_hash 34 | app.logger.debug('Finished computing cache-busting values') 35 | 36 | def bust_filename(filename): 37 | return hash_table.get(filename, "") 38 | 39 | def unbust_filename(filename): 40 | return filename.split("?", 1)[0] 41 | 42 | @app.url_defaults 43 | def reverse_to_cache_busted_url(endpoint, values): 44 | """ 45 | Make `url_for` produce busted filenames when using the 'static' endpoint. 46 | """ 47 | if endpoint == "static": 48 | file_hash = bust_filename(values["filename"]) 49 | if file_hash: 50 | values["q"] = file_hash 51 | 52 | def debusting_static_view(filename): 53 | """ 54 | Serve a request for a static file having a busted name. 55 | """ 56 | return original_static_view(filename=unbust_filename(filename)) 57 | 58 | # Replace the default static file view with our debusting view. 59 | original_static_view = app.view_functions["static"] 60 | app.view_functions["static"] = debusting_static_view 61 | -------------------------------------------------------------------------------- /cps/static/js/libs/bootstrap-table/bootstrap-table-editable.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.12.1 - 2018-03-12 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2018 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.extend(a.fn.bootstrapTable.defaults,{editable:!0,onEditableInit:function(){return!1},onEditableSave:function(){return!1},onEditableShown:function(){return!1},onEditableHidden:function(){return!1}}),a.extend(a.fn.bootstrapTable.Constructor.EVENTS,{"editable-init.bs.table":"onEditableInit","editable-save.bs.table":"onEditableSave","editable-shown.bs.table":"onEditableShown","editable-hidden.bs.table":"onEditableHidden"});var b=a.fn.bootstrapTable.Constructor,c=b.prototype.initTable,d=b.prototype.initBody;b.prototype.initTable=function(){var b=this;c.apply(this,Array.prototype.slice.apply(arguments)),this.options.editable&&a.each(this.columns,function(c,d){if(d.editable){var e={},f=[],g="editable-",h=function(a,b){var c=a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()});if(c.slice(0,g.length)==g){var d=c.replace(g,"data-");e[d]=b}};a.each(b.options,h),d.formatter=d.formatter||function(a){return a},d._formatter=d._formatter?d._formatter:d.formatter,d.formatter=function(c,g,i){var j=d._formatter?d._formatter(c,g,i):c;a.each(d,h),a.each(e,function(a,b){f.push(" "+a+'="'+b+'"')});var k=!1;return d.editable.hasOwnProperty("noeditFormatter")&&(k=d.editable.noeditFormatter(c,g,i)),k===!1?['"].join(""):k}}})},b.prototype.initBody=function(){var b=this;d.apply(this,Array.prototype.slice.apply(arguments)),this.options.editable&&(a.each(this.columns,function(c,d){d.editable&&(b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("save").on("save",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g],i=h[d.field];a(this).data("value",e.submitValue),h[d.field]=e.submitValue,b.trigger("editable-save",d.field,h,i,a(this)),b.resetFooter()}),b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("shown").on("shown",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g];b.trigger("editable-shown",d.field,h,a(this),e)}),b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("hidden").on("hidden",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g];b.trigger("editable-hidden",d.field,h,a(this),e)}))}),this.trigger("editable-init"))}}(jQuery); -------------------------------------------------------------------------------- /cps/templates/tasks.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block header %} 3 | 4 | {% endblock %} 5 | {% block body %} 6 |
7 |

{{_('Tasks list')}}

8 | 9 | 10 | 11 | {% if g.user.role_admin() %} 12 | 13 | {% endif %} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
{{_('User')}}{{_('Task')}}{{_('Status')}}{{_('Progress')}}{{_('Runtime')}}{{_('Starttime')}}
24 | 26 |
27 | {% endblock %} 28 | {% block js %} 29 | 30 | 57 | 58 | {% endblock %} 59 | -------------------------------------------------------------------------------- /cps/templates/shelf.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 |

{{title}}

5 | {% if g.user.is_authenticated %} 6 | {% if (g.user.role_edit_shelfs() and shelf.is_public ) or not shelf.is_public %} 7 |
{{ _('Delete this Shelf') }}
8 | {{ _('Edit Shelf') }} 9 | {{ _('Change order') }} 10 | {% endif %} 11 | {% endif %} 12 |
13 | 14 | {% for entry in entries %} 15 |
16 |
17 | {% if entry.has_cover is defined %} 18 | 19 | 20 | 21 | {% endif %} 22 |
23 |
24 |

{{entry.title|shortentitle}}

25 |

26 | {% for author in entry.authors %} 27 | {{author.name.replace('|',',')}} 28 | {% if not loop.last %} 29 | & 30 | {% endif %} 31 | {% endfor %} 32 |

33 | {% if entry.ratings.__len__() > 0 %} 34 |
35 | {% for number in range((entry.ratings[0].rating/2)|int(2)) %} 36 | 37 | {% if loop.last and loop.index < 5 %} 38 | {% for numer in range(5 - loop.index) %} 39 | 40 | {% endfor %} 41 | {% endif %} 42 | {% endfor %} 43 |
44 | {% endif %} 45 |
46 |
47 | {% endfor %} 48 |
49 |
50 | 65 | 66 | {% endblock %} 67 | -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/content.inline.min.css: -------------------------------------------------------------------------------- 1 | .mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7ACAFF}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-content-body a[data-mce-selected],.mce-content-body code[data-mce-selected]{background:#bfe6ff}.mce-content-body hr{cursor:default}.mce-content-body{line-height:1.3} -------------------------------------------------------------------------------- /cps/templates/search.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |
4 | {% if entries|length < 1 %} 5 |

{{_('No Results for:')}} {{searchterm}}

6 |

{{_('Please try a different search')}}

7 | {% else %} 8 |

{{entries|length}} {{_('Results for:')}} {{searchterm}}

9 | {% if g.user.is_authenticated %} 10 | {% if g.user.shelf.all() or g.public_shelfes %} 11 | 29 | {% endif %} 30 | {% endif %} 31 | {% endif %} 32 | 33 |
34 | {% for entry in entries %} 35 |
36 |
37 | {% if entry.has_cover is defined %} 38 | 39 | {{ entry.title }} 40 | 41 | {% endif %} 42 |
43 |
44 |

{{entry.title|shortentitle}}

45 |

46 | {% for author in entry.authors %} 47 | {{author.name.replace('|',',')}} 48 | {% if not loop.last %} 49 | & 50 | {% endif %} 51 | {% endfor %} 52 |

53 | {% if entry.ratings.__len__() > 0 %} 54 |
55 | {% for number in range((entry.ratings[0].rating/2)|int(2)) %} 56 | 57 | {% if loop.last and loop.index < 5 %} 58 | {% for numer in range(5 - loop.index) %} 59 | 60 | {% endfor %} 61 | {% endif %} 62 | {% endfor %} 63 |
64 | {% endif %} 65 |
66 |
67 | {% endfor %} 68 |
69 |
70 | {% endblock %} 71 | -------------------------------------------------------------------------------- /cps/static/js/libs/tinymce/skins/lightgray/content.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px;line-height:1.3;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7ACAFF}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-content-body a[data-mce-selected],.mce-content-body code[data-mce-selected]{background:#bfe6ff}.mce-content-body hr{cursor:default} -------------------------------------------------------------------------------- /cps/static/img/goodreads.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /cps/templates/feed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | urn:uuid:2853dacf-ed79-42f5-8e8a-a7bb3d1ae6a2 4 | {{ current_time }} 5 | 8 | 11 | 14 | {% if pagination.has_prev %} 15 | 18 | {% endif %} 19 | {% if pagination.has_next %} 20 | 24 | {% endif %} 25 | {% if pagination.has_prev %} 26 | 29 | {% endif %} 30 | 31 | {{instance}} 32 | 33 | {{instance}} 34 | https://github.com/janeczku/calibre-web 35 | 36 | 37 | {% if entries and entries[0] %} 38 | {% for entry in entries %} 39 | 40 | {{entry.title}} 41 | {{entry.uuid}} 42 | {{entry.atom_timestamp}} 43 | 44 | {{entry.authors[0].name}} 45 | 46 | {{entry.language}} 47 | {% for tag in entry.tags %} 48 | 51 | {% endfor %} 52 | {% if entry.comments[0] %}{{entry.comments[0].text|striptags}}{% endif %} 53 | {% if entry.has_cover %} 54 | 55 | 56 | {% endif %} 57 | {% for format in entry.data %} 58 | 60 | {% endfor %} 61 | 62 | {% endfor %} 63 | {% endif %} 64 | {% for entry in listelements %} 65 | 66 | {{entry.name}} 67 | {{ url_for(folder, book_id=entry.id) }} 68 | 69 | 70 | {% endfor %} 71 | 72 | -------------------------------------------------------------------------------- /cps/static/locale/ta-LK/viewer.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2012 Mozilla Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Main toolbar buttons (tooltips and alt text for images) 16 | 17 | # LOCALIZATION NOTE (page.title): The tooltip for the pageNumber input. 18 | # LOCALIZATION NOTE (of_pages): "{{pagesCount}}" will be replaced by a number 19 | # representing the total number of pages in the document. 20 | # LOCALIZATION NOTE (page_of_pages): "{{pageNumber}}" and "{{pagesCount}}" 21 | # will be replaced by a number representing the currently visible page, 22 | # respectively a number representing the total number of pages in the document. 23 | 24 | zoom.title=அளவு 25 | open_file.title=கோப்பினைத் திறக்க 26 | open_file_label=திறக்க 27 | 28 | # Secondary toolbar and context menu 29 | 30 | 31 | # Document properties dialog box 32 | # LOCALIZATION NOTE (document_properties_kb): "{{size_kb}}" and "{{size_b}}" 33 | # will be replaced by the PDF file size in kilobytes, respectively in bytes. 34 | # LOCALIZATION NOTE (document_properties_mb): "{{size_mb}}" and "{{size_b}}" 35 | # will be replaced by the PDF file size in megabytes, respectively in bytes. 36 | # LOCALIZATION NOTE (document_properties_date_string): "{{date}}" and "{{time}}" 37 | # will be replaced by the creation/modification date, and time, of the PDF file. 38 | 39 | # LOCALIZATION NOTE (print_progress_percent): "{{progress}}" will be replaced by 40 | # a numerical per cent value. 41 | 42 | # Tooltips and alt text for side panel toolbar buttons 43 | # (the _label strings are alt text for the buttons, the .title strings are 44 | # tooltips) 45 | 46 | # Thumbnails panel item (tooltip and alt text for images) 47 | # LOCALIZATION NOTE (thumb_page_title): "{{page}}" will be replaced by the page 48 | # number. 49 | # LOCALIZATION NOTE (thumb_page_canvas): "{{page}}" will be replaced by the page 50 | # number. 51 | 52 | # Find panel button title and messages 53 | find_previous.title=இந்த சொற்றொடரின் முன்னைய நிகழ்வை தேடு 54 | find_next.title=இந்த சொற்றொடரின் அடுத்த நிகழ்வைத் தேடு 55 | 56 | # Error panel labels 57 | # LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be 58 | # replaced by the PDF.JS version and build ID. 59 | # LOCALIZATION NOTE (error_message): "{{message}}" will be replaced by an 60 | # english string describing the error. 61 | # LOCALIZATION NOTE (error_stack): "{{stack}}" will be replaced with a stack 62 | # trace. 63 | # LOCALIZATION NOTE (error_file): "{{file}}" will be replaced with a filename 64 | # LOCALIZATION NOTE (error_line): "{{line}}" will be replaced with a line number 65 | 66 | # Predefined zoom values 67 | # LOCALIZATION NOTE (page_scale_percent): "{{scale}}" will be replaced by a 68 | # numerical scale value. 69 | 70 | # Loading indicator messages 71 | 72 | # LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip. 73 | # "{{type}}" will be replaced with an annotation type from a list defined in 74 | # the PDF spec (32000-1:2008 Table 169 – Annotation types). 75 | # Some common types are e.g.: "Check", "Text", "Comment", "Note" 76 | password_ok=ஆம் 77 | 78 | -------------------------------------------------------------------------------- /cps/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | {% if g.user.show_detail_random() %} 4 |
5 |

{{_('Discover (Random Books)')}}

6 |
7 | 8 | {% for entry in random %} 9 |
10 | 19 |
20 |

{{entry.title|shortentitle}}

21 |

22 | {% for author in entry.authors %} 23 | {{author.name.replace('|',',')|shortentitle(30)}} 24 | {% if not loop.last %} 25 | & 26 | {% endif %} 27 | {% endfor %} 28 |

29 | {% if entry.ratings.__len__() > 0 %} 30 |
31 | {% for number in range((entry.ratings[0].rating/2)|int(2)) %} 32 | 33 | {% if loop.last and loop.index < 5 %} 34 | {% for numer in range(5 - loop.index) %} 35 | 36 | {% endfor %} 37 | {% endif %} 38 | {% endfor %} 39 |
40 | {% endif %} 41 |
42 |
43 | {% endfor %} 44 |
45 |
46 | {% endif %} 47 |
48 |

{{title}}

49 |
50 | {% if entries[0] %} 51 | {% for entry in entries %} 52 |
53 | 62 |
63 |

{{entry.title|shortentitle}}

64 |

65 | {% for author in entry.authors %} 66 | {{author.name.replace('|',',')|shortentitle(30)}} 67 | {% if not loop.last %} 68 | & 69 | {% endif %} 70 | {% endfor %} 71 |

72 | {% if entry.ratings.__len__() > 0 %} 73 |
74 | {% for number in range((entry.ratings[0].rating/2)|int(2)) %} 75 | 76 | {% if loop.last and loop.index < 5 %} 77 | {% for numer in range(5 - loop.index) %} 78 | 79 | {% endfor %} 80 | {% endif %} 81 | {% endfor %} 82 |
83 | {% endif %} 84 |
85 |
86 | {% endfor %} 87 | {% endif %} 88 |
89 |
90 | {% endblock %} 91 | -------------------------------------------------------------------------------- /cps/static/locale/mn/viewer.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2012 Mozilla Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Main toolbar buttons (tooltips and alt text for images) 16 | 17 | # LOCALIZATION NOTE (page.title): The tooltip for the pageNumber input. 18 | # LOCALIZATION NOTE (of_pages): "{{pagesCount}}" will be replaced by a number 19 | # representing the total number of pages in the document. 20 | # LOCALIZATION NOTE (page_of_pages): "{{pageNumber}}" and "{{pagesCount}}" 21 | # will be replaced by a number representing the currently visible page, 22 | # respectively a number representing the total number of pages in the document. 23 | 24 | zoom.title=Тэлэлт 25 | open_file.title=Файл нээ 26 | open_file_label=Нээ 27 | 28 | # Secondary toolbar and context menu 29 | 30 | 31 | # Document properties dialog box 32 | document_properties_file_name=Файлын нэр: 33 | # LOCALIZATION NOTE (document_properties_kb): "{{size_kb}}" and "{{size_b}}" 34 | # will be replaced by the PDF file size in kilobytes, respectively in bytes. 35 | # LOCALIZATION NOTE (document_properties_mb): "{{size_mb}}" and "{{size_b}}" 36 | # will be replaced by the PDF file size in megabytes, respectively in bytes. 37 | document_properties_title=Гарчиг: 38 | # LOCALIZATION NOTE (document_properties_date_string): "{{date}}" and "{{time}}" 39 | # will be replaced by the creation/modification date, and time, of the PDF file. 40 | 41 | # LOCALIZATION NOTE (print_progress_percent): "{{progress}}" will be replaced by 42 | # a numerical per cent value. 43 | 44 | # Tooltips and alt text for side panel toolbar buttons 45 | # (the _label strings are alt text for the buttons, the .title strings are 46 | # tooltips) 47 | findbar_label=Ол 48 | 49 | # Thumbnails panel item (tooltip and alt text for images) 50 | # LOCALIZATION NOTE (thumb_page_title): "{{page}}" will be replaced by the page 51 | # number. 52 | # LOCALIZATION NOTE (thumb_page_canvas): "{{page}}" will be replaced by the page 53 | # number. 54 | 55 | # Find panel button title and messages 56 | find_previous.title=Хайлтын өмнөх олдцыг харуулна 57 | find_next.title=Хайлтын дараагийн олдцыг харуулна 58 | find_not_found=Олдсонгүй 59 | 60 | # Error panel labels 61 | error_more_info=Нэмэлт мэдээлэл 62 | # LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be 63 | # replaced by the PDF.JS version and build ID. 64 | # LOCALIZATION NOTE (error_message): "{{message}}" will be replaced by an 65 | # english string describing the error. 66 | # LOCALIZATION NOTE (error_stack): "{{stack}}" will be replaced with a stack 67 | # trace. 68 | # LOCALIZATION NOTE (error_file): "{{file}}" will be replaced with a filename 69 | # LOCALIZATION NOTE (error_line): "{{line}}" will be replaced with a line number 70 | 71 | # Predefined zoom values 72 | # LOCALIZATION NOTE (page_scale_percent): "{{scale}}" will be replaced by a 73 | # numerical scale value. 74 | 75 | # Loading indicator messages 76 | loading_error_indicator=Алдаа 77 | 78 | # LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip. 79 | # "{{type}}" will be replaced with an annotation type from a list defined in 80 | # the PDF spec (32000-1:2008 Table 169 – Annotation types). 81 | # Some common types are e.g.: "Check", "Text", "Comment", "Note" 82 | password_ok=OK 83 | 84 | -------------------------------------------------------------------------------- /cps/static/locale/rw/viewer.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2012 Mozilla Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Main toolbar buttons (tooltips and alt text for images) 16 | 17 | # LOCALIZATION NOTE (page.title): The tooltip for the pageNumber input. 18 | # LOCALIZATION NOTE (of_pages): "{{pagesCount}}" will be replaced by a number 19 | # representing the total number of pages in the document. 20 | # LOCALIZATION NOTE (page_of_pages): "{{pageNumber}}" and "{{pagesCount}}" 21 | # will be replaced by a number representing the currently visible page, 22 | # respectively a number representing the total number of pages in the document. 23 | 24 | zoom.title=Ihindurangano 25 | open_file.title=Gufungura Dosiye 26 | open_file_label=Gufungura 27 | 28 | # Secondary toolbar and context menu 29 | 30 | 31 | # Document properties dialog box 32 | # LOCALIZATION NOTE (document_properties_kb): "{{size_kb}}" and "{{size_b}}" 33 | # will be replaced by the PDF file size in kilobytes, respectively in bytes. 34 | # LOCALIZATION NOTE (document_properties_mb): "{{size_mb}}" and "{{size_b}}" 35 | # will be replaced by the PDF file size in megabytes, respectively in bytes. 36 | document_properties_title=Umutwe: 37 | # LOCALIZATION NOTE (document_properties_date_string): "{{date}}" and "{{time}}" 38 | # will be replaced by the creation/modification date, and time, of the PDF file. 39 | 40 | # LOCALIZATION NOTE (print_progress_percent): "{{progress}}" will be replaced by 41 | # a numerical per cent value. 42 | 43 | # Tooltips and alt text for side panel toolbar buttons 44 | # (the _label strings are alt text for the buttons, the .title strings are 45 | # tooltips) 46 | findbar_label=Gushakisha 47 | 48 | # Thumbnails panel item (tooltip and alt text for images) 49 | # LOCALIZATION NOTE (thumb_page_title): "{{page}}" will be replaced by the page 50 | # number. 51 | # LOCALIZATION NOTE (thumb_page_canvas): "{{page}}" will be replaced by the page 52 | # number. 53 | 54 | # Find panel button title and messages 55 | find_label="Gushaka:" 56 | find_previous.title=Gushaka aho uyu murongo ugaruka mbere y'aha 57 | find_next.title=Gushaka aho uyu murongo wongera kugaruka 58 | find_not_found=Umurongo ntubonetse 59 | 60 | # Error panel labels 61 | # LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be 62 | # replaced by the PDF.JS version and build ID. 63 | # LOCALIZATION NOTE (error_message): "{{message}}" will be replaced by an 64 | # english string describing the error. 65 | # LOCALIZATION NOTE (error_stack): "{{stack}}" will be replaced with a stack 66 | # trace. 67 | # LOCALIZATION NOTE (error_file): "{{file}}" will be replaced with a filename 68 | # LOCALIZATION NOTE (error_line): "{{line}}" will be replaced with a line number 69 | 70 | # Predefined zoom values 71 | # LOCALIZATION NOTE (page_scale_percent): "{{scale}}" will be replaced by a 72 | # numerical scale value. 73 | 74 | # Loading indicator messages 75 | loading_error_indicator=Ikosa 76 | 77 | # LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip. 78 | # "{{type}}" will be replaced with an annotation type from a list defined in 79 | # the PDF spec (32000-1:2008 Table 169 – Annotation types). 80 | # Some common types are e.g.: "Check", "Text", "Comment", "Note" 81 | password_invalid=Ijambo ry'ibanga ridahari. Wakongera ukagerageza 82 | password_ok=YEGO 83 | 84 | -------------------------------------------------------------------------------- /cps/templates/author.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 |

{{title}}

4 | 5 | {% if author is not none %} 6 |
7 | {%if author.image_url is not none %} 8 | {{author.name|safe}} 9 | {% endif %} 10 | 11 | {%if author.about is not none %} 12 |

{{author.about|safe}}

13 | {% endif %} 14 | 15 | - {{_("via")}} Goodreads 16 |
17 | 18 |
19 | {% endif %} 20 | 21 |
22 | {% if author is not none %} 23 |

{{_("In Library")}}

24 | {% endif %} 25 |
26 | {% if entries[0] %} 27 | {% for entry in entries %} 28 |
29 | 38 |
39 |

{{entry.title|shortentitle}}

40 |

41 | {% for author in entry.authors %} 42 | {{author.name.replace('|',',')}} 43 | {% if not loop.last %} 44 | & 45 | {% endif %} 46 | {% endfor %} 47 |

48 | {% if entry.ratings.__len__() > 0 %} 49 |
50 | {% for number in range((entry.ratings[0].rating/2)|int(2)) %} 51 | 52 | {% if loop.last and loop.index < 5 %} 53 | {% for numer in range(5 - loop.index) %} 54 | 55 | {% endfor %} 56 | {% endif %} 57 | {% endfor %} 58 |
59 | {% endif %} 60 |
61 |
62 | {% endfor %} 63 | {% endif %} 64 |
65 |
66 | 67 | {% if other_books %} 68 |
69 |

{{_("More by")}} {{ author.name.replace('|',',')|safe }}

70 |
71 | {% for entry in other_books %} 72 |
73 |
74 | 75 | 76 | 77 |
78 |
79 |

{{entry.title|shortentitle}}

80 |

81 | {% for author in entry.authors %} 82 | 83 | {{author.name.replace('|',',')}} 84 | 85 | {% if not loop.last %} 86 | & 87 | {% endif %} 88 | {% endfor %} 89 |

90 |
91 | {% for number in range((entry.average_rating)|float|round|int(2)) %} 92 | 93 | {% if loop.last and loop.index < 5 %} 94 | {% for numer in range(5 - loop.index) %} 95 | 96 | {% endfor %} 97 | {% endif %} 98 | {% endfor %} 99 |
100 |
101 |
102 | {% endfor %} 103 |
104 | 105 | 106 | Goodreads 107 | 108 |
109 | {% endif %} 110 | {% endblock %} 111 | -------------------------------------------------------------------------------- /cps/static/locale/tn/viewer.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2012 Mozilla Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Main toolbar buttons (tooltips and alt text for images) 16 | 17 | # LOCALIZATION NOTE (page.title): The tooltip for the pageNumber input. 18 | # LOCALIZATION NOTE (of_pages): "{{pagesCount}}" will be replaced by a number 19 | # representing the total number of pages in the document. 20 | # LOCALIZATION NOTE (page_of_pages): "{{pageNumber}}" and "{{pagesCount}}" 21 | # will be replaced by a number representing the currently visible page, 22 | # respectively a number representing the total number of pages in the document. 23 | 24 | zoom.title=Zuma/gogela 25 | open_file.title=Bula Faele 26 | open_file_label=Bula 27 | 28 | # Secondary toolbar and context menu 29 | 30 | hand_tool_disable.title=Thibela go dira ga sediriswa sa seatla 31 | hand_tool_disable_label=Thibela go dira ga sediriswa sa seatla 32 | 33 | # Document properties dialog box 34 | document_properties_file_name=Leina la faele: 35 | # LOCALIZATION NOTE (document_properties_kb): "{{size_kb}}" and "{{size_b}}" 36 | # will be replaced by the PDF file size in kilobytes, respectively in bytes. 37 | # LOCALIZATION NOTE (document_properties_mb): "{{size_mb}}" and "{{size_b}}" 38 | # will be replaced by the PDF file size in megabytes, respectively in bytes. 39 | document_properties_title=Leina: 40 | # LOCALIZATION NOTE (document_properties_date_string): "{{date}}" and "{{time}}" 41 | # will be replaced by the creation/modification date, and time, of the PDF file. 42 | 43 | # LOCALIZATION NOTE (print_progress_percent): "{{progress}}" will be replaced by 44 | # a numerical per cent value. 45 | 46 | # Tooltips and alt text for side panel toolbar buttons 47 | # (the _label strings are alt text for the buttons, the .title strings are 48 | # tooltips) 49 | findbar_label=Batla 50 | 51 | # Thumbnails panel item (tooltip and alt text for images) 52 | # LOCALIZATION NOTE (thumb_page_title): "{{page}}" will be replaced by the page 53 | # number. 54 | # LOCALIZATION NOTE (thumb_page_canvas): "{{page}}" will be replaced by the page 55 | # number. 56 | 57 | # Find panel button title and messages 58 | find_previous.title=Batla tiragalo e e fetileng ya setlhopha sa mafoko 59 | find_next.title=Batla tiragalo e e latelang ya setlhopha sa mafoko 60 | find_not_found=Setlhopha sa mafoko ga se a bonwa 61 | 62 | # Error panel labels 63 | error_more_info=Tshedimosetso e Nngwe 64 | # LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be 65 | # replaced by the PDF.JS version and build ID. 66 | # LOCALIZATION NOTE (error_message): "{{message}}" will be replaced by an 67 | # english string describing the error. 68 | # LOCALIZATION NOTE (error_stack): "{{stack}}" will be replaced with a stack 69 | # trace. 70 | # LOCALIZATION NOTE (error_file): "{{file}}" will be replaced with a filename 71 | # LOCALIZATION NOTE (error_line): "{{line}}" will be replaced with a line number 72 | 73 | # Predefined zoom values 74 | # LOCALIZATION NOTE (page_scale_percent): "{{scale}}" will be replaced by a 75 | # numerical scale value. 76 | 77 | # Loading indicator messages 78 | loading_error_indicator=Phoso 79 | 80 | # LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip. 81 | # "{{type}}" will be replaced with an annotation type from a list defined in 82 | # the PDF spec (32000-1:2008 Table 169 – Annotation types). 83 | # Some common types are e.g.: "Check", "Text", "Comment", "Note" 84 | password_ok=Siame 85 | 86 | web_fonts_disabled=Mefutatlhaka ya Webo ga e dire: ga e kgone go dirisa mofutatlhaka wa PDF o tsentsweng. 87 | -------------------------------------------------------------------------------- /cps/static/js/libs/hooks.min.js: -------------------------------------------------------------------------------- 1 | EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e=EPUBJS.core.folder(location.pathname),f=(EPUBJS.cssPath,{});EPUBJS.core.addCss(EPUBJS.cssPath+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,h,n=b.height,o=b.width,p=225;m||(c=j.cloneNode(!0),m=c.querySelector("p")),f[i]||(f[i]=document.createElement("div"),f[i].setAttribute("class","popup"),pop_content=document.createElement("div"),f[i].appendChild(pop_content),pop_content.appendChild(m),pop_content.setAttribute("class","pop_content"),b.render.document.body.appendChild(f[i]),f[i].addEventListener("mouseover",d,!1),f[i].addEventListener("mouseout",e,!1),b.on("renderer:pageChanged",g,this),b.on("renderer:pageChanged",e,this)),c=f[i],h=a.getBoundingClientRect(),k=h.left,l=h.top,c.classList.add("show"),popRect=c.getBoundingClientRect(),c.style.left=k-popRect.width/2+"px",c.style.top=l+"px",p>n/2.5&&(p=n/2.5,pop_content.style.maxHeight=p+"px"),popRect.height+l>=n-25?(c.style.top=l-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),k-popRect.width<=0?(c.style.left=k+"px",c.classList.add("left")):c.classList.remove("left"),k+popRect.width/2>=o?(c.style.left=k-300+"px",popRect=c.getBoundingClientRect(),c.style.left=k-popRect.width+"px",popRect.height+l>=n-25?(c.style.top=l-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){f[i].classList.add("on")}function e(){f[i].classList.remove("on")}function g(){setTimeout(function(){f[i].classList.remove("show")},100)}var h,i,j,k,l,m;"noteref"==a.getAttribute("epub:type")&&(h=a.getAttribute("href"),i=h.replace("#",""),j=b.render.document.getElementById(i),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",g,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(b.currentChapter.manifestProperties.indexOf("mathml")!==-1){b.render.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;if("reflowable"!=b.layoutSettings.layout)return void a();d.forEach(function(a){var c=function(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,g<0&&(g=0),i+g>=e?(ge&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))},d=function(){b.off("renderer:resized",c),b.off("renderer:chapterUnload",this)};a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnload",d),c()}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]");Array.prototype.slice.call(c).forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()}; -------------------------------------------------------------------------------- /cps/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | from socket import error as SocketError 6 | import sys 7 | import os 8 | try: 9 | from gevent.pywsgi import WSGIServer 10 | from gevent.pool import Pool 11 | from gevent import __version__ as geventVersion 12 | gevent_present = True 13 | except ImportError: 14 | from tornado.wsgi import WSGIContainer 15 | from tornado.httpserver import HTTPServer 16 | from tornado.ioloop import IOLoop 17 | from tornado import version as tornadoVersion 18 | gevent_present = False 19 | 20 | import web 21 | 22 | 23 | class server: 24 | 25 | wsgiserver = None 26 | restart= False 27 | 28 | def __init__(self): 29 | pass 30 | 31 | def start_gevent(self): 32 | try: 33 | ssl_args = dict() 34 | if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile(): 35 | ssl_args = {"certfile": web.ub.config.get_config_certfile(), 36 | "keyfile": web.ub.config.get_config_keyfile()} 37 | if os.name == 'nt': 38 | self.wsgiserver= WSGIServer(('0.0.0.0', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args) 39 | else: 40 | self.wsgiserver = WSGIServer(('', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args) 41 | self.wsgiserver.serve_forever() 42 | 43 | except SocketError: 44 | web.app.logger.info('Unable to listen on \'\', trying on IPv4 only...') 45 | self.wsgiserver = WSGIServer(('0.0.0.0', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args) 46 | self.wsgiserver.serve_forever() 47 | except Exception: 48 | web.app.logger.info("Unknown error while starting gevent") 49 | 50 | def startServer(self): 51 | if gevent_present: 52 | web.app.logger.info('Starting Gevent server') 53 | # leave subprocess out to allow forking for fetchers and processors 54 | self.start_gevent() 55 | else: 56 | web.app.logger.info('Starting Tornado server') 57 | if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile(): 58 | ssl={"certfile": web.ub.config.get_config_certfile(), 59 | "keyfile": web.ub.config.get_config_keyfile()} 60 | else: 61 | ssl=None 62 | # Max Buffersize set to 200MB 63 | http_server = HTTPServer(WSGIContainer(web.app), 64 | max_buffer_size = 209700000, 65 | ssl_options=ssl) 66 | http_server.listen(web.ub.config.config_port) 67 | self.wsgiserver=IOLoop.instance() 68 | self.wsgiserver.start() # wait for stop signal 69 | self.wsgiserver.close(True) 70 | 71 | if self.restart == True: 72 | web.app.logger.info("Performing restart of Calibre-Web") 73 | web.helper.global_WorkerThread.stop() 74 | if os.name == 'nt': 75 | arguments = ["\"" + sys.executable + "\""] 76 | for e in sys.argv: 77 | arguments.append("\"" + e + "\"") 78 | os.execv(sys.executable, arguments) 79 | else: 80 | os.execl(sys.executable, sys.executable, *sys.argv) 81 | else: 82 | web.app.logger.info("Performing shutdown of Calibre-Web") 83 | web.helper.global_WorkerThread.stop() 84 | sys.exit(0) 85 | 86 | def setRestartTyp(self,starttyp): 87 | self.restart=starttyp 88 | 89 | def stopServer(self): 90 | if gevent_present: 91 | self.wsgiserver.close() 92 | else: 93 | self.wsgiserver.add_callback(self.wsgiserver.stop) 94 | 95 | @staticmethod 96 | def getNameVersion(): 97 | if gevent_present: 98 | return {'Gevent':'v'+geventVersion} 99 | else: 100 | return {'Tornado':'v'+tornadoVersion} 101 | 102 | 103 | # Start Instance of Server 104 | Server=server() 105 | -------------------------------------------------------------------------------- /cps/static/locale/tl/viewer.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2012 Mozilla Foundation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Main toolbar buttons (tooltips and alt text for images) 16 | previous.title=Naunang Pahina 17 | next.title=Sunod na Pahina 18 | 19 | # LOCALIZATION NOTE (page.title): The tooltip for the pageNumber input. 20 | # LOCALIZATION NOTE (of_pages): "{{pagesCount}}" will be replaced by a number 21 | # representing the total number of pages in the document. 22 | # LOCALIZATION NOTE (page_of_pages): "{{pageNumber}}" and "{{pagesCount}}" 23 | # will be replaced by a number representing the currently visible page, 24 | # respectively a number representing the total number of pages in the document. 25 | 26 | open_file.title=Magbukas ng file 27 | open_file_label=Buksan 28 | bookmark.title=Kasalukuyang tingin (kopyahin o buksan sa bagong window) 29 | bookmark_label=Kasalukuyang tingin 30 | 31 | # Secondary toolbar and context menu 32 | tools.title=Mga Tool 33 | tools_label=Mga Tool 34 | 35 | 36 | # Document properties dialog box 37 | # LOCALIZATION NOTE (document_properties_kb): "{{size_kb}}" and "{{size_b}}" 38 | # will be replaced by the PDF file size in kilobytes, respectively in bytes. 39 | # LOCALIZATION NOTE (document_properties_mb): "{{size_mb}}" and "{{size_b}}" 40 | # will be replaced by the PDF file size in megabytes, respectively in bytes. 41 | document_properties_title=Pamagat: 42 | # LOCALIZATION NOTE (document_properties_date_string): "{{date}}" and "{{time}}" 43 | # will be replaced by the creation/modification date, and time, of the PDF file. 44 | 45 | # LOCALIZATION NOTE (print_progress_percent): "{{progress}}" will be replaced by 46 | # a numerical per cent value. 47 | 48 | # Tooltips and alt text for side panel toolbar buttons 49 | # (the _label strings are alt text for the buttons, the .title strings are 50 | # tooltips) 51 | thumbs.title=Ipakita ang mga Thumbnails 52 | findbar_label=Hanapin 53 | 54 | # Thumbnails panel item (tooltip and alt text for images) 55 | # LOCALIZATION NOTE (thumb_page_title): "{{page}}" will be replaced by the page 56 | # number. 57 | thumb_page_title=Pahina {{page}} 58 | # LOCALIZATION NOTE (thumb_page_canvas): "{{page}}" will be replaced by the page 59 | # number. 60 | thumb_page_canvas=Thumbnail ng Pahina {{page}} 61 | 62 | # Find panel button title and messages 63 | find_highlight=I-highlight lahat 64 | 65 | # Error panel labels 66 | error_more_info=Maraming Inpormasyon 67 | error_less_info=Maikling Inpormasyon 68 | # LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be 69 | # replaced by the PDF.JS version and build ID. 70 | # LOCALIZATION NOTE (error_message): "{{message}}" will be replaced by an 71 | # english string describing the error. 72 | error_message=Mensahe: {{message}} 73 | # LOCALIZATION NOTE (error_stack): "{{stack}}" will be replaced with a stack 74 | # trace. 75 | # LOCALIZATION NOTE (error_file): "{{file}}" will be replaced with a filename 76 | # LOCALIZATION NOTE (error_line): "{{line}}" will be replaced with a line number 77 | error_line=Linya: {{line}} 78 | rendering_error=May naganap na pagkakamali habang pagsasalin sa pahina. 79 | 80 | # Predefined zoom values 81 | page_scale_width=Haba ng Pahina 82 | page_scale_fit=ang pahina ay angkop 83 | page_scale_auto=awtomatikong pag-imbulog 84 | # LOCALIZATION NOTE (page_scale_percent): "{{scale}}" will be replaced by a 85 | # numerical scale value. 86 | 87 | # Loading indicator messages 88 | loading_error=May maling nangyari habang kinakarga ang PDF. 89 | 90 | # LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip. 91 | # "{{type}}" will be replaced with an annotation type from a list defined in 92 | # the PDF spec (32000-1:2008 Table 169 – Annotation types). 93 | # Some common types are e.g.: "Check", "Text", "Comment", "Note" 94 | password_ok=OK 95 | 96 | -------------------------------------------------------------------------------- /cps/templates/read.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ePubJS Reader 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 42 |
43 | 44 |
45 |
46 | Menu 47 |
48 |
49 | 50 |   –   51 | 52 |
53 |
54 | Bookmark 55 | Settings 56 | Fullscreen 57 |
58 |
59 | 60 |
61 | 62 |
63 | 64 | 65 |
66 |
67 | 78 |
79 | 80 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /cps/static/css/kthoom.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #444; 3 | overflow-x: hidden; 4 | overflow-y: auto; 5 | color: white; 6 | font-family: sans-serif; 7 | margin: 0px; 8 | } 9 | 10 | #main { 11 | text-align: center; 12 | z-index: 2; 13 | } 14 | 15 | .view { 16 | padding-top:0px; 17 | } 18 | 19 | #sidebar a, 20 | #sidebar ul, 21 | #sidebar li, 22 | #sidebar li img { 23 | max-width: 100%; 24 | text-align: center; 25 | } 26 | 27 | #sidebar ul { 28 | position: relative; 29 | } 30 | 31 | #sidebar a { 32 | display: inline-block; 33 | position: relative; 34 | cursor: pointer; 35 | padding: 4px; 36 | 37 | transition: all .2s ease; 38 | } 39 | 40 | #sidebar a:hover, 41 | #sidebar a:focus { 42 | outline: none; 43 | box-shadow: 0px 2px 8px 1px black; 44 | } 45 | 46 | #sidebar a.active, 47 | #sidebar a.active img + span { 48 | background-color: #45B29D; 49 | } 50 | 51 | #sidebar li img { 52 | display: block; 53 | max-height: 200px; 54 | } 55 | 56 | #sidebar li img + span { 57 | position: absolute; 58 | bottom: 0; 59 | right: 0; 60 | padding: 2px; 61 | min-width: 25px; 62 | line-height: 25px; 63 | background: #6b6b6b; 64 | border-top-left-radius: 5px; 65 | } 66 | 67 | #sidebar #panels { 68 | z-index: 1; 69 | } 70 | 71 | #progress { 72 | position: absolute; 73 | display: inline; 74 | top: 0; 75 | left: 0; 76 | right: 0; 77 | min-height: 4px; 78 | font-family: sans-serif; 79 | font-size: 10px; 80 | line-height: 10px; 81 | text-align: right; 82 | 83 | transition: min-height 150ms ease-in-out; 84 | } 85 | 86 | #progress .bar-load, 87 | #progress .bar-read { 88 | display: flex; 89 | align-items: flex-end; 90 | justify-content: flex-end; 91 | position: absolute; 92 | top: 0; 93 | left: 0; 94 | bottom: 0; 95 | 96 | transition: width 150ms ease-in-out; 97 | } 98 | 99 | #progress .bar-load { 100 | color: #000; 101 | background-color: #CCC; 102 | } 103 | 104 | #progress .bar-read { 105 | color: #FFF; 106 | background-color: #45B29D; 107 | } 108 | 109 | #progress .text { 110 | display: none; 111 | padding: 0 5px; 112 | } 113 | 114 | #progress.loading, 115 | #titlebar:hover #progress { 116 | min-height: 10px; 117 | } 118 | 119 | #progress.loading .text, 120 | #titlebar:hover #progress .text { 121 | display: inline-block; 122 | } 123 | 124 | .hide { 125 | display: none !important; 126 | } 127 | 128 | #mainContent { 129 | overflow: auto; 130 | outline: none; 131 | } 132 | 133 | #mainText { 134 | text-align: left; 135 | width: 90%; 136 | position: relative; 137 | top: 10px; 138 | background: #ccc; 139 | color: black; 140 | margin-right: auto; 141 | margin-left: auto; 142 | padding: 10px; 143 | word-wrap: break-word; 144 | } 145 | 146 | #titlebar { 147 | min-height: 25px; 148 | height: auto; 149 | } 150 | 151 | #metainfo { 152 | max-width: 70%; 153 | } 154 | 155 | #prev { 156 | left: 40px; 157 | } 158 | 159 | #next { 160 | right: 40px; 161 | } 162 | 163 | .arrow { 164 | position: absolute; 165 | top: 50%; 166 | margin-top: -32px; 167 | font-size: 64px; 168 | color: #E2E2E2; 169 | font-family: arial, sans-serif; 170 | font-weight: bold; 171 | cursor: pointer; 172 | -webkit-user-select: none; 173 | -khtml-user-select: none; 174 | -moz-user-select: none; 175 | -ms-user-select: none; 176 | user-select: none; 177 | } 178 | 179 | .arrow:hover { 180 | color: #777; 181 | } 182 | 183 | .arrow:active, 184 | .arrow.active { 185 | color: #000; 186 | } 187 | 188 | th, td { 189 | padding: 5px; 190 | } 191 | 192 | th { 193 | text-align: right; 194 | vertical-align: top; 195 | } 196 | 197 | .modal { 198 | /* Makes the modal responsive. Note sure if this should be moved to main.css */ 199 | margin: 0; 200 | max-width: 96%; 201 | transform: translate(-50%, -50%); 202 | } 203 | 204 | .md-content { 205 | min-height: 320px; 206 | height: auto; 207 | } 208 | 209 | .md-content > div { 210 | overflow: hidden; 211 | } 212 | 213 | .md-content > div p { 214 | padding: 5px 0; 215 | } 216 | 217 | .settings-column { 218 | float: left; 219 | min-width: 35%; 220 | padding-bottom: 10px; 221 | } 222 | 223 | .inputs { 224 | margin: -5px; 225 | } 226 | 227 | .inputs input { 228 | vertical-align: middle; 229 | } 230 | 231 | .inputs label { 232 | display: inline-block; 233 | margin: 5px; 234 | white-space: nowrap; 235 | } 236 | 237 | .dark-theme #main { 238 | background-color: #000; 239 | } 240 | 241 | .dark-theme #titlebar { 242 | color: #DDD; 243 | } 244 | 245 | .dark-theme #titlebar a:active { 246 | color: #FFF; 247 | } 248 | 249 | .dark-theme #progress .bar-read { 250 | background-color: red; 251 | } 252 | 253 | 254 | .dark-theme .overlay { 255 | background-color: rgba(0,0,0,0.8); 256 | } 257 | -------------------------------------------------------------------------------- /cps/static/js/libs/context.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * context.js Library associated with > v0.9.6.2 of intention.js 3 | * http://intentionjs.com/ 4 | * 5 | * Copyright 2011, 2013 Dowjones and other contributors 6 | * Released under the MIT license 7 | * 8 | */ 9 | 10 | (function () { 11 | 12 | 'use strict'; 13 | var context = function($, Intention){ 14 | 15 | // create a brand spankin new intention object 16 | var intent=new Intention(), 17 | // placeholder for the horizontal axis 18 | horizontal_axis, 19 | orientation_axis; 20 | 21 | // throttle funtion used for keeping calls to the resize responive 22 | // callback to a minimum 23 | function throttle(callback, interval){ 24 | var lastExec = new Date(), 25 | timer = null; 26 | 27 | return function(e){ 28 | var d = new Date(); 29 | if (d-lastExec < interval) { 30 | if (timer) { 31 | window.clearTimeout(timer); 32 | } 33 | var callbackWrapper = function(event){ 34 | return function(){ 35 | callback(event); 36 | }; 37 | }; 38 | timer = window.setTimeout(callbackWrapper(e), interval); 39 | return false; 40 | } 41 | callback(e); 42 | lastExec = d; 43 | }; 44 | } 45 | 46 | // catchall 47 | // ======================================================================= 48 | intent.responsive([{name:'base'}]).respond('base'); 49 | 50 | // width context? 51 | // ======================================================================= 52 | horizontal_axis = intent.responsive({ 53 | ID:'width', 54 | contexts: [ 55 | {name:'standard', min:840}, 56 | {name:'tablet', min:510}, 57 | {name:'mobile', min:0}], 58 | // compare the return value of the callback to each context 59 | // return true for a match 60 | matcher: function(test, context){ 61 | if(typeof test === 'string'){ 62 | 63 | return test === context.name; 64 | } 65 | return test>=context.min; 66 | }, 67 | // callback, return value is passed to matcher() 68 | // to compare against current context 69 | measure: function(arg){ 70 | 71 | if(typeof arg === 'string'){ 72 | return arg; 73 | } 74 | 75 | return $(window).width(); 76 | }}); 77 | 78 | // orientation context? 79 | // ======================================================================= 80 | orientation_axis = intent.responsive({ 81 | ID:'orientation', 82 | contexts: [{name:'portrait', rotation: 0}, 83 | {name:'landscape', rotation:90}], 84 | matcher: function(measure, ctx){ 85 | return measure === ctx.rotation; 86 | }, 87 | measure: function(){ 88 | var test = Math.abs(window.orientation); 89 | if(test > 0) { 90 | test = 180 - test; 91 | } 92 | return test; 93 | } 94 | }); 95 | 96 | // ONE TIME CHECK AXES: 97 | // touch device? 98 | // ======================================================================= 99 | intent.responsive({ 100 | ID:'touch', 101 | contexts:[{name:'touch'}], 102 | matcher: function() { 103 | return "ontouchstart" in window; 104 | }}).respond(); 105 | 106 | // retina display? 107 | // ======================================================================= 108 | intent.responsive({ 109 | ID: 'highres', 110 | // contexts 111 | contexts:[{name:'highres'}], 112 | // matching: 113 | matcher: function(){ 114 | return window.devicePixelRatio > 1; 115 | }}).respond(); 116 | 117 | // bind events to the window 118 | $(window).on('resize', throttle(horizontal_axis.respond, 100)) 119 | .on('orientationchange', horizontal_axis.respond) 120 | .on('orientationchange', orientation_axis.respond); 121 | 122 | // register the current width and orientation without waiting for a window 123 | // resize 124 | horizontal_axis.respond(); 125 | orientation_axis.respond(); 126 | 127 | $(function(){ 128 | // at doc ready grab all of the elements in the doc 129 | intent.elements(document); 130 | }); 131 | 132 | // return the intention object so that it can be extended by other plugins 133 | return intent; 134 | }; 135 | 136 | (function (root, factory) { 137 | if (typeof define === 'function' && define.amd) { 138 | // AMD. Register as an anonymous module. 139 | define('context', ['jquery', 'intention'], factory); 140 | } else { 141 | // Browser globals 142 | root.intent = factory(root.jQuery, root.Intention); 143 | } 144 | }(this, function ($, Intention) { 145 | return context($, Intention); 146 | })); 147 | }).call(this); -------------------------------------------------------------------------------- /cps/templates/email_edit.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block header %} 3 | 4 | 5 | {% endblock %} 6 | {% block body %} 7 |
8 |

{{title}}

9 |
10 |
11 | 12 | 13 |
14 |
15 | 16 | 17 |
18 |
19 | 20 | 25 |
26 |
27 | 28 | 29 |
30 |
31 | 32 | 33 |
34 |
35 | 36 | 37 |
38 | 39 | 40 | {{_('Back')}} 41 |
42 | {% if g.allow_registration %} 43 |

{{_('Allowed domains for registering')}}

44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 |
54 |
55 | 56 | 57 |
58 | 59 |
60 | {% endif %} 61 |
62 | {% endblock %} 63 | {% block modal %} 64 | {% if g.allow_registration %} 65 | 80 | {% endif %} 81 | {% endblock %} 82 | {% block js %} 83 | {% if g.allow_registration %} 84 | 85 | 86 | 87 | 88 | {% endif %} 89 | {% endblock %} 90 | 91 | --------------------------------------------------------------------------------