2019-07-13 18:45:48 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
|
|
|
|
# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11,
|
|
|
|
# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh,
|
|
|
|
# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe,
|
|
|
|
# ruben-herold, marblepebble, JackED42, SiphonSquirrel,
|
|
|
|
# apetresc, nanu-c, mutschler
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
# custom jinja filters
|
|
|
|
|
|
|
|
from __future__ import division, print_function, unicode_literals
|
|
|
|
import datetime
|
|
|
|
import mimetypes
|
2020-11-22 09:03:10 +00:00
|
|
|
from uuid import uuid4
|
2019-07-13 18:45:48 +00:00
|
|
|
|
|
|
|
from babel.dates import format_date
|
|
|
|
from flask import Blueprint, request, url_for
|
|
|
|
from flask_babel import get_locale
|
|
|
|
from flask_login import current_user
|
2021-08-27 07:43:32 +00:00
|
|
|
from markupsafe import escape
|
2019-07-13 18:45:48 +00:00
|
|
|
from . import logger
|
|
|
|
|
|
|
|
|
|
|
|
jinjia = Blueprint('jinjia', __name__)
|
|
|
|
log = logger.create()
|
|
|
|
|
|
|
|
|
|
|
|
# pagination links in jinja
|
|
|
|
@jinjia.app_template_filter('url_for_other_page')
|
|
|
|
def url_for_other_page(page):
|
|
|
|
args = request.view_args.copy()
|
|
|
|
args['page'] = page
|
2020-10-04 17:23:06 +00:00
|
|
|
for get, val in request.args.items():
|
|
|
|
args[get] = val
|
2019-07-13 18:45:48 +00:00
|
|
|
return url_for(request.endpoint, **args)
|
|
|
|
|
|
|
|
|
|
|
|
# shortentitles to at longest nchar, shorten longer words if necessary
|
|
|
|
@jinjia.app_template_filter('shortentitle')
|
|
|
|
def shortentitle_filter(s, nchar=20):
|
|
|
|
text = s.split()
|
|
|
|
res = "" # result
|
|
|
|
suml = 0 # overall length
|
|
|
|
for line in text:
|
|
|
|
if suml >= 60:
|
|
|
|
res += '...'
|
|
|
|
break
|
|
|
|
# if word longer than 20 chars truncate line and append '...', otherwise add whole word to result
|
|
|
|
# string, and summarize total length to stop at chars given by nchar
|
|
|
|
if len(line) > nchar:
|
|
|
|
res += line[:(nchar-3)] + '[..] '
|
|
|
|
suml += nchar+3
|
|
|
|
else:
|
|
|
|
res += line + ' '
|
|
|
|
suml += len(line) + 1
|
|
|
|
return res.strip()
|
|
|
|
|
|
|
|
|
|
|
|
@jinjia.app_template_filter('mimetype')
|
|
|
|
def mimetype_filter(val):
|
|
|
|
return mimetypes.types_map.get('.' + val, 'application/octet-stream')
|
|
|
|
|
|
|
|
|
|
|
|
@jinjia.app_template_filter('formatdate')
|
|
|
|
def formatdate_filter(val):
|
|
|
|
try:
|
2020-06-06 07:52:35 +00:00
|
|
|
return format_date(val, format='medium', locale=get_locale())
|
2019-07-13 18:45:48 +00:00
|
|
|
except AttributeError as e:
|
2020-04-19 17:08:58 +00:00
|
|
|
log.error('Babel error: %s, Current user locale: %s, Current User: %s', e,
|
|
|
|
current_user.locale,
|
2021-03-21 17:55:02 +00:00
|
|
|
current_user.name
|
2020-04-19 17:08:58 +00:00
|
|
|
)
|
2020-06-06 07:52:35 +00:00
|
|
|
return val
|
2019-07-13 18:45:48 +00:00
|
|
|
|
2020-04-19 17:08:58 +00:00
|
|
|
|
2019-07-13 18:45:48 +00:00
|
|
|
@jinjia.app_template_filter('formatdateinput')
|
|
|
|
def format_date_input(val):
|
2020-06-06 07:52:35 +00:00
|
|
|
input_date = val.isoformat().split('T', 1)[0] # Hack to support dates <1900
|
2019-07-13 18:45:48 +00:00
|
|
|
return '' if input_date == "0101-01-01" else input_date
|
|
|
|
|
|
|
|
|
|
|
|
@jinjia.app_template_filter('strftime')
|
|
|
|
def timestamptodate(date, fmt=None):
|
|
|
|
date = datetime.datetime.fromtimestamp(
|
|
|
|
int(date)/1000
|
|
|
|
)
|
|
|
|
native = date.replace(tzinfo=None)
|
|
|
|
if fmt:
|
|
|
|
time_format = fmt
|
|
|
|
else:
|
|
|
|
time_format = '%d %m %Y - %H:%S'
|
|
|
|
return native.strftime(time_format)
|
|
|
|
|
|
|
|
|
|
|
|
@jinjia.app_template_filter('yesno')
|
|
|
|
def yesno(value, yes, no):
|
|
|
|
return yes if value else no
|
2020-07-25 17:39:19 +00:00
|
|
|
|
2020-10-10 10:47:49 +00:00
|
|
|
|
2020-07-25 17:39:19 +00:00
|
|
|
@jinjia.app_template_filter('formatfloat')
|
|
|
|
def formatfloat(value, decimals=1):
|
2021-07-11 11:15:13 +00:00
|
|
|
value = 0 if not value else value
|
2021-07-12 12:04:23 +00:00
|
|
|
return ('{0:.' + str(decimals) + 'f}').format(value).rstrip('0').rstrip('.')
|
2020-10-10 10:47:49 +00:00
|
|
|
|
|
|
|
|
2020-06-30 06:34:26 +00:00
|
|
|
@jinjia.app_template_filter('formatseriesindex')
|
|
|
|
def formatseriesindex_filter(series_index):
|
2020-10-10 10:47:49 +00:00
|
|
|
if series_index:
|
2021-05-19 17:54:44 +00:00
|
|
|
try:
|
|
|
|
if int(series_index) - series_index == 0:
|
|
|
|
return int(series_index)
|
|
|
|
else:
|
|
|
|
return series_index
|
|
|
|
except ValueError:
|
2020-10-10 10:47:49 +00:00
|
|
|
return series_index
|
|
|
|
return 0
|
|
|
|
|
2021-09-17 06:42:56 +00:00
|
|
|
|
2021-08-27 07:43:32 +00:00
|
|
|
@jinjia.app_template_filter('escapedlink')
|
|
|
|
def escapedlink_filter(url, text):
|
|
|
|
return "<a href='{}'>{}</a>".format(url, escape(text))
|
2021-03-20 10:32:50 +00:00
|
|
|
|
2021-09-17 06:42:56 +00:00
|
|
|
|
2020-11-22 09:03:10 +00:00
|
|
|
@jinjia.app_template_filter('uuidfilter')
|
|
|
|
def uuidfilter(var):
|
|
|
|
return uuid4()
|
|
|
|
|
|
|
|
|
2021-03-20 10:32:50 +00:00
|
|
|
@jinjia.app_template_filter('book_cover_cache_id')
|
|
|
|
def book_cover_cache_id(book, resolution=None):
|
|
|
|
timestamp = int(book.last_modified.timestamp() * 1000)
|
|
|
|
cache_bust = str(book.uuid) + '_' + str(timestamp)
|
|
|
|
return cache_bust if not resolution else cache_bust + '_' + str(resolution)
|
|
|
|
|
|
|
|
|
|
|
|
@jinjia.app_template_filter('get_book_thumbnails')
|
|
|
|
def get_book_thumbnails(book_id, thumbnails=None):
|
|
|
|
return list(filter(lambda t: t.book_id == book_id, thumbnails)) if book_id > -1 and thumbnails else list()
|
|
|
|
|
|
|
|
|
|
|
|
@jinjia.app_template_filter('get_book_thumbnail_srcset')
|
|
|
|
def get_book_thumbnail_srcset(thumbnails):
|
|
|
|
srcset = list()
|
|
|
|
for thumbnail in thumbnails:
|
|
|
|
timestamp = int(thumbnail.generated_at.timestamp() * 1000)
|
|
|
|
cache_id = str(thumbnail.uuid) + '_' + str(timestamp)
|
|
|
|
url = url_for('web.get_cached_cover_thumbnail', cache_id=cache_id)
|
|
|
|
srcset.append(url + ' ' + str(thumbnail.resolution) + 'x')
|
|
|
|
return ', '.join(srcset)
|