torrents: clean up & optimize magnets further

Removes the specialized template ES magnet creator, since create_magnet()
can use both Torrents and ES objects. Search results will get the
properly escaped magnets, now.
Slightly optimizes the tracker adding and string joins.
RIP base32, wonder how many bad clients will break with sha1.
This commit is contained in:
TheAMM 2018-07-21 22:01:19 +03:00
parent ef7ff1b9ce
commit bf090c0fab
4 changed files with 20 additions and 24 deletions

View File

@ -1,15 +1,13 @@
import os.path import os.path
import re import re
from base64 import b32encode
from datetime import datetime from datetime import datetime
from email.utils import formatdate from email.utils import formatdate
from urllib.parse import urlencode
import flask import flask
from werkzeug.urls import url_encode from werkzeug.urls import url_encode
from nyaa.backend import get_category_id_map from nyaa.backend import get_category_id_map
from nyaa.torrents import get_default_trackers from nyaa.torrents import create_magnet
app = flask.current_app app = flask.current_app
bp = flask.Blueprint('template-utils', __name__) bp = flask.Blueprint('template-utils', __name__)
@ -20,20 +18,9 @@ _static_cache = {} # For static_cachebuster
# For processing ES links # For processing ES links
@bp.app_context_processor @bp.app_context_processor
def create_magnet_from_es_info(): def create_magnet_from_es_torrent():
def _create_magnet_from_es_info(display_name, info_hash, max_trackers=5, trackers=None): # Since ES entries look like ducks, we can use the create_magnet as-is
if trackers is None: return dict(create_magnet_from_es_torrent=create_magnet)
trackers = get_default_trackers()
magnet_parts = [
('dn', display_name)
]
for tracker in trackers[:max_trackers]:
magnet_parts.append(('tr', tracker))
b32_info_hash = b32encode(bytes.fromhex(info_hash)).decode('utf-8')
return 'magnet:?xt=urn:btih:' + b32_info_hash + '&' + urlencode(magnet_parts)
return dict(create_magnet_from_es_info=_create_magnet_from_es_info)
# ######################### TEMPLATE GLOBALS ######################### # ######################### TEMPLATE GLOBALS #########################

View File

@ -12,7 +12,7 @@
{% if torrent.has_torrent and not magnet_links %} {% if torrent.has_torrent and not magnet_links %}
<link>{{ url_for('torrents.download', torrent_id=torrent.meta.id, _external=True) }}</link> <link>{{ url_for('torrents.download', torrent_id=torrent.meta.id, _external=True) }}</link>
{% else %} {% else %}
<link>{{ create_magnet_from_es_info(torrent.display_name, torrent.info_hash) }}</link> <link>{{ create_magnet_from_es_torrent(torrent) }}</link>
{% endif %} {% endif %}
<guid isPermaLink="true">{{ url_for('torrents.view', torrent_id=torrent.meta.id, _external=True) }}</guid> <guid isPermaLink="true">{{ url_for('torrents.view', torrent_id=torrent.meta.id, _external=True) }}</guid>
<pubDate>{{ torrent.created_time|rfc822_es }}</pubDate> <pubDate>{{ torrent.created_time|rfc822_es }}</pubDate>

View File

@ -86,7 +86,7 @@
<td class="text-center" style="white-space: nowrap;"> <td class="text-center" style="white-space: nowrap;">
{% if torrent.has_torrent %}<a href="{{ url_for('torrents.download', torrent_id=torrent_id) }}"><i class="fa fa-fw fa-download"></i></a>{% endif %} {% if torrent.has_torrent %}<a href="{{ url_for('torrents.download', torrent_id=torrent_id) }}"><i class="fa fa-fw fa-download"></i></a>{% endif %}
{% if use_elastic %} {% if use_elastic %}
<a href="{{ create_magnet_from_es_info(torrent.display_name, torrent.info_hash) }}"><i class="fa fa-fw fa-magnet"></i></a> <a href="{{ create_magnet_from_es_torrent(torrent) }}"><i class="fa fa-fw fa-magnet"></i></a>
{% else %} {% else %}
<a href="{{ torrent.magnet_uri }}"><i class="fa fa-fw fa-magnet"></i></a> <a href="{{ torrent.magnet_uri }}"><i class="fa fa-fw fa-magnet"></i></a>
{% endif %} {% endif %}

View File

@ -1,4 +1,3 @@
import base64
import os import os
from urllib.parse import quote, urlencode from urllib.parse import quote, urlencode
@ -84,11 +83,21 @@ def create_magnet(torrent, max_trackers=5, trackers=None):
magnet_parts = [ magnet_parts = [
('dn', torrent.display_name) ('dn', torrent.display_name)
] ]
for tracker in trackers[:max_trackers]: magnet_parts.extend(
magnet_parts.append(('tr', tracker)) ('tr', tracker_url)
for tracker_url in trackers[:max_trackers]
)
b32_info_hash = base64.b32encode(torrent.info_hash).decode('utf-8') # Since we accept both models.Torrents and ES objects,
return 'magnet:?xt=urn:btih:' + b32_info_hash + '&' + urlencode(magnet_parts, quote_via=quote) # we need to make sure the info_hash is a hex string
info_hash = torrent.info_hash
if isinstance(info_hash, (bytes, bytearray)):
info_hash = info_hash.hex()
return ''.join([
'magnet:?xt=urn:btih:', info_hash,
'&', urlencode(magnet_parts, quote_via=quote)
])
def create_default_metadata_base(torrent, trackers=None, webseeds=None): def create_default_metadata_base(torrent, trackers=None, webseeds=None):