Move '/' and '/rss' routes into 'main' blueprint

and update templates.
This commit is contained in:
Kfir Hadas 2017-07-11 00:44:10 +03:00
parent f3b923ccca
commit eccb0ebdff
7 changed files with 177 additions and 168 deletions

View File

@ -1,20 +1,15 @@
import json import json
import math
import os.path import os.path
import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from urllib.parse import quote from urllib.parse import quote
import flask import flask
from flask_paginate import Pagination
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, template_utils, 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.utils import cached_function
_generate_query_string, search_db, search_elastic)
from nyaa.utils import cached_function, chain_get
DEBUG_API = False DEBUG_API = False
@ -64,158 +59,6 @@ def get_category_id_map():
# Routes start here # # Routes start here #
@app.route('/rss', defaults={'rss': True})
@app.route('/', defaults={'rss': False})
def home(rss):
render_as_rss = rss
req_args = flask.request.args
if req_args.get('page') == 'rss':
render_as_rss = True
search_term = chain_get(req_args, 'q', 'term')
sort_key = req_args.get('s')
sort_order = req_args.get('o')
category = chain_get(req_args, 'c', 'cats')
quality_filter = chain_get(req_args, 'f', 'filter')
user_name = chain_get(req_args, 'u', 'user')
page_number = chain_get(req_args, 'p', 'page', 'offset')
try:
page_number = max(1, int(page_number))
except (ValueError, TypeError):
page_number = 1
# Check simply if the key exists
use_magnet_links = 'magnets' in req_args or 'm' in req_args
results_per_page = app.config.get('RESULTS_PER_PAGE', DEFAULT_PER_PAGE)
user_id = None
if user_name:
user = models.User.by_username(user_name)
if not user:
flask.abort(404)
user_id = user.id
special_results = {
'first_word_user': None,
'query_sans_user': None,
'infohash_torrent': None
}
# Add advanced features to searches (but not RSS or user searches)
if search_term and not render_as_rss and not user_id:
# Check if the first word of the search is an existing user
user_word_match = re.match(r'^([a-zA-Z0-9_-]+) *(.*|$)', search_term)
if user_word_match:
special_results['first_word_user'] = models.User.by_username(user_word_match.group(1))
special_results['query_sans_user'] = user_word_match.group(2)
# Check if search is a 40-char torrent hash
infohash_match = re.match(r'(?i)^([a-f0-9]{40})$', search_term)
if infohash_match:
# Check for info hash in database
matched_torrent = models.Torrent.by_info_hash_hex(infohash_match.group(1))
special_results['infohash_torrent'] = matched_torrent
query_args = {
'user': user_id,
'sort': sort_key or 'id',
'order': sort_order or 'desc',
'category': category or '0_0',
'quality_filter': quality_filter or '0',
'page': page_number,
'rss': render_as_rss,
'per_page': results_per_page
}
if flask.g.user:
query_args['logged_in_user'] = flask.g.user
if flask.g.user.is_moderator: # God mode
query_args['admin'] = True
infohash_torrent = special_results.get('infohash_torrent')
if infohash_torrent:
# infohash_torrent is only set if this is not RSS or userpage search
flask.flash(flask.Markup('You were redirected here because '
'the given hash matched this torrent.'), 'info')
# Redirect user from search to the torrent if we found one with the specific info_hash
return flask.redirect(flask.url_for('view_torrent', torrent_id=infohash_torrent.id))
# If searching, we get results from elastic search
use_elastic = app.config.get('USE_ELASTIC_SEARCH')
if use_elastic and search_term:
query_args['term'] = search_term
max_search_results = app.config.get('ES_MAX_SEARCH_RESULT', DEFAULT_MAX_SEARCH_RESULT)
# Only allow up to (max_search_results / page) pages
max_page = min(query_args['page'], int(math.ceil(max_search_results / results_per_page)))
query_args['page'] = max_page
query_args['max_search_results'] = max_search_results
query_results = search_elastic(**query_args)
if render_as_rss:
return render_rss(
'"{}"'.format(search_term), query_results,
use_elastic=True, magnet_links=use_magnet_links)
else:
rss_query_string = _generate_query_string(
search_term, category, quality_filter, user_name)
max_results = min(max_search_results, query_results['hits']['total'])
# change p= argument to whatever you change page_parameter to or pagination breaks
pagination = Pagination(p=query_args['page'], per_page=results_per_page,
total=max_results, bs_version=3, page_parameter='p',
display_msg=SERACH_PAGINATE_DISPLAY_MSG)
return flask.render_template('home.html',
use_elastic=True,
pagination=pagination,
torrent_query=query_results,
search=query_args,
rss_filter=rss_query_string,
special_results=special_results)
else:
# If ES is enabled, default to db search for browsing
if use_elastic:
query_args['term'] = ''
else: # Otherwise, use db search for everything
query_args['term'] = search_term or ''
query = search_db(**query_args)
if render_as_rss:
return render_rss('Home', query, use_elastic=False, magnet_links=use_magnet_links)
else:
rss_query_string = _generate_query_string(
search_term, category, quality_filter, user_name)
# Use elastic is always false here because we only hit this section
# if we're browsing without a search term (which means we default to DB)
# or if ES is disabled
return flask.render_template('home.html',
use_elastic=False,
torrent_query=query,
search=query_args,
rss_filter=rss_query_string,
special_results=special_results)
def render_rss(label, query, use_elastic, magnet_links=False):
rss_xml = flask.render_template('rss.xml',
use_elastic=use_elastic,
magnet_links=magnet_links,
term=label,
site_url=flask.request.url_root,
torrent_query=query)
response = flask.make_response(rss_xml)
response.headers['Content-Type'] = 'application/xml'
# Cache for an hour
response.headers['Cache-Control'] = 'max-age={}'.format(1 * 5 * 60)
return response
@cached_function @cached_function
def _create_upload_category_choices(): def _create_upload_category_choices():
''' Turns categories in the database into a list of (id, name)s ''' ''' Turns categories in the database into a list of (id, name)s '''
@ -487,6 +330,7 @@ def register_blueprints(flask_app):
# Site routes # Site routes
flask_app.register_blueprint(views.account_bp) flask_app.register_blueprint(views.account_bp)
flask_app.register_blueprint(views.admin_bp) flask_app.register_blueprint(views.admin_bp)
flask_app.register_blueprint(views.main_bp)
flask_app.register_blueprint(views.site_bp) flask_app.register_blueprint(views.site_bp)
flask_app.register_blueprint(views.users_bp) flask_app.register_blueprint(views.users_bp)

View File

@ -9,7 +9,7 @@
<link rel="shortcut icon" type="image/png" href="{{ url_for('static', filename='favicon.png') }}"> <link rel="shortcut icon" type="image/png" href="{{ url_for('static', filename='favicon.png') }}">
<link rel="icon" type="image/png" href="{{ url_for('static', filename='favicon.png') }}"> <link rel="icon" type="image/png" href="{{ url_for('static', filename='favicon.png') }}">
<link rel="mask-icon" href="{{ url_for('static', filename='pinned-tab.svg') }}" color="#3582F7"> <link rel="mask-icon" href="{{ url_for('static', filename='pinned-tab.svg') }}" color="#3582F7">
<link rel="alternate" type="application/rss+xml" href="{% if rss_filter %}{{ url_for('home', page='rss', _external=True, **rss_filter) }}{% else %}{{ url_for('home', page='rss', _external=True) }}{% endif %}" /> <link rel="alternate" type="application/rss+xml" href="{% if rss_filter %}{{ url_for('main.home', page='rss', _external=True, **rss_filter) }}{% else %}{{ url_for('main.home', page='rss', _external=True) }}{% endif %}" />
<meta property="og:site_name" content="{{ config.SITE_NAME }}"> <meta property="og:site_name" content="{{ config.SITE_NAME }}">
<meta property="og:title" content="{{ self.title() }}"> <meta property="og:title" content="{{ self.title() }}">
@ -65,7 +65,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="{{ url_for('home') }}">{{ config.SITE_NAME }}</a> <a class="navbar-brand" href="{{ url_for('main.home') }}">{{ config.SITE_NAME }}</a>
</div><!--/.navbar-header --> </div><!--/.navbar-header -->
{% set search_username = (user.username + ("'" if user.username[-1] == 's' else "'s")) if user_page else None %} {% set search_username = (user.username + ("'" if user.username[-1] == 's' else "'s")) if user_page else None %}
{% set search_placeholder = 'Search {} torrents...'.format(search_username) if user_page else 'Search...' %} {% set search_placeholder = 'Search {} torrents...'.format(search_username) if user_page else 'Search...' %}
@ -82,7 +82,7 @@
<li {% if request.path == url_for('site.help') %}class="active"{% endif %}><a href="{{ url_for('site.help') }}">Help</a></li> <li {% if request.path == url_for('site.help') %}class="active"{% endif %}><a href="{{ url_for('site.help') }}">Help</a></li>
</ul> </ul>
</li> </li>
<li><a href="{% if rss_filter %}{{ url_for('home', page='rss', **rss_filter) }}{% else %}{{ url_for('home', page='rss') }}{% endif %}">RSS</a></li> <li><a href="{% if rss_filter %}{{ url_for('main.home', page='rss', **rss_filter) }}{% else %}{{ url_for('main.home', page='rss') }}{% endif %}">RSS</a></li>
{% if config.SITE_FLAVOR == 'nyaa' %} {% if config.SITE_FLAVOR == 'nyaa' %}
<li><a href="//{{ config.EXTERNAL_URLS['fap'] }}">Fap</a></li> <li><a href="//{{ config.EXTERNAL_URLS['fap'] }}">Fap</a></li>
{% elif config.SITE_FLAVOR == 'sukebei' %} {% elif config.SITE_FLAVOR == 'sukebei' %}
@ -216,7 +216,7 @@
{% if user_page %} {% if user_page %}
<form class="navbar-form navbar-right form" action="{{ url_for('users.view_user', user_name=user.username) }}" method="get"> <form class="navbar-form navbar-right form" action="{{ url_for('users.view_user', user_name=user.username) }}" method="get">
{% else %} {% else %}
<form class="navbar-form navbar-right form" action="{{ url_for('home') }}" method="get"> <form class="navbar-form navbar-right form" action="{{ url_for('main.home') }}" method="get">
{% endif %} {% endif %}
<input type="text" class="form-control" name="q" placeholder="{{ search_placeholder }}" value="{{ search["term"] if search is defined else '' }}"> <input type="text" class="form-control" name="q" placeholder="{{ search_placeholder }}" value="{{ search["term"] if search is defined else '' }}">
@ -252,7 +252,7 @@
{% if user_page %} {% if user_page %}
<form class="navbar-form navbar-right form" action="{{ url_for('users.view_user', user_name=user.username) }}" method="get"> <form class="navbar-form navbar-right form" action="{{ url_for('users.view_user', user_name=user.username) }}" method="get">
{% else %} {% else %}
<form class="navbar-form navbar-right form" action="{{ url_for('home') }}" method="get"> <form class="navbar-form navbar-right form" action="{{ url_for('main.home') }}" method="get">
{% endif %} {% endif %}
<div class="input-group search-container hidden-xs hidden-sm"> <div class="input-group search-container hidden-xs hidden-sm">
<div class="input-group-btn nav-filter" id="navFilter-criteria"> <div class="input-group-btn nav-filter" id="navFilter-criteria">

View File

@ -2,8 +2,8 @@
<channel> <channel>
<title>{{ config.SITE_NAME }} - {{ term }} - {% if not magnet_links %}Torrent File{% else %}Magnet URI{% endif %} RSS</title> <title>{{ config.SITE_NAME }} - {{ term }} - {% if not magnet_links %}Torrent File{% else %}Magnet URI{% endif %} RSS</title>
<description>RSS Feed for {{ term }}</description> <description>RSS Feed for {{ term }}</description>
<link>{{ url_for('home', _external=True) }}</link> <link>{{ url_for('main.home', _external=True) }}</link>
<atom:link href="{{ url_for('home', page='rss', _external=True) }}" rel="self" type="application/rss+xml" /> <atom:link href="{{ url_for('main.home', page='rss', _external=True) }}" rel="self" type="application/rss+xml" />
{% for torrent in torrent_query %} {% for torrent in torrent_query %}
<item> <item>
<title>{{ torrent.display_name }}</title> <title>{{ torrent.display_name }}</title>

View File

@ -62,9 +62,9 @@
{% set icon_dir = config.SITE_FLAVOR %} {% set icon_dir = config.SITE_FLAVOR %}
<td style="padding:0 4px;"> <td style="padding:0 4px;">
{% if use_elastic %} {% if use_elastic %}
<a href="{{ url_for('home', c=cat_id) }}" title="{{ category_name(cat_id) }}"> <a href="{{ url_for('main.home', c=cat_id) }}" title="{{ category_name(cat_id) }}">
{% else %} {% else %}
<a href="{{ url_for('home', c=cat_id) }}" title="{{ torrent.main_category.name }} - {{ torrent.sub_category.name }}"> <a href="{{ url_for('main.home', c=cat_id) }}" title="{{ torrent.main_category.name }} - {{ torrent.sub_category.name }}">
{% endif %} {% endif %}
<img src="{{ url_for('static', filename='img/icons/%s/%s.png'|format(icon_dir, cat_id)) }}" alt="{{ category_name(cat_id) }}"> <img src="{{ url_for('static', filename='img/icons/%s/%s.png'|format(icon_dir, cat_id)) }}" alt="{{ category_name(cat_id) }}">
</a> </a>

View File

@ -19,7 +19,7 @@
<div class="row"> <div class="row">
<div class="col-md-1">Category:</div> <div class="col-md-1">Category:</div>
<div class="col-md-5"> <div class="col-md-5">
<a href="{{ url_for('home', c=torrent.main_category.id_as_string) }}">{{ torrent.main_category.name }}</a> - <a href="{{ url_for('home', c=torrent.sub_category.id_as_string) }}">{{ torrent.sub_category.name }}</a> <a href="{{ url_for('main.home', c=torrent.main_category.id_as_string) }}">{{ torrent.main_category.name }}</a> - <a href="{{ url_for('main.home', c=torrent.sub_category.id_as_string) }}">{{ torrent.sub_category.name }}</a>
</div> </div>
<div class="col-md-1">Date:</div> <div class="col-md-1">Date:</div>

View File

@ -1,11 +1,13 @@
from nyaa.views import ( from nyaa.views import (
account, account,
admin, admin,
main,
site, site,
users, users,
) )
account_bp = account.bp account_bp = account.bp
admin_bp = admin.bp admin_bp = admin.bp
main_bp = main.bp
site_bp = site.bp site_bp = site.bp
users_bp = users.bp users_bp = users.bp

163
nyaa/views/main.py Normal file
View File

@ -0,0 +1,163 @@
import math
import re
import flask
from flask_paginate import Pagination
from nyaa import app, models
from nyaa.search import (DEFAULT_MAX_SEARCH_RESULT, DEFAULT_PER_PAGE, SERACH_PAGINATE_DISPLAY_MSG,
_generate_query_string, search_db, search_elastic)
from nyaa.utils import chain_get
bp = flask.Blueprint('main', __name__)
@bp.route('/rss', defaults={'rss': True})
@bp.route('/', defaults={'rss': False})
def home(rss):
render_as_rss = rss
req_args = flask.request.args
if req_args.get('page') == 'rss':
render_as_rss = True
search_term = chain_get(req_args, 'q', 'term')
sort_key = req_args.get('s')
sort_order = req_args.get('o')
category = chain_get(req_args, 'c', 'cats')
quality_filter = chain_get(req_args, 'f', 'filter')
user_name = chain_get(req_args, 'u', 'user')
page_number = chain_get(req_args, 'p', 'page', 'offset')
try:
page_number = max(1, int(page_number))
except (ValueError, TypeError):
page_number = 1
# Check simply if the key exists
use_magnet_links = 'magnets' in req_args or 'm' in req_args
results_per_page = app.config.get('RESULTS_PER_PAGE', DEFAULT_PER_PAGE)
user_id = None
if user_name:
user = models.User.by_username(user_name)
if not user:
flask.abort(404)
user_id = user.id
special_results = {
'first_word_user': None,
'query_sans_user': None,
'infohash_torrent': None
}
# Add advanced features to searches (but not RSS or user searches)
if search_term and not render_as_rss and not user_id:
# Check if the first word of the search is an existing user
user_word_match = re.match(r'^([a-zA-Z0-9_-]+) *(.*|$)', search_term)
if user_word_match:
special_results['first_word_user'] = models.User.by_username(user_word_match.group(1))
special_results['query_sans_user'] = user_word_match.group(2)
# Check if search is a 40-char torrent hash
infohash_match = re.match(r'(?i)^([a-f0-9]{40})$', search_term)
if infohash_match:
# Check for info hash in database
matched_torrent = models.Torrent.by_info_hash_hex(infohash_match.group(1))
special_results['infohash_torrent'] = matched_torrent
query_args = {
'user': user_id,
'sort': sort_key or 'id',
'order': sort_order or 'desc',
'category': category or '0_0',
'quality_filter': quality_filter or '0',
'page': page_number,
'rss': render_as_rss,
'per_page': results_per_page
}
if flask.g.user:
query_args['logged_in_user'] = flask.g.user
if flask.g.user.is_moderator: # God mode
query_args['admin'] = True
infohash_torrent = special_results.get('infohash_torrent')
if infohash_torrent:
# infohash_torrent is only set if this is not RSS or userpage search
flask.flash(flask.Markup('You were redirected here because '
'the given hash matched this torrent.'), 'info')
# Redirect user from search to the torrent if we found one with the specific info_hash
return flask.redirect(flask.url_for('view_torrent', torrent_id=infohash_torrent.id))
# If searching, we get results from elastic search
use_elastic = app.config.get('USE_ELASTIC_SEARCH')
if use_elastic and search_term:
query_args['term'] = search_term
max_search_results = app.config.get('ES_MAX_SEARCH_RESULT', DEFAULT_MAX_SEARCH_RESULT)
# Only allow up to (max_search_results / page) pages
max_page = min(query_args['page'], int(math.ceil(max_search_results / results_per_page)))
query_args['page'] = max_page
query_args['max_search_results'] = max_search_results
query_results = search_elastic(**query_args)
if render_as_rss:
return render_rss(
'"{}"'.format(search_term), query_results,
use_elastic=True, magnet_links=use_magnet_links)
else:
rss_query_string = _generate_query_string(
search_term, category, quality_filter, user_name)
max_results = min(max_search_results, query_results['hits']['total'])
# change p= argument to whatever you change page_parameter to or pagination breaks
pagination = Pagination(p=query_args['page'], per_page=results_per_page,
total=max_results, bs_version=3, page_parameter='p',
display_msg=SERACH_PAGINATE_DISPLAY_MSG)
return flask.render_template('home.html',
use_elastic=True,
pagination=pagination,
torrent_query=query_results,
search=query_args,
rss_filter=rss_query_string,
special_results=special_results)
else:
# If ES is enabled, default to db search for browsing
if use_elastic:
query_args['term'] = ''
else: # Otherwise, use db search for everything
query_args['term'] = search_term or ''
query = search_db(**query_args)
if render_as_rss:
return render_rss('Home', query, use_elastic=False, magnet_links=use_magnet_links)
else:
rss_query_string = _generate_query_string(
search_term, category, quality_filter, user_name)
# Use elastic is always false here because we only hit this section
# if we're browsing without a search term (which means we default to DB)
# or if ES is disabled
return flask.render_template('home.html',
use_elastic=False,
torrent_query=query,
search=query_args,
rss_filter=rss_query_string,
special_results=special_results)
def render_rss(label, query, use_elastic, magnet_links=False):
rss_xml = flask.render_template('rss.xml',
use_elastic=use_elastic,
magnet_links=magnet_links,
term=label,
site_url=flask.request.url_root,
torrent_query=query)
response = flask.make_response(rss_xml)
response.headers['Content-Type'] = 'application/xml'
# Cache for an hour
response.headers['Cache-Control'] = 'max-age={}'.format(1 * 5 * 60)
return response