# -*- 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 . # custom jinja filters from __future__ import division, print_function, unicode_literals import datetime import mimetypes from uuid import uuid4 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 from markupsafe import escape 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 for get, val in request.args.items(): args[get] = val 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: return format_date(val, format='medium', locale=get_locale()) except AttributeError as e: log.error('Babel error: %s, Current user locale: %s, Current User: %s', e, current_user.locale, current_user.name ) return val @jinjia.app_template_filter('formatdateinput') def format_date_input(val): input_date = val.isoformat().split('T', 1)[0] # Hack to support dates <1900 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 @jinjia.app_template_filter('formatfloat') def formatfloat(value, decimals=1): value = 0 if not value else value return ('{0:.' + str(decimals) + 'f}').format(value).rstrip('0').rstrip('.') @jinjia.app_template_filter('formatseriesindex') def formatseriesindex_filter(series_index): if series_index: try: if int(series_index) - series_index == 0: return int(series_index) else: return series_index except ValueError: return series_index return 0 @jinjia.app_template_filter('escapedlink') def escapedlink_filter(url, text): return "{}".format(url, escape(text)) @jinjia.app_template_filter('uuidfilter') def uuidfilter(var): return uuid4() @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)