mirror of
https://gitlab.com/SIGBUS/nyaa.git
synced 2024-10-31 22:55:53 +00:00
Move template filters and globals into blueprint (#301)
* Move 8 of 9 template filters and globals into a blueprint * Rename nyaa.filters -> nyaa.template_utils * Fix import sorting
This commit is contained in:
parent
50529920bd
commit
f3b923ccca
102
nyaa/routes.py
102
nyaa/routes.py
|
@ -3,17 +3,15 @@ import math
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from email.utils import formatdate
|
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask_paginate import Pagination
|
from flask_paginate import Pagination
|
||||||
from werkzeug import url_encode
|
|
||||||
from werkzeug.datastructures import CombinedMultiDict
|
from werkzeug.datastructures import CombinedMultiDict
|
||||||
|
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from nyaa import api_handler, app, backend, db, forms, models, torrents, views
|
from nyaa import api_handler, app, backend, db, forms, models, template_utils, torrents, views
|
||||||
from nyaa.search import (DEFAULT_MAX_SEARCH_RESULT, DEFAULT_PER_PAGE, SERACH_PAGINATE_DISPLAY_MSG,
|
from nyaa.search import (DEFAULT_MAX_SEARCH_RESULT, DEFAULT_PER_PAGE, SERACH_PAGINATE_DISPLAY_MSG,
|
||||||
_generate_query_string, search_db, search_elastic)
|
_generate_query_string, search_db, search_elastic)
|
||||||
from nyaa.utils import cached_function, chain_get
|
from nyaa.utils import cached_function, chain_get
|
||||||
|
@ -21,51 +19,6 @@ from nyaa.utils import cached_function, chain_get
|
||||||
DEBUG_API = False
|
DEBUG_API = False
|
||||||
|
|
||||||
|
|
||||||
# For static_cachebuster
|
|
||||||
_static_cache = {}
|
|
||||||
|
|
||||||
|
|
||||||
@app.template_global()
|
|
||||||
def static_cachebuster(filename):
|
|
||||||
''' Adds a ?t=<mtime> cachebuster to the given path, if the file exists.
|
|
||||||
Results are cached in memory and persist until app restart! '''
|
|
||||||
# Instead of timestamps, we could use commit hashes (we already load it in __init__)
|
|
||||||
# But that'd mean every static resource would get cache busted. This lets unchanged items
|
|
||||||
# stay in the cache.
|
|
||||||
|
|
||||||
if app.debug:
|
|
||||||
# Do not bust cache on debug (helps debugging)
|
|
||||||
return flask.url_for('static', filename=filename)
|
|
||||||
|
|
||||||
# Get file mtime if not already cached.
|
|
||||||
if filename not in _static_cache:
|
|
||||||
file_path = os.path.join(app.static_folder, filename)
|
|
||||||
file_mtime = None
|
|
||||||
if os.path.exists(file_path):
|
|
||||||
file_mtime = int(os.path.getmtime(file_path))
|
|
||||||
|
|
||||||
_static_cache[filename] = file_mtime
|
|
||||||
|
|
||||||
return flask.url_for('static', filename=filename, t=_static_cache[filename])
|
|
||||||
|
|
||||||
|
|
||||||
@app.template_global()
|
|
||||||
def modify_query(**new_values):
|
|
||||||
args = flask.request.args.copy()
|
|
||||||
|
|
||||||
for key, value in new_values.items():
|
|
||||||
args[key] = value
|
|
||||||
|
|
||||||
return '{}?{}'.format(flask.request.path, url_encode(args))
|
|
||||||
|
|
||||||
|
|
||||||
@app.template_global()
|
|
||||||
def filter_truthy(input_list):
|
|
||||||
''' Jinja2 can't into list comprehension so this is for
|
|
||||||
the search_results.html template '''
|
|
||||||
return [item for item in input_list if item]
|
|
||||||
|
|
||||||
|
|
||||||
@app.template_global()
|
@app.template_global()
|
||||||
def category_name(cat_id):
|
def category_name(cat_id):
|
||||||
''' Given a category id (eg. 1_2), returns a category name (eg. Anime - English-translated) '''
|
''' Given a category id (eg. 1_2), returns a category name (eg. Anime - English-translated) '''
|
||||||
|
@ -96,18 +49,6 @@ def before_request():
|
||||||
return 'You are banned.', 403
|
return 'You are banned.', 403
|
||||||
|
|
||||||
|
|
||||||
@app.template_filter('utc_time')
|
|
||||||
def get_utc_timestamp(datetime_str):
|
|
||||||
''' Returns a UTC POSIX timestamp, as seconds '''
|
|
||||||
UTC_EPOCH = datetime.utcfromtimestamp(0)
|
|
||||||
return int((datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%S') - UTC_EPOCH).total_seconds())
|
|
||||||
|
|
||||||
|
|
||||||
@app.template_filter('display_time')
|
|
||||||
def get_display_time(datetime_str):
|
|
||||||
return datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%S').strftime('%Y-%m-%d %H:%M')
|
|
||||||
|
|
||||||
|
|
||||||
@cached_function
|
@cached_function
|
||||||
def get_category_id_map():
|
def get_category_id_map():
|
||||||
''' Reads database for categories and turns them into a dict with
|
''' Reads database for categories and turns them into a dict with
|
||||||
|
@ -261,16 +202,6 @@ def home(rss):
|
||||||
special_results=special_results)
|
special_results=special_results)
|
||||||
|
|
||||||
|
|
||||||
@app.template_filter('rfc822')
|
|
||||||
def _jinja2_filter_rfc822(date, fmt=None):
|
|
||||||
return formatdate(date.timestamp())
|
|
||||||
|
|
||||||
|
|
||||||
@app.template_filter('rfc822_es')
|
|
||||||
def _jinja2_filter_rfc822_es(datestr, fmt=None):
|
|
||||||
return formatdate(datetime.strptime(datestr, '%Y-%m-%dT%H:%M:%S').timestamp())
|
|
||||||
|
|
||||||
|
|
||||||
def render_rss(label, query, use_elastic, magnet_links=False):
|
def render_rss(label, query, use_elastic, magnet_links=False):
|
||||||
rss_xml = flask.render_template('rss.xml',
|
rss_xml = flask.render_template('rss.xml',
|
||||||
use_elastic=use_elastic,
|
use_elastic=use_elastic,
|
||||||
|
@ -544,40 +475,13 @@ def _get_cached_torrent_file(torrent):
|
||||||
return open(cached_torrent, 'rb'), os.path.getsize(cached_torrent)
|
return open(cached_torrent, 'rb'), os.path.getsize(cached_torrent)
|
||||||
|
|
||||||
|
|
||||||
@app.template_filter()
|
|
||||||
def timesince(dt, default='just now'):
|
|
||||||
"""
|
|
||||||
Returns string representing "time since" e.g.
|
|
||||||
3 minutes ago, 5 hours ago etc.
|
|
||||||
Date and time (UTC) are returned if older than 1 day.
|
|
||||||
"""
|
|
||||||
|
|
||||||
now = datetime.utcnow()
|
|
||||||
diff = now - dt
|
|
||||||
|
|
||||||
periods = (
|
|
||||||
(diff.days, 'day', 'days'),
|
|
||||||
(diff.seconds / 3600, 'hour', 'hours'),
|
|
||||||
(diff.seconds / 60, 'minute', 'minutes'),
|
|
||||||
(diff.seconds, 'second', 'seconds'),
|
|
||||||
)
|
|
||||||
|
|
||||||
if diff.days >= 1:
|
|
||||||
return dt.strftime('%Y-%m-%d %H:%M UTC')
|
|
||||||
else:
|
|
||||||
for period, singular, plural in periods:
|
|
||||||
|
|
||||||
if period >= 1:
|
|
||||||
return '%d %s ago' % (period, singular if int(period) == 1 else plural)
|
|
||||||
|
|
||||||
return default
|
|
||||||
|
|
||||||
|
|
||||||
# #################################### BLUEPRINTS ####################################
|
# #################################### BLUEPRINTS ####################################
|
||||||
|
|
||||||
def register_blueprints(flask_app):
|
def register_blueprints(flask_app):
|
||||||
""" Register the blueprints using the flask_app object """
|
""" Register the blueprints using the flask_app object """
|
||||||
|
|
||||||
|
# Template filters and globals
|
||||||
|
flask_app.register_blueprint(template_utils.bp)
|
||||||
# API routes
|
# API routes
|
||||||
flask_app.register_blueprint(api_handler.api_blueprint, url_prefix='/api')
|
flask_app.register_blueprint(api_handler.api_blueprint, url_prefix='/api')
|
||||||
# Site routes
|
# Site routes
|
||||||
|
|
107
nyaa/template_utils.py
Normal file
107
nyaa/template_utils.py
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
import os.path
|
||||||
|
from datetime import datetime
|
||||||
|
from email.utils import formatdate
|
||||||
|
|
||||||
|
import flask
|
||||||
|
from werkzeug.urls import url_encode
|
||||||
|
|
||||||
|
from nyaa import app
|
||||||
|
|
||||||
|
bp = flask.Blueprint('template-utils', __name__)
|
||||||
|
_static_cache = {} # For static_cachebuster
|
||||||
|
|
||||||
|
|
||||||
|
# ######################### TEMPLATE GLOBALS #########################
|
||||||
|
|
||||||
|
@bp.app_template_global()
|
||||||
|
def static_cachebuster(filename):
|
||||||
|
""" Adds a ?t=<mtime> cachebuster to the given path, if the file exists.
|
||||||
|
Results are cached in memory and persist until app restart! """
|
||||||
|
# Instead of timestamps, we could use commit hashes (we already load it in __init__)
|
||||||
|
# But that'd mean every static resource would get cache busted. This lets unchanged items
|
||||||
|
# stay in the cache.
|
||||||
|
|
||||||
|
if app.debug:
|
||||||
|
# Do not bust cache on debug (helps debugging)
|
||||||
|
return flask.url_for('static', filename=filename)
|
||||||
|
|
||||||
|
# Get file mtime if not already cached.
|
||||||
|
if filename not in _static_cache:
|
||||||
|
file_path = os.path.join(app.static_folder, filename)
|
||||||
|
file_mtime = None
|
||||||
|
if os.path.exists(file_path):
|
||||||
|
file_mtime = int(os.path.getmtime(file_path))
|
||||||
|
|
||||||
|
_static_cache[filename] = file_mtime
|
||||||
|
|
||||||
|
return flask.url_for('static', filename=filename, t=_static_cache[filename])
|
||||||
|
|
||||||
|
|
||||||
|
@bp.app_template_global()
|
||||||
|
def modify_query(**new_values):
|
||||||
|
args = flask.request.args.copy()
|
||||||
|
|
||||||
|
for key, value in new_values.items():
|
||||||
|
args[key] = value
|
||||||
|
|
||||||
|
return '{}?{}'.format(flask.request.path, url_encode(args))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.app_template_global()
|
||||||
|
def filter_truthy(input_list):
|
||||||
|
""" Jinja2 can't into list comprehension so this is for
|
||||||
|
the search_results.html template """
|
||||||
|
return [item for item in input_list if item]
|
||||||
|
|
||||||
|
|
||||||
|
# ######################### TEMPLATE FILTERS #########################
|
||||||
|
|
||||||
|
@bp.app_template_filter('utc_time')
|
||||||
|
def get_utc_timestamp(datetime_str):
|
||||||
|
""" Returns a UTC POSIX timestamp, as seconds """
|
||||||
|
UTC_EPOCH = datetime.utcfromtimestamp(0)
|
||||||
|
return int((datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%S') - UTC_EPOCH).total_seconds())
|
||||||
|
|
||||||
|
|
||||||
|
@bp.app_template_filter('display_time')
|
||||||
|
def get_display_time(datetime_str):
|
||||||
|
return datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%S').strftime('%Y-%m-%d %H:%M')
|
||||||
|
|
||||||
|
|
||||||
|
@bp.app_template_filter('rfc822')
|
||||||
|
def _jinja2_filter_rfc822(date, fmt=None):
|
||||||
|
return formatdate(date.timestamp())
|
||||||
|
|
||||||
|
|
||||||
|
@bp.app_template_filter('rfc822_es')
|
||||||
|
def _jinja2_filter_rfc822_es(datestr, fmt=None):
|
||||||
|
return formatdate(datetime.strptime(datestr, '%Y-%m-%dT%H:%M:%S').timestamp())
|
||||||
|
|
||||||
|
|
||||||
|
@bp.app_template_filter()
|
||||||
|
def timesince(dt, default='just now'):
|
||||||
|
"""
|
||||||
|
Returns string representing "time since" e.g.
|
||||||
|
3 minutes ago, 5 hours ago etc.
|
||||||
|
Date and time (UTC) are returned if older than 1 day.
|
||||||
|
"""
|
||||||
|
|
||||||
|
now = datetime.utcnow()
|
||||||
|
diff = now - dt
|
||||||
|
|
||||||
|
periods = (
|
||||||
|
(diff.days, 'day', 'days'),
|
||||||
|
(diff.seconds / 3600, 'hour', 'hours'),
|
||||||
|
(diff.seconds / 60, 'minute', 'minutes'),
|
||||||
|
(diff.seconds, 'second', 'seconds'),
|
||||||
|
)
|
||||||
|
|
||||||
|
if diff.days >= 1:
|
||||||
|
return dt.strftime('%Y-%m-%d %H:%M UTC')
|
||||||
|
else:
|
||||||
|
for period, singular, plural in periods:
|
||||||
|
|
||||||
|
if period >= 1:
|
||||||
|
return '%d %s ago' % (period, singular if int(period) == 1 else plural)
|
||||||
|
|
||||||
|
return default
|
|
@ -4,11 +4,12 @@ import datetime
|
||||||
from email.utils import formatdate
|
from email.utils import formatdate
|
||||||
|
|
||||||
from tests import NyaaTestCase
|
from tests import NyaaTestCase
|
||||||
from nyaa.routes import (_jinja2_filter_rfc822, _jinja2_filter_rfc822_es, get_utc_timestamp,
|
from nyaa.routes import category_name
|
||||||
get_display_time, timesince, filter_truthy, category_name)
|
from nyaa.template_utils import (_jinja2_filter_rfc822, _jinja2_filter_rfc822_es, get_utc_timestamp,
|
||||||
|
get_display_time, timesince, filter_truthy)
|
||||||
|
|
||||||
|
|
||||||
class TestFilters(NyaaTestCase):
|
class TestTemplateUtils(NyaaTestCase):
|
||||||
|
|
||||||
# def setUp(self):
|
# def setUp(self):
|
||||||
# self.db, nyaa.app.config['DATABASE'] = tempfile.mkstemp()
|
# self.db, nyaa.app.config['DATABASE'] = tempfile.mkstemp()
|
Loading…
Reference in a new issue