Merge branch 'master' into Develop
commit
bc6a50550e
@ -1,109 +1,118 @@
|
|||||||
# About
|
# Calibre-Web
|
||||||
|
|
||||||
Calibre-Web is a web app providing a clean interface for browsing, reading and downloading eBooks using a valid [Calibre](https://calibre-ebook.com) database.
|
Calibre-Web is a web app that offers a clean and intuitive interface for browsing, reading, and downloading eBooks using a valid [Calibre](https://calibre-ebook.com) database.
|
||||||
|
|
||||||
[![GitHub License](https://img.shields.io/github/license/janeczku/calibre-web?style=flat-square)](https://github.com/janeczku/calibre-web/blob/master/LICENSE)
|
[![License](https://img.shields.io/github/license/janeczku/calibre-web?style=flat-square)](https://github.com/janeczku/calibre-web/blob/master/LICENSE)
|
||||||
[![GitHub commit activity](https://img.shields.io/github/commit-activity/w/janeczku/calibre-web?logo=github&style=flat-square&label=commits)]()
|
![Commit Activity](https://img.shields.io/github/commit-activity/w/janeczku/calibre-web?logo=github&style=flat-square&label=commits)
|
||||||
[![GitHub all releases](https://img.shields.io/github/downloads/janeczku/calibre-web/total?logo=github&style=flat-square)](https://github.com/janeczku/calibre-web/releases)
|
[![All Releases](https://img.shields.io/github/downloads/janeczku/calibre-web/total?logo=github&style=flat-square)](https://github.com/janeczku/calibre-web/releases)
|
||||||
[![PyPI](https://img.shields.io/pypi/v/calibreweb?logo=pypi&logoColor=fff&style=flat-square)](https://pypi.org/project/calibreweb/)
|
[![PyPI](https://img.shields.io/pypi/v/calibreweb?logo=pypi&logoColor=fff&style=flat-square)](https://pypi.org/project/calibreweb/)
|
||||||
[![PyPI - Downloads](https://img.shields.io/pypi/dm/calibreweb?logo=pypi&logoColor=fff&style=flat-square)](https://pypi.org/project/calibreweb/)
|
[![PyPI - Downloads](https://img.shields.io/pypi/dm/calibreweb?logo=pypi&logoColor=fff&style=flat-square)](https://pypi.org/project/calibreweb/)
|
||||||
[![Discord](https://img.shields.io/discord/838810113564344381?label=Discord&logo=discord&style=flat-square)](https://discord.gg/h2VsJ2NEfB)
|
[![Discord](https://img.shields.io/discord/838810113564344381?label=Discord&logo=discord&style=flat-square)](https://discord.gg/h2VsJ2NEfB)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><strong>Table of Contents</strong> (click to expand)</summary>
|
||||||
|
|
||||||
|
1. [About](#calibre-web)
|
||||||
|
2. [Features](#features)
|
||||||
|
3. [Installation](#installation)
|
||||||
|
- [Installation via pip (recommended)](#installation-via-pip-recommended)
|
||||||
|
- [Quick start](#quick-start)
|
||||||
|
- [Requirements](#requirements)
|
||||||
|
4. [Docker Images](#docker-images)
|
||||||
|
5. [Contributor Recognition](#contributor-recognition)
|
||||||
|
6. [Contact](#contact)
|
||||||
|
7. [Contributing to Calibre-Web](#contributing-to-calibre-web)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
*This software is a fork of [library](https://github.com/mutschler/calibreserver) and licensed under the GPL v3 License.*
|
*This software is a fork of [library](https://github.com/mutschler/calibreserver) and licensed under the GPL v3 License.*
|
||||||
|
|
||||||
![Main screen](https://github.com/janeczku/calibre-web/wiki/images/main_screen.png)
|
![Main screen](https://github.com/janeczku/calibre-web/wiki/images/main_screen.png)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Bootstrap 3 HTML5 interface
|
- Modern and responsive Bootstrap 3 HTML5 interface
|
||||||
- full graphical setup
|
- Full graphical setup
|
||||||
- User management with fine-grained per-user permissions
|
- Comprehensive user management with fine-grained per-user permissions
|
||||||
- Admin interface
|
- Admin interface
|
||||||
- User Interface in brazilian, czech, dutch, english, finnish, french, galician, german, greek, hungarian, indonesian, italian, japanese, khmer, korean, norwegian, polish, russian, simplified and traditional chinese, spanish, swedish, turkish, ukrainian, vietnamese
|
- Multilingual user interface supporting 20+ languages ([supported languages](https://github.com/janeczku/calibre-web/wiki/Translation-Status))
|
||||||
- OPDS feed for eBook reader apps
|
- OPDS feed for eBook reader apps
|
||||||
- Filter and search by titles, authors, tags, series, book format and language
|
- Advanced search and filtering options
|
||||||
- Create a custom book collection (shelves)
|
- Custom book collection (shelves) creation
|
||||||
- Support for editing eBook metadata and deleting eBooks from Calibre library
|
- eBook metadata editing and deletion support
|
||||||
- Support for downloading eBook metadata from various sources, sources can be extended via external plugins
|
- Metadata download from various sources (extensible via plugins)
|
||||||
- Support for converting eBooks through Calibre binaries
|
- eBook conversion through Calibre binaries
|
||||||
- Restrict eBook download to logged-in users
|
- eBook download restriction to logged-in users
|
||||||
- Support for public user registration
|
- Public user registration support
|
||||||
- Send eBooks to E-Readers with the click of a button
|
- Send eBooks to E-Readers with a single click
|
||||||
- Sync your Kobo devices through Calibre-Web with your Calibre library
|
- Sync Kobo devices with your Calibre library
|
||||||
- Support for reading eBooks directly in the browser (.txt, .epub, .pdf, .cbr, .cbt, .cbz, .djvu)
|
- In-browser eBook reading support for multiple formats
|
||||||
- Upload new books in many formats, including audio formats (.mp3, .m4a, .m4b)
|
- Upload new books in various formats, including audio formats
|
||||||
- Support for Calibre Custom Columns
|
- Calibre Custom Columns support
|
||||||
- Ability to hide content based on categories and Custom Column content per user
|
- Content hiding based on categories and Custom Column content per user
|
||||||
- Self-update capability
|
- Self-update capability
|
||||||
- "Magic Link" login to make it easy to log on eReaders
|
- "Magic Link" login for easy access on eReaders
|
||||||
- Login via LDAP, google/github oauth and via proxy authentication
|
- LDAP, Google/GitHub OAuth, and proxy authentication support
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
#### Installation via pip (recommended)
|
#### Installation via pip (recommended)
|
||||||
1. To avoid problems with already installed python dependencies, it's recommended to create a virtual environment for Calibre-Web
|
1. Create a virtual environment for Calibre-Web to avoid conflicts with existing Python dependencies
|
||||||
2. Install Calibre-Web via pip with the command `pip install calibreweb` (Depending on your OS and or distro the command could also be `pip3`).
|
2. Install Calibre-Web via pip: `pip install calibreweb` (or `pip3` depending on your OS/distro)
|
||||||
3. Optional features can also be installed via pip, please refer to [this page](https://github.com/janeczku/calibre-web/wiki/Dependencies-in-Calibre-Web-Linux-and-Windows) for details
|
3. Install optional features via pip as needed, see [this page](https://github.com/janeczku/calibre-web/wiki/Dependencies-in-Calibre-Web-Linux-and-Windows) for details
|
||||||
4. Calibre-Web can be started afterwards by typing `cps`
|
4. Start Calibre-Web by typing `cps`
|
||||||
|
|
||||||
Issues with Raspberry Pi - Raspberry Pi OS:
|
*Note: Raspberry Pi OS users may encounter issues during installation. If so, please update pip (`./venv/bin/python3 -m pip install --upgrade pip`) and/or install cargo (`sudo apt install cargo`) before retrying the installation.*
|
||||||
Depending on your version of pip it's possible that the installation fails with `Failed to build cryptography
|
|
||||||
ERROR: Could not build wheels for cryptography, which is required to install pyproject.toml-based projects`.
|
|
||||||
In this case please try to update pip with `./venv/bin/python3 -m pip install --upgrade pip` first, and then try installing Calibre-Web again.
|
|
||||||
If this isn't working please also install cargo via `sudo apt install cargo`, and try installing Calibre-Web again.
|
|
||||||
|
|
||||||
In the Wiki there are also examples for: a [manual installation](https://github.com/janeczku/calibre-web/wiki/Manual-installation), [installation on Linux Mint](https://github.com/janeczku/calibre-web/wiki/How-To:Install-Calibre-Web-in-Linux-Mint-19-or-20), [installation on a Cloud Provider](https://github.com/janeczku/calibre-web/wiki/How-To:-Install-Calibre-Web-on-a-Cloud-Provider).
|
Refer to the Wiki for additional installation examples: [manual installation](https://github.com/janeczku/calibre-web/wiki/Manual-installation), [Linux Mint](https://github.com/janeczku/calibre-web/wiki/How-To:Install-Calibre-Web-in-Linux-Mint-19-or-20), [Cloud Provider](https://github.com/janeczku/calibre-web/wiki/How-To:-Install-Calibre-Web-on-a-Cloud-Provider).
|
||||||
|
|
||||||
## Quick start
|
## Quick Start
|
||||||
|
|
||||||
Point your browser to `http://localhost:8083` or `http://localhost:8083/opds` for the OPDS catalog \
|
1. Open your browser and navigate to `http://localhost:8083` or `http://localhost:8083/opds` for the OPDS catalog
|
||||||
Login with default admin login \
|
2. Log in with the default admin credentials
|
||||||
If you don't have a Calibre database already, this [database](https://github.com/janeczku/calibre-web/blob/master/library/metadata.db) can be used. **IMPORTATNT** Please move the database out of the calibre-web folder structure, as it will be overwritten during update. \
|
3. If you don't have a Calibre database, you can use [this database](https://github.com/janeczku/calibre-web/blob/master/library/metadata.db) (move it out of the Calibre-Web folder to prevent overwriting during updates)
|
||||||
Set `Location of Calibre database` to the path of the folder where your Calibre library (metadata.db) lives, push "submit" button. \
|
4. Set `Location of Calibre database` to the path of the folder containing your Calibre library (metadata.db) and click "Save"
|
||||||
Optionally a Google Drive can be used to host the calibre library [-> Using Google Drive integration](https://github.com/janeczku/calibre-web/wiki/G-Drive-Setup#using-google-drive-integration) \
|
5. Optionally, use Google Drive to host your Calibre library by following the [Google Drive integration guide](https://github.com/janeczku/calibre-web/wiki/G-Drive-Setup#using-google-drive-integration)
|
||||||
Afterwards you can configure your Calibre-Web instance ([Basic Configuration](https://github.com/janeczku/calibre-web/wiki/Configuration#basic-configuration) and [UI Configuration](https://github.com/janeczku/calibre-web/wiki/Configuration#ui-configuration) on admin page)
|
6. Configure your Calibre-Web instance via the admin page, referring to the [Basic Configuration](https://github.com/janeczku/calibre-web/wiki/Configuration#basic-configuration) and [UI Configuration](https://github.com/janeczku/calibre-web/wiki/Configuration#ui-configuration) guides
|
||||||
|
|
||||||
#### Default admin login:
|
|
||||||
*Username:* admin\
|
|
||||||
*Password:* admin123
|
|
||||||
|
|
||||||
|
#### Default Admin Login:
|
||||||
|
- **Username:** admin
|
||||||
|
- **Password:** admin123
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
python 3.5+
|
- Python 3.5+
|
||||||
|
- [Imagemagick](https://imagemagick.org/script/download.php) for cover extraction from EPUBs (Windows users may need to install [Ghostscript](https://ghostscript.com/releases/gsdnld.html) for PDF cover extraction)
|
||||||
[Download](https://imagemagick.org/script/download.php) Imagemagick to extract covers from epubs. On Windows the additional installation of [ghostscript](https://ghostscript.com/releases/gsdnld.html) might be necessary to extract covers from pdf files. On Linux Imagemagick and Ghostscript can often be installed using the system package manager.
|
- Optional: [Calibre desktop program](https://calibre-ebook.com/download) for on-the-fly conversion and metadata editing (set "calibre's converter tool" path on the setup page)
|
||||||
|
- Optional: [Kepubify tool](https://github.com/pgaskin/kepubify/releases/latest) for Kobo device support (place the binary in `/opt/kepubify` on Linux or `C:\Program Files\kepubify` on Windows)
|
||||||
|
|
||||||
Optionally, to enable on-the-fly conversion from one ebook format to another when using the send-to-ereader feature, or during editing of ebooks metadata:
|
## Docker Images
|
||||||
|
|
||||||
[Download and install](https://calibre-ebook.com/download) the Calibre desktop program for your platform and enter the folder including program name (normally /opt/calibre/ebook-convert, or C:\Program Files\calibre\ebook-convert.exe) in the field "calibre's converter tool" on the setup page.
|
Pre-built Docker images are available in the following Docker Hub repositories (maintained by the LinuxServer team):
|
||||||
|
|
||||||
[Download](https://github.com/pgaskin/kepubify/releases/latest) Kepubify tool for your platform and place the binary starting with `kepubify` in Linux: `/opt/kepubify` Windows: `C:\Program Files\kepubify`.
|
#### **LinuxServer - x64, aarch64**
|
||||||
|
- [Docker Hub](https://hub.docker.com/r/linuxserver/calibre-web)
|
||||||
|
- [GitHub](https://github.com/linuxserver/docker-calibre-web)
|
||||||
|
- [GitHub - Optional Calibre layer](https://github.com/linuxserver/docker-mods/tree/universal-calibre)
|
||||||
|
|
||||||
|
Include the environment variable `DOCKER_MODS=linuxserver/mods:universal-calibre` in your Docker run/compose file to add the Calibre `ebook-convert` binary (x64 only). Omit this variable for a lightweight image.
|
||||||
|
|
||||||
## Docker Images
|
Both the Calibre-Web and Calibre-Mod images are automatically rebuilt on new releases and updates.
|
||||||
|
|
||||||
A pre-built Docker image is available in these Docker Hub repository (maintained by the LinuxServer team):
|
- Set "path to convertertool" to `/usr/bin/ebook-convert`
|
||||||
|
- Set "path to unrar" to `/usr/bin/unrar`
|
||||||
|
|
||||||
#### **LinuxServer - x64, armhf, aarch64**
|
## Contributor Recognition
|
||||||
+ Docker Hub - [https://hub.docker.com/r/linuxserver/calibre-web](https://hub.docker.com/r/linuxserver/calibre-web)
|
|
||||||
+ Github - [https://github.com/linuxserver/docker-calibre-web](https://github.com/linuxserver/docker-calibre-web)
|
|
||||||
+ Github - (Optional Calibre layer) - [https://github.com/linuxserver/docker-calibre-web/tree/calibre](https://github.com/linuxserver/docker-calibre-web/tree/calibre)
|
|
||||||
|
|
||||||
This image has the option to pull in an extra docker manifest layer to include the Calibre `ebook-convert` binary. Just include the environmental variable `DOCKER_MODS=linuxserver/calibre-web:calibre` in your docker run/docker compose file. **(x64 only)**
|
We would like to thank all the [contributors](https://github.com/janeczku/calibre-web/graphs/contributors) and maintainers of Calibre-Web for their valuable input and dedication to the project. Your contributions are greatly appreciated.
|
||||||
|
|
||||||
If you do not need this functionality then this can be omitted, keeping the image as lightweight as possible.
|
|
||||||
|
|
||||||
Both the Calibre-Web and Calibre-Mod images are rebuilt automatically on new releases of Calibre-Web and Calibre respectively, and on updates to any included base image packages on a weekly basis if required.
|
|
||||||
+ The "path to convertertool" should be set to `/usr/bin/ebook-convert`
|
|
||||||
+ The "path to unrar" should be set to `/usr/bin/unrar`
|
|
||||||
|
|
||||||
# Contact
|
## Contact
|
||||||
|
|
||||||
Just reach us out on [Discord](https://discord.gg/h2VsJ2NEfB)
|
Join us on [Discord](https://discord.gg/h2VsJ2NEfB)
|
||||||
|
|
||||||
For further information, How To's and FAQ please check the [Wiki](https://github.com/janeczku/calibre-web/wiki)
|
For more information, How To's, and FAQs, please visit the [Wiki](https://github.com/janeczku/calibre-web/wiki)
|
||||||
|
|
||||||
# Contributing to Calibre-Web
|
## Contributing to Calibre-Web
|
||||||
|
|
||||||
Please have a look at our [Contributing Guidelines](https://github.com/janeczku/calibre-web/blob/master/CONTRIBUTING.md)
|
Check out our [Contributing Guidelines](https://github.com/janeczku/calibre-web/blob/master/CONTRIBUTING.md)
|
||||||
|
@ -1,326 +1,369 @@
|
|||||||
{% extends is_xhr|yesno("fragment.html", "layout.html") %}
|
{% extends is_xhr|yesno("fragment.html", "layout.html") %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="single">
|
<div class="single">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 col-lg-3 col-xs-5">
|
<div class="col-sm-3 col-lg-3 col-xs-5">
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<!-- Always use full-sized image for the detail page -->
|
<!-- Always use full-sized image for the detail page -->
|
||||||
<img id="detailcover" title="{{entry.title}}" src="{{url_for('web.get_cover', book_id=entry.id, resolution='og', c=entry|last_modified)}}" />
|
<img id="detailcover" title="{{ entry.title }}"
|
||||||
</div>
|
src="{{ url_for('web.get_cover', book_id=entry.id, resolution='og', c=entry|last_modified) }}"/>
|
||||||
</div>
|
|
||||||
<div class="col-sm-9 col-lg-9 book-meta">
|
|
||||||
<div class="btn-toolbar" role="toolbar">
|
|
||||||
<div class="btn-group" role="group" aria-label="Download, send to eReader, reading">
|
|
||||||
{% if current_user.role_download() %}
|
|
||||||
{% if entry.data|length %}
|
|
||||||
<div class="btn-group" role="group">
|
|
||||||
{% if entry.data|length < 2 %}
|
|
||||||
<button id="Download" type="button" class="btn btn-primary">
|
|
||||||
{{_('Download')}} :
|
|
||||||
</button>
|
|
||||||
{% for format in entry.data %}
|
|
||||||
<a href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}" id="btnGroupDrop1{{format.format|lower}}" class="btn btn-primary" role="button">
|
|
||||||
<span class="glyphicon glyphicon-download"></span>{{format.format}} ({{ format.uncompressed_size|filesizeformat }})
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
<button id="btnGroupDrop1" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
<span class="glyphicon glyphicon-download"></span> {{_('Download')}}
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
|
||||||
{% for format in entry.data %}
|
|
||||||
<li><a href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}">{{format.format}} ({{ format.uncompressed_size|filesizeformat }})</a></li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
</div>
|
||||||
{% endif %}
|
<div class="col-sm-9 col-lg-9 book-meta">
|
||||||
{% if current_user.kindle_mail and entry.email_share_list %}
|
<div class="btn-toolbar" role="toolbar">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<div class="btn-group" role="group" aria-label="Download, send to eReader, reading">
|
||||||
{% if entry.email_share_list.__len__() == 1 %}
|
{% if current_user.role_download() %}
|
||||||
<div id="sendbtn" data-action="{{url_for('web.send_to_ereader', book_id=entry.id, book_format=entry.email_share_list[0]['format'], convert=entry.email_share_list[0]['convert'])}}" data-text="{{_('Send to eReader')}}" class="btn btn-primary postAction" role="button"><span class="glyphicon glyphicon-send"></span> {{entry.email_share_list[0]['text']}}</div>
|
{% if entry.data|length %}
|
||||||
{% else %}
|
<div class="btn-group" role="group">
|
||||||
<div class="btn-group" role="group">
|
{% if entry.data|length < 2 %}
|
||||||
<button id="sendbtn2" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button id="Download" type="button" class="btn btn-primary">
|
||||||
<span class="glyphicon glyphicon-send"></span>{{_('Send to eReader')}}
|
{{ _('Download') }} :
|
||||||
<span class="caret"></span>
|
</button>
|
||||||
</button>
|
{% for format in entry.data %}
|
||||||
<ul class="dropdown-menu" aria-labelledby="send-to-ereader">
|
<a href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}"
|
||||||
{% for format in entry.email_share_list %}
|
id="btnGroupDrop1{{ format.format|lower }}" class="btn btn-primary"
|
||||||
<li><a class="postAction" data-action="{{url_for('web.send_to_ereader', book_id=entry.id, book_format=format['format'], convert=format['convert'])}}">{{format['text']}}</a></li>
|
role="button">
|
||||||
{%endfor%}
|
<span class="glyphicon glyphicon-download"></span>{{ format.format }}
|
||||||
</ul>
|
({{ format.uncompressed_size|filesizeformat }})
|
||||||
</div>
|
</a>
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% else %}
|
||||||
{% if entry.reader_list and current_user.role_viewer() %}
|
<button id="btnGroupDrop1" type="button" class="btn btn-primary dropdown-toggle"
|
||||||
<div class="btn-group" role="group">
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
{% if entry.reader_list|length > 1 %}
|
<span class="glyphicon glyphicon-download"></span> {{ _('Download') }}
|
||||||
<button id="read-in-browser" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<span class="caret"></span>
|
||||||
<span class="glyphicon glyphicon-book"></span> {{_('Read in Browser')}}
|
</button>
|
||||||
<span class="caret"></span>
|
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
||||||
</button>
|
{% for format in entry.data %}
|
||||||
<ul class="dropdown-menu" aria-labelledby="read-in-browser">
|
<li>
|
||||||
{% for format in entry.reader_list %}
|
<a href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}">{{ format.format }}
|
||||||
<li><a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=format) }}">{{format}}</a></li>
|
({{ format.uncompressed_size|filesizeformat }})</a></li>
|
||||||
{%endfor%}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<a target="_blank" href="{{url_for('web.read_book', book_id=entry.id, book_format=entry.reader_list[0])}}" id="readbtn" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-book"></span> {{_('Read in Browser')}} - {{entry.reader_list[0]}}</a>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
{% endif %}
|
||||||
{% endif %}
|
{% if current_user.kindle_mail and entry.email_share_list %}
|
||||||
{% if entry.audio_entries|length > 0 and current_user.role_viewer() %}
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<div class="btn-group" role="group">
|
{% if entry.email_share_list.__len__() == 1 %}
|
||||||
{% if entry.audio_entries|length > 1 %}
|
<div class="btn-group" role="group">
|
||||||
<button id="listen-in-browser" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button id="sendbtn" class="btn btn-primary sendbtn-form" data-href="{{url_for('web.send_to_ereader', book_id=entry.id, book_format=entry.email_share_list[0]['format'], convert=entry.email_share_list[0]['convert'])}}">
|
||||||
<span class="glyphicon glyphicon-music"></span> {{_('Listen in Browser')}}
|
<span class="glyphicon glyphicon-send"></span> {{entry.email_share_list[0]['text']}}
|
||||||
<span class="caret"></span>
|
</button>
|
||||||
</button>
|
</div>
|
||||||
<ul class="dropdown-menu" aria-labelledby="listen-in-browser">
|
{% else %}
|
||||||
{% for format in entry.reader_list %}
|
<div class="btn-group" role="group">
|
||||||
<li><a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=format) }}">{{format}}</a></li>
|
<button id="sendbtn2" type="button" class="btn btn-primary dropdown-toggle"
|
||||||
{%endfor%}
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
</ul>
|
<span class="glyphicon glyphicon-send"></span>{{ _('Send to eReader') }}
|
||||||
<ul class="dropdown-menu" aria-labelledby="listen-in-browser">
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="send-to-ereader">
|
||||||
|
{% for format in entry.email_share_list %}
|
||||||
|
<li>
|
||||||
|
<a class="sendbtn-form" data-href="{{url_for('web.send_to_ereader', book_id=entry.id, book_format=format['format'], convert=format['convert'])}}">{{ format['text'] }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if entry.reader_list and current_user.role_viewer() %}
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
{% if entry.reader_list|length > 1 %}
|
||||||
|
<button id="read-in-browser" type="button" class="btn btn-primary dropdown-toggle"
|
||||||
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="glyphicon glyphicon-book"></span> {{ _('Read in Browser') }}
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="read-in-browser">
|
||||||
|
{% for format in entry.reader_list %}
|
||||||
|
<li><a target="_blank"
|
||||||
|
href="{{ url_for('web.read_book', book_id=entry.id, book_format=format) }}">{{ format }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<a target="_blank"
|
||||||
|
href="{{ url_for('web.read_book', book_id=entry.id, book_format=entry.reader_list[0]) }}"
|
||||||
|
id="readbtn" class="btn btn-primary" role="button"><span
|
||||||
|
class="glyphicon glyphicon-book"></span> {{ _('Read in Browser') }}
|
||||||
|
- {{ entry.reader_list[0] }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if entry.audio_entries|length > 0 and current_user.role_viewer() %}
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
{% if entry.audio_entries|length > 1 %}
|
||||||
|
<button id="listen-in-browser" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="glyphicon glyphicon-music"></span> {{ _('Listen in Browser') }}
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="listen-in-browser">
|
||||||
|
{% for format in entry.reader_list %}
|
||||||
|
<li><a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=format) }}">{{ format }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="listen-in-browser">
|
||||||
|
|
||||||
{% for format in entry.data %}
|
{% for format in entry.data %}
|
||||||
{% if format.format|lower in entry.audio_entries %}
|
{% if format.format|lower in entry.audio_entries %}
|
||||||
<li><a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=format.format|lower) }}">{{format.format|lower }}</a></li>
|
<li><a target="_blank"
|
||||||
|
href="{{ url_for('web.read_book', book_id=entry.id, book_format=format.format|lower) }}">{{ format.format|lower }}</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=entry.audio_entries[0]) }}" id="listenbtn" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-music"></span> {{ _('Listen in Browser') }} - {{ entry.audio_entries[0] }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
</ul>
|
</div>
|
||||||
{% else %}
|
<h2 id="title">{{ entry.title }}</h2>
|
||||||
<a target="_blank" href="{{url_for('web.read_book', book_id=entry.id, book_format=entry.audio_entries[0])}}" id="listenbtn" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-music"></span> {{_('Listen in Browser')}} - {{entry.audio_entries[0]}}</a>
|
<p class="author">
|
||||||
{% endif %}
|
{% for author in entry.ordered_authors %}
|
||||||
</div>
|
<a href="{{ url_for('web.books_list', data='author', sort_param='stored', book_id=author.id ) }}">{{ author.name.replace('|',',') }}</a>
|
||||||
{% endif %}
|
{% if not loop.last %}
|
||||||
</div>
|
&
|
||||||
</div>
|
{% endif %}
|
||||||
<h2 id="title">{{entry.title}}</h2>
|
{% endfor %}
|
||||||
<p class="author">
|
</p>
|
||||||
{% for author in entry.ordered_authors %}
|
{% if entry.ratings.__len__() > 0 %}
|
||||||
<a href="{{url_for('web.books_list', data='author', sort_param='stored', book_id=author.id ) }}">{{author.name.replace('|',',')}}</a>
|
<div class="rating">
|
||||||
{% if not loop.last %}
|
<p>
|
||||||
&
|
{% for number in range((entry.ratings[0].rating/2)|int(2)) %}
|
||||||
{% endif %}
|
<span class="glyphicon glyphicon-star good"></span>
|
||||||
{% endfor %}
|
{% if loop.last and loop.index < 5 %}
|
||||||
</p>
|
{% for numer in range(5 - loop.index) %}
|
||||||
{% if entry.ratings.__len__() > 0 %}
|
<span class="glyphicon glyphicon-star-empty"></span>
|
||||||
<div class="rating">
|
{% endfor %}
|
||||||
<p>
|
{% endif %}
|
||||||
{% for number in range((entry.ratings[0].rating/2)|int(2)) %}
|
{% endfor %}
|
||||||
<span class="glyphicon glyphicon-star good"></span>
|
</p>
|
||||||
{% if loop.last and loop.index < 5 %}
|
</div>
|
||||||
{% for numer in range(5 - loop.index) %}
|
|
||||||
<span class="glyphicon glyphicon-star-empty"></span>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% if entry.series|length > 0 %}
|
||||||
</p>
|
<p>{{ _("Book %(index)s of %(range)s", index=entry.series_index | formatfloat(2), range=(url_for('web.books_list', data='series', sort_param='stored', book_id=entry.series[0].id)|escapedlink(entry.series[0].name))|safe) }}</p>
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if entry.series|length > 0 %}
|
|
||||||
<p>{{_("Book %(index)s of %(range)s", index=entry.series_index | formatfloat(2), range=(url_for('web.books_list', data='series', sort_param='stored', book_id=entry.series[0].id)|escapedlink(entry.series[0].name))|safe)}}</p>
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if entry.languages.__len__() > 0 %}
|
{% if entry.languages|length > 0 %}
|
||||||
<div class="languages">
|
<div class="languages">
|
||||||
<p>
|
<p>
|
||||||
<span class="label label-default">{{_('Language')}}: {% for language in entry.languages %}{{language.language_name}}{% if not loop.last %}, {% endif %}{% endfor %}</span>
|
<span class="label label-default">{{_('Language')}}: {% for language in entry.languages %}{{language.language_name}}{% if not loop.last %}, {% endif %}{% endfor %}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if entry.identifiers|length > 0 %}
|
{% if entry.identifiers|length > 0 %}
|
||||||
<div class="identifiers">
|
<div class="identifiers">
|
||||||
<p>
|
<p>
|
||||||
<span class="glyphicon glyphicon-link"></span>
|
<span class="glyphicon glyphicon-link"></span>
|
||||||
{% for identifier in entry.identifiers %}
|
{% for identifier in entry.identifiers %}
|
||||||
<a href="{{identifier}}" target="_blank" class="btn btn-xs btn-success" role="button">{{identifier.format_type()}}</a>
|
<a href="{{ identifier }}" target="_blank" class="btn btn-xs btn-success"
|
||||||
{%endfor%}
|
role="button">{{ identifier.format_type() }}</a>
|
||||||
</p>
|
{% endfor %}
|
||||||
</div>
|
</p>
|
||||||
{% endif %}
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if entry.tags|length > 0 %}
|
{% if entry.tags|length > 0 %}
|
||||||
|
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<p>
|
<p>
|
||||||
<span class="glyphicon glyphicon-tags"></span>
|
<span class="glyphicon glyphicon-tags"></span>
|
||||||
|
|
||||||
{% for tag in entry.tags %}
|
{% for tag in entry.tags %}
|
||||||
<a href="{{ url_for('web.books_list', data='category', sort_param='stored', book_id=tag.id) }}" class="btn btn-xs btn-info" role="button">{{tag.name}}</a>
|
<a href="{{ url_for('web.books_list', data='category', sort_param='stored', book_id=tag.id) }}"
|
||||||
{%endfor%}
|
class="btn btn-xs btn-info" role="button">{{ tag.name }}</a>
|
||||||
</p>
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if entry.publishers|length > 0 %}
|
{% if entry.publishers|length > 0 %}
|
||||||
<div class="publishers">
|
<div class="publishers">
|
||||||
<p>
|
<p>
|
||||||
<span>{{_('Publisher')}}:
|
<span>{{ _('Publisher') }}:
|
||||||
<a href="{{url_for('web.books_list', data='publisher', sort_param='stored', book_id=entry.publishers[0].id ) }}">{{entry.publishers[0].name}}</a>
|
<a href="{{ url_for('web.books_list', data='publisher', sort_param='stored', book_id=entry.publishers[0].id ) }}">{{ entry.publishers[0].name }}</a>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if (entry.pubdate|string)[:10] != '0101-01-01' %}
|
{% if (entry.pubdate|string)[:10] != '0101-01-01' %}
|
||||||
<div class="publishing-date">
|
<div class="publishing-date">
|
||||||
<p>{{_('Published')}}: {{entry.pubdate|formatdate}} </p>
|
<p>{{ _('Published') }}: {{ entry.pubdate|formatdate }} </p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if cc|length > 0 %}
|
{% if cc|length > 0 %}
|
||||||
|
|
||||||
|
|
||||||
{% for c in cc %}
|
{% for c in cc %}
|
||||||
<div class="real_custom_columns">
|
<div class="real_custom_columns">
|
||||||
{% if entry['custom_column_' ~ c.id]|length > 0 %}
|
{% if entry['custom_column_' ~ c.id]|length > 0 %}
|
||||||
{{ c.name }}:
|
{{ c.name }}:
|
||||||
{% for column in entry['custom_column_' ~ c.id] %}
|
{% for column in entry['custom_column_' ~ c.id] %}
|
||||||
{% if c.datatype == 'rating' %}
|
{% if c.datatype == 'rating' %}
|
||||||
{{ (column.value / 2)|formatfloat }}
|
{{ (column.value / 2)|formatfloat }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if c.datatype == 'bool' %}
|
{% if c.datatype == 'bool' %}
|
||||||
{% if column.value == true %}
|
{% if column.value == true %}
|
||||||
<span class="glyphicon glyphicon-ok"></span>
|
<span class="glyphicon glyphicon-ok"></span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="glyphicon glyphicon-remove"></span>
|
<span class="glyphicon glyphicon-remove"></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if c.datatype == 'float' %}
|
{% if c.datatype == 'float' %}
|
||||||
{{ column.value|formatfloat(2) }}
|
{{ column.value|formatfloat(2) }}
|
||||||
{% elif c.datatype == 'datetime' %}
|
{% elif c.datatype == 'datetime' %}
|
||||||
{{ column.value|formatdate }}
|
{{ column.value|formatdate }}
|
||||||
{% elif c.datatype == 'comments' %}
|
{% elif c.datatype == 'comments' %}
|
||||||
{{column.value|safe}}
|
{{ column.value|safe }}
|
||||||
{% elif c.datatype == 'series' %}
|
{% elif c.datatype == 'series' %}
|
||||||
{{ '%s [%s]' % (column.value, column.extra|formatfloat(2)) }}
|
{{ '%s [%s]' % (column.value, column.extra|formatfloat(2)) }}
|
||||||
{% elif c.datatype == 'text' %}
|
{% elif c.datatype == 'text' %}
|
||||||
{{ column.value.strip() }}{% if not loop.last %}, {% endif %}
|
{{ column.value.strip() }}{% if not loop.last %}, {% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ column.value }}
|
{{ column.value }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not current_user.is_anonymous %}
|
{% if not current_user.is_anonymous %}
|
||||||
|
|
||||||
<div class="custom_columns">
|
<div class="custom_columns">
|
||||||
<p>
|
<p>
|
||||||
<form id="have_read_form" action="{{ url_for('web.toggle_read', book_id=entry.id)}}" method="POST">
|
<form id="have_read_form" action="{{ url_for('web.toggle_read', book_id=entry.id) }}"
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
method="POST">
|
||||||
<label class="block-label">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<input id="have_read_cb" data-checked="{{_('Mark As Unread')}}" data-unchecked="{{_('Mark As Read')}}" type="checkbox" {% if entry.read_status %}checked{% endif %} >
|
<label class="block-label">
|
||||||
<span>{{_('Read')}}</span>
|
<input id="have_read_cb" data-checked="{{ _('Mark As Unread') }}"
|
||||||
</label>
|
data-unchecked="{{ _('Mark As Read') }}" type="checkbox"
|
||||||
</form>
|
{% if entry.read_status %}checked{% endif %}>
|
||||||
</p>
|
<span>{{ _('Read') }}</span>
|
||||||
{% if current_user.check_visibility(32768) %}
|
</label>
|
||||||
<p>
|
</form>
|
||||||
<form id="archived_form" action="{{ url_for('web.toggle_archived', book_id=entry.id)}}" method="POST">
|
</p>
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
{% if current_user.check_visibility(32768) %}
|
||||||
<label class="block-label">
|
<p>
|
||||||
<input id="archived_cb" data-checked="{{_('Restore from archive')}}" data-unchecked="{{_('Add to archive')}}" type="checkbox" {% if entry.is_archived %}checked{% endif %} >
|
<form id="archived_form" action="{{ url_for('web.toggle_archived', book_id=entry.id) }}"
|
||||||
<span>{{_('Archived')}}</span>
|
method="POST">
|
||||||
</label>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
</form>
|
<label class="block-label">
|
||||||
</p>
|
<input id="archived_cb" data-checked="{{ _('Restore from archive') }}"
|
||||||
{% endif %}
|
data-unchecked="{{ _('Add to archive') }}" type="checkbox"
|
||||||
</div>
|
{% if entry.is_archived %}checked{% endif %}>
|
||||||
{% endif %}
|
<span>{{ _('Archived') }}</span>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% if entry.comments|length > 0 and entry.comments[0].text|length > 0%}
|
{% if entry.comments|length > 0 and entry.comments[0].text|length > 0 %}
|
||||||
<div class="comments">
|
<div class="comments">
|
||||||
<h3 id="decription">{{_('Description:')}}</h3>
|
<h3 id="decription">{{ _('Description:') }}</h3>
|
||||||
{{entry.comments[0].text|safe}}
|
{{ entry.comments[0].text|safe }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<div class="more-stuff">
|
<div class="more-stuff">
|
||||||
|
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
{% if current_user.shelf.all() or g.shelves_access %}
|
{% if current_user.shelf.all() or g.shelves_access %}
|
||||||
<div id="shelf-actions" class="btn-toolbar" role="toolbar">
|
<div id="shelf-actions" class="btn-toolbar" role="toolbar">
|
||||||
<div class="btn-group" role="group" aria-label="Add to shelves">
|
<div class="btn-group" role="group" aria-label="Add to shelves">
|
||||||
<button id="add-to-shelf" type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button id="add-to-shelf" type="button"
|
||||||
<span class="glyphicon glyphicon-list"></span> {{_('Add to shelf')}}
|
class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown"
|
||||||
<span class="caret"></span>
|
aria-haspopup="true" aria-expanded="false">
|
||||||
</button>
|
<span class="glyphicon glyphicon-list"></span> {{ _('Add to shelf') }}
|
||||||
<ul id="add-to-shelves" class="dropdown-menu" aria-labelledby="add-to-shelf">
|
<span class="caret"></span>
|
||||||
{% for shelf in g.shelves_access %}
|
</button>
|
||||||
{% if not shelf.id in books_shelfs and ( not shelf.is_public or current_user.role_edit_shelfs() ) %}
|
<ul id="add-to-shelves" class="dropdown-menu" aria-labelledby="add-to-shelf">
|
||||||
<li>
|
{% for shelf in g.shelves_access %}
|
||||||
<a data-href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
|
{% if not shelf.id in books_shelfs and ( not shelf.is_public or current_user.role_edit_shelfs() ) %}
|
||||||
data-remove-href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
|
<li>
|
||||||
data-shelf-action="add"
|
<a data-href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
|
||||||
>
|
data-remove-href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
|
||||||
{{shelf.name}}{% if shelf.is_public == 1 %} {{_('(Public)')}}{% endif %}
|
data-shelf-action="add"
|
||||||
</a>
|
>
|
||||||
</li>
|
{{ shelf.name }}{% if shelf.is_public == 1 %}
|
||||||
{% endif %}
|
{{ _('(Public)') }}{% endif %}
|
||||||
{%endfor%}
|
</a>
|
||||||
</ul>
|
</li>
|
||||||
</div>
|
{% endif %}
|
||||||
<div id="remove-from-shelves" class="btn-group" role="group" aria-label="Remove from shelves">
|
{% endfor %}
|
||||||
{% if books_shelfs %}
|
</ul>
|
||||||
{% for shelf in g.shelves_access %}
|
</div>
|
||||||
{% if shelf.id in books_shelfs %}
|
<div id="remove-from-shelves" class="btn-group" role="group"
|
||||||
<a data-href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
|
aria-label="Remove from shelves">
|
||||||
data-add-href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
|
{% if books_shelfs %}
|
||||||
class="btn btn-sm btn-default" role="button" data-shelf-action="remove"
|
{% for shelf in g.shelves_access %}
|
||||||
>
|
{% if shelf.id in books_shelfs %}
|
||||||
<span {% if not shelf.is_public or current_user.role_edit_shelfs() %}
|
<a data-href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
|
||||||
class="glyphicon glyphicon-remove"
|
data-add-href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
|
||||||
{% endif %}></span> {{shelf.name}}{% if shelf.is_public == 1 %} {{_('(Public)')}}{% endif %}
|
class="btn btn-sm btn-default" role="button"
|
||||||
</a>
|
data-shelf-action="remove"
|
||||||
{% endif %}
|
>
|
||||||
{%endfor%}
|
<span {% if not shelf.is_public or current_user.role_edit_shelfs() %}
|
||||||
{% endif %}
|
class="glyphicon glyphicon-remove"
|
||||||
</div>
|
{% endif %}></span> {{ shelf.name }}{% if shelf.is_public == 1 %} {{ _('(Public)') }}{% endif %}
|
||||||
<div id="shelf-action-errors" class="pull-left" role="alert"></div>
|
</a>
|
||||||
</div>
|
{% endif %}
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div id="shelf-action-errors" class="pull-left" role="alert"></div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if current_user.role_edit() %}
|
{% if current_user.role_edit() %}
|
||||||
<div class="btn-toolbar" role="toolbar">
|
<div class="btn-toolbar" role="toolbar">
|
||||||
<div class="btn-group" role="group" aria-label="Edit/Delete book">
|
<div class="btn-group" role="group" aria-label="Edit/Delete book">
|
||||||
<a href="{{ url_for('edit-book.show_edit_book', book_id=entry.id) }}" class="btn btn-sm btn-primary" id="edit_book" role="button"><span class="glyphicon glyphicon-edit"></span> {{_('Edit Metadata')}}</a>
|
<a href="{{ url_for('edit-book.show_edit_book', book_id=entry.id) }}"
|
||||||
|
class="btn btn-sm btn-primary" id="edit_book" role="button"><span
|
||||||
|
class="glyphicon glyphicon-edit"></span> {{ _('Edit Metadata') }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<script type="text/template" id="template-shelf-add">
|
<script type="text/template" id="template-shelf-add">
|
||||||
<li>
|
<li>
|
||||||
<a data-href="<%= add %>" data-remove-href="<%= remove %>" data-shelf-action="add">
|
<a data-href="<%= add %>" data-remove-href="<%= remove %>" data-shelf-action="add">
|
||||||
<%= content %>
|
<%= content %>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</script>
|
</script>
|
||||||
<script type="text/template" id="template-shelf-remove">
|
<script type="text/template" id="template-shelf-remove">
|
||||||
<a data-href="<%= remove %>" data-add-href="<%= add %>" class="btn btn-sm btn-default" data-shelf-action="remove">
|
<a data-href="<%= remove %>" data-add-href="<%= add %>" class="btn btn-sm btn-default"
|
||||||
<span class="glyphicon glyphicon-remove"></span> <%= content %>
|
data-shelf-action="remove">
|
||||||
</a>
|
<span class="glyphicon glyphicon-remove"></span> <%= content %>
|
||||||
|
</a>
|
||||||
</script>
|
</script>
|
||||||
<script src="{{ url_for('static', filename='js/details.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/details.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/fullscreen.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/fullscreen.js') }}"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue