mirror of
https://github.com/sb745/NyaaV3.git
synced 2025-03-12 22:06:55 +02:00

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.
151 lines
4.3 KiB
Python
151 lines
4.3 KiB
Python
import os
|
|
from urllib.parse import quote, urlencode
|
|
|
|
import flask
|
|
from flask import current_app as app
|
|
|
|
from orderedset import OrderedSet
|
|
|
|
from nyaa import bencode
|
|
|
|
USED_TRACKERS = OrderedSet()
|
|
|
|
|
|
def read_trackers_from_file(file_object):
|
|
USED_TRACKERS.clear()
|
|
|
|
for line in file_object:
|
|
line = line.strip()
|
|
if line and not line.startswith('#'):
|
|
USED_TRACKERS.add(line)
|
|
return USED_TRACKERS
|
|
|
|
|
|
def read_trackers():
|
|
tracker_list_file = os.path.join(app.config['BASE_DIR'], 'trackers.txt')
|
|
|
|
if os.path.exists(tracker_list_file):
|
|
with open(tracker_list_file, 'r') as in_file:
|
|
return read_trackers_from_file(in_file)
|
|
|
|
|
|
def default_trackers():
|
|
if not USED_TRACKERS:
|
|
read_trackers()
|
|
return USED_TRACKERS[:]
|
|
|
|
|
|
def get_trackers_and_webseeds(torrent):
|
|
trackers = OrderedSet()
|
|
webseeds = OrderedSet()
|
|
|
|
# Our main one first
|
|
main_announce_url = app.config.get('MAIN_ANNOUNCE_URL')
|
|
if main_announce_url:
|
|
trackers.add(main_announce_url)
|
|
|
|
# then the user ones
|
|
torrent_trackers = torrent.trackers # here be webseeds too
|
|
for torrent_tracker in torrent_trackers:
|
|
tracker = torrent_tracker.tracker
|
|
|
|
# separate potential webseeds
|
|
if tracker.is_webseed:
|
|
webseeds.add(tracker.uri)
|
|
else:
|
|
trackers.add(tracker.uri)
|
|
|
|
# and finally our tracker list
|
|
trackers.update(default_trackers())
|
|
|
|
return list(trackers), list(webseeds)
|
|
|
|
|
|
def get_default_trackers():
|
|
trackers = OrderedSet()
|
|
|
|
# Our main one first
|
|
main_announce_url = app.config.get('MAIN_ANNOUNCE_URL')
|
|
if main_announce_url:
|
|
trackers.add(main_announce_url)
|
|
|
|
# and finally our tracker list
|
|
trackers.update(default_trackers())
|
|
|
|
return list(trackers)
|
|
|
|
|
|
def create_magnet(torrent, max_trackers=5, trackers=None):
|
|
# Unless specified, we just use default trackers
|
|
if trackers is None:
|
|
trackers = get_default_trackers()
|
|
|
|
magnet_parts = [
|
|
('dn', torrent.display_name)
|
|
]
|
|
magnet_parts.extend(
|
|
('tr', tracker_url)
|
|
for tracker_url in trackers[:max_trackers]
|
|
)
|
|
|
|
# Since we accept both models.Torrents and ES objects,
|
|
# 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):
|
|
if trackers is None or webseeds is None:
|
|
db_trackers, db_webseeds = get_trackers_and_webseeds(torrent)
|
|
|
|
trackers = db_trackers if trackers is None else trackers
|
|
webseeds = db_webseeds if webseeds is None else webseeds
|
|
|
|
metadata_base = {
|
|
'created by': 'NyaaV2',
|
|
'creation date': int(torrent.created_utc_timestamp),
|
|
'comment': flask.url_for('torrents.view',
|
|
torrent_id=torrent.id,
|
|
_external=True)
|
|
# 'encoding' : 'UTF-8' # It's almost always UTF-8 and expected, but if it isn't...
|
|
}
|
|
|
|
if len(trackers) > 0:
|
|
metadata_base['announce'] = trackers[0]
|
|
if len(trackers) > 1:
|
|
# Yes, it's a list of lists with a single element inside.
|
|
metadata_base['announce-list'] = [[tracker] for tracker in trackers]
|
|
|
|
# Add webseeds
|
|
if webseeds:
|
|
metadata_base['url-list'] = webseeds
|
|
|
|
return metadata_base
|
|
|
|
|
|
def create_bencoded_torrent(torrent, bencoded_info, metadata_base=None):
|
|
''' Creates a bencoded torrent metadata for a given torrent,
|
|
optionally using a given metadata_base dict (note: 'info' key will be
|
|
popped off the dict) '''
|
|
if metadata_base is None:
|
|
metadata_base = create_default_metadata_base(torrent)
|
|
|
|
metadata_base['encoding'] = torrent.encoding
|
|
|
|
# Make sure info doesn't exist on the base
|
|
metadata_base.pop('info', None)
|
|
prefixed_dict = {key: metadata_base[key] for key in metadata_base if key < 'info'}
|
|
suffixed_dict = {key: metadata_base[key] for key in metadata_base if key > 'info'}
|
|
|
|
prefix = bencode.encode(prefixed_dict)
|
|
suffix = bencode.encode(suffixed_dict)
|
|
|
|
bencoded_torrent = prefix[:-1] + b'4:info' + bencoded_info + suffix[1:]
|
|
|
|
return bencoded_torrent
|