mirror of
https://gitlab.com/SIGBUS/nyaa.git
synced 2024-12-22 04:00:01 +00:00
search: Allow specifying multiple usernames...
...by repeating &u=user in the GET parameters. No UX for this yet. Reworks the RSS URL generator to fit with duplicated keys.
This commit is contained in:
parent
5bfd7d8695
commit
c655463078
|
@ -3,6 +3,7 @@ import re
|
|||
import shlex
|
||||
import threading
|
||||
import time
|
||||
from urllib.parse import quote, urlencode
|
||||
|
||||
import flask
|
||||
from flask_sqlalchemy import Pagination
|
||||
|
@ -60,17 +61,18 @@ def _get_index_name(column):
|
|||
return table_indexes.get(column.name)
|
||||
|
||||
|
||||
def _generate_query_string(term, category, filter, user):
|
||||
params = {}
|
||||
def _generate_query_string(term, category, filter, user_names):
|
||||
params = []
|
||||
if term:
|
||||
params['q'] = str(term)
|
||||
params.append(('q', str(term)))
|
||||
if category:
|
||||
params['c'] = str(category)
|
||||
params.append(('c', str(category)))
|
||||
if filter:
|
||||
params['f'] = str(filter)
|
||||
if user:
|
||||
params['u'] = str(user)
|
||||
return params
|
||||
params.append(('f', str(filter)))
|
||||
for name in user_names:
|
||||
params.append(('u', name))
|
||||
|
||||
return urlencode(params, quote_via=quote)
|
||||
|
||||
|
||||
# For preprocessing ES search terms in _parse_es_search_terms
|
||||
|
@ -181,7 +183,7 @@ def _parse_es_search_terms(search, search_terms):
|
|||
return search
|
||||
|
||||
|
||||
def search_elastic(term='', user=None, sort='id', order='desc',
|
||||
def search_elastic(term='', user_ids=None, sort='id', order='desc',
|
||||
category='0_0', quality_filter='0', page=1,
|
||||
rss=False, admin=False, logged_in_user=None,
|
||||
per_page=75, max_search_results=1000):
|
||||
|
@ -261,17 +263,9 @@ def search_elastic(term='', user=None, sort='id', order='desc',
|
|||
if not main_category:
|
||||
flask.abort(400)
|
||||
|
||||
# This might be useless since we validate users
|
||||
# before coming into this method, but just to be safe...
|
||||
if user:
|
||||
user = models.User.by_id(user)
|
||||
if not user:
|
||||
flask.abort(404)
|
||||
user = user.id
|
||||
|
||||
same_user = False
|
||||
if logged_in_user:
|
||||
same_user = user == logged_in_user.id
|
||||
same_user = len(user_ids) == 1 and logged_in_user.id in user_ids
|
||||
|
||||
s = Search(using=es_client, index=app.config.get('ES_INDEX_NAME')) # todo, sukebei prefix
|
||||
|
||||
|
@ -281,8 +275,8 @@ def search_elastic(term='', user=None, sort='id', order='desc',
|
|||
s = _parse_es_search_terms(s, term)
|
||||
|
||||
# User view (/user/username)
|
||||
if user:
|
||||
s = s.filter('term', uploader_id=user)
|
||||
if user_ids:
|
||||
s = s.filter('terms', uploader_id=user_ids)
|
||||
|
||||
if not admin:
|
||||
# Hide all DELETED torrents if regular user
|
||||
|
@ -370,7 +364,7 @@ class QueryPairCaller(object):
|
|||
return wrapper
|
||||
|
||||
|
||||
def search_db(term='', user=None, sort='id', order='desc', category='0_0',
|
||||
def search_db(term='', user_ids=None, sort='id', order='desc', category='0_0',
|
||||
quality_filter='0', page=1, rss=False, admin=False,
|
||||
logged_in_user=None, per_page=75):
|
||||
if page > 4294967295:
|
||||
|
@ -380,7 +374,7 @@ def search_db(term='', user=None, sort='id', order='desc', category='0_0',
|
|||
|
||||
same_user = False
|
||||
if logged_in_user:
|
||||
same_user = logged_in_user.id == user
|
||||
same_user = len(user_ids) == 1 and logged_in_user.id in user_ids
|
||||
|
||||
# Logged in users should always be able to view their full listing.
|
||||
if same_user or admin:
|
||||
|
@ -426,12 +420,6 @@ def search_db(term='', user=None, sort='id', order='desc', category='0_0',
|
|||
if filter_tuple is sentinel:
|
||||
flask.abort(400)
|
||||
|
||||
if user:
|
||||
user = models.User.by_id(user)
|
||||
if not user:
|
||||
flask.abort(404)
|
||||
user = user.id
|
||||
|
||||
main_category = None
|
||||
sub_category = None
|
||||
main_cat_id = 0
|
||||
|
@ -469,8 +457,8 @@ def search_db(term='', user=None, sort='id', order='desc', category='0_0',
|
|||
qpc = QueryPairCaller(query, count_query)
|
||||
|
||||
# User view (/user/username)
|
||||
if user:
|
||||
qpc.filter(models.Torrent.uploader_id == user)
|
||||
if user_ids:
|
||||
qpc.filter(models.Torrent.uploader_id.in_(user_ids))
|
||||
|
||||
if not admin:
|
||||
# Hide all DELETED torrents if regular user
|
||||
|
@ -610,7 +598,7 @@ BAKED_FILTER_LAMBDAS = {
|
|||
}
|
||||
|
||||
|
||||
def search_db_baked(term='', user=None, sort='id', order='desc', category='0_0',
|
||||
def search_db_baked(term='', user_ids=None, sort='id', order='desc', category='0_0',
|
||||
quality_filter='0', page=1, rss=False, admin=False,
|
||||
logged_in_user=None, per_page=75):
|
||||
if page > 4294967295:
|
||||
|
@ -631,12 +619,6 @@ def search_db_baked(term='', user=None, sort='id', order='desc', category='0_0',
|
|||
if filter_lambda is sentinel:
|
||||
flask.abort(400)
|
||||
|
||||
if user:
|
||||
user = models.User.by_id(user)
|
||||
if not user:
|
||||
flask.abort(404)
|
||||
user = user.id
|
||||
|
||||
main_cat_id = 0
|
||||
sub_cat_id = 0
|
||||
|
||||
|
@ -664,7 +646,7 @@ def search_db_baked(term='', user=None, sort='id', order='desc', category='0_0',
|
|||
|
||||
same_user = False
|
||||
if logged_in_user:
|
||||
same_user = logged_in_user.id == user
|
||||
same_user = len(user_ids) == 1 and logged_in_user.id in user_ids
|
||||
|
||||
if term:
|
||||
query = bakery(lambda session: session.query(models.TorrentNameSearch))
|
||||
|
@ -685,9 +667,9 @@ def search_db_baked(term='', user=None, sort='id', order='desc', category='0_0',
|
|||
baked_params = {}
|
||||
|
||||
# User view (/user/username)
|
||||
if user:
|
||||
qpc += lambda q: q.filter(models.Torrent.uploader_id == bp('user'))
|
||||
baked_params['user'] = user
|
||||
if user_ids:
|
||||
qpc += lambda q: q.filter(models.Torrent.uploader_id.in_(bp('user_ids', expanding=True)))
|
||||
baked_params['user_ids'] = user_ids
|
||||
|
||||
if not admin:
|
||||
# Hide all DELETED torrents if regular user
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<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="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('main.home', page='rss', _external=True, **rss_filter) }}{% else %}{{ url_for('main.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:title" content="{{ self.title() }}">
|
||||
|
@ -93,7 +93,7 @@
|
|||
<li {% if request.path == url_for('site.trusted') %}class="active"{% endif %}><a href="{{ url_for('site.trusted') }}">Trusted</a></li>
|
||||
</ul>
|
||||
</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>
|
||||
<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' %}
|
||||
<li><a href="//{{ config.EXTERNAL_URLS['fap'] }}">Fap</a></li>
|
||||
{% elif config.SITE_FLAVOR == 'sukebei' %}
|
||||
|
|
|
@ -76,7 +76,7 @@ def home(rss):
|
|||
category = chain_get(req_args, 'c', 'cats')
|
||||
quality_filter = chain_get(req_args, 'f', 'filter')
|
||||
|
||||
user_name = chain_get(req_args, 'u', 'user')
|
||||
user_names = set(req_args.getlist('u') + req_args.getlist('user'))
|
||||
page_number = chain_get(req_args, 'p', 'page', 'offset')
|
||||
try:
|
||||
page_number = max(1, int(page_number))
|
||||
|
@ -88,12 +88,16 @@ def home(rss):
|
|||
|
||||
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:
|
||||
user_ids = []
|
||||
if user_names:
|
||||
for name in user_names:
|
||||
user = models.User.by_username(name)
|
||||
if user:
|
||||
user_ids.append(user.id)
|
||||
# If we have usernames to look up but find none, 404
|
||||
if not user_ids:
|
||||
flask.abort(404)
|
||||
user_id = user.id
|
||||
user_ids = tuple(user_ids)
|
||||
|
||||
special_results = {
|
||||
'first_word_user': None,
|
||||
|
@ -101,7 +105,7 @@ def home(rss):
|
|||
'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:
|
||||
if search_term and not render_as_rss and not user_ids:
|
||||
# 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:
|
||||
|
@ -122,7 +126,7 @@ def home(rss):
|
|||
special_results['infohash_torrent'] = matched_torrent
|
||||
|
||||
query_args = {
|
||||
'user': user_id,
|
||||
'user_ids': user_ids,
|
||||
'sort': sort_key or 'id',
|
||||
'order': sort_order or 'desc',
|
||||
'category': category or '0_0',
|
||||
|
@ -166,7 +170,7 @@ def home(rss):
|
|||
use_elastic=True, magnet_links=use_magnet_links)
|
||||
else:
|
||||
rss_query_string = _generate_query_string(
|
||||
search_term, category, quality_filter, user_name)
|
||||
search_term, category, quality_filter, user_names)
|
||||
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,
|
||||
|
@ -195,7 +199,7 @@ def home(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)
|
||||
search_term, category, quality_filter, user_names)
|
||||
# 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
|
||||
|
|
|
@ -130,7 +130,7 @@ def view_user(user_name):
|
|||
|
||||
query_args = {
|
||||
'term': search_term or '',
|
||||
'user': user.id,
|
||||
'user_ids': (user.id,), # Tuple!
|
||||
'sort': sort_key or 'id',
|
||||
'order': sort_order or 'desc',
|
||||
'category': category or '0_0',
|
||||
|
@ -146,7 +146,7 @@ def view_user(user_name):
|
|||
query_args['admin'] = True
|
||||
|
||||
# Use elastic search for term searching
|
||||
rss_query_string = _generate_query_string(search_term, category, quality_filter, user_name)
|
||||
rss_query_string = _generate_query_string(search_term, category, quality_filter, [user_name])
|
||||
use_elastic = app.config.get('USE_ELASTIC_SEARCH')
|
||||
if use_elastic and search_term:
|
||||
query_args['term'] = search_term
|
||||
|
|
Loading…
Reference in a new issue