nyaa/nyaa/torrents.py

145 lines
4.1 KiB
Python
Raw Normal View History

2017-05-12 18:51:49 +00:00
import base64
import os
2017-05-12 18:51:49 +00:00
import time
from urllib.parse import urlencode
from flask import current_app as app
2017-05-12 18:51:49 +00:00
from orderedset import OrderedSet
from nyaa import bencode
2017-05-12 18:51:49 +00:00
USED_TRACKERS = OrderedSet()
# Limit the amount of trackers added into .torrent files
MAX_TRACKERS = 5
2017-05-12 18:51:49 +00:00
2017-05-22 21:01:23 +00:00
2017-05-12 18:51:49 +00:00
def read_trackers_from_file(file_object):
USED_TRACKERS.clear()
for line in file_object:
line = line.strip()
if line:
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)
2017-05-12 18:51:49 +00:00
# then the user ones
torrent_trackers = torrent.trackers # here be webseeds too
2017-05-12 18:51:49 +00:00
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)
2017-05-12 18:51:49 +00:00
# and finally our tracker list
trackers.update(default_trackers())
return list(trackers), list(webseeds)
2017-05-12 18:51:49 +00:00
2017-05-16 09:47:06 +00:00
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)
2017-05-12 18:51:49 +00:00
def create_magnet(torrent, max_trackers=5, trackers=None):
# Unless specified, we just use default trackers
2017-05-12 18:51:49 +00:00
if trackers is None:
trackers = get_default_trackers()
2017-05-12 18:51:49 +00:00
magnet_parts = [
('dn', torrent.display_name)
]
for tracker in trackers[:max_trackers]:
magnet_parts.append(('tr', tracker))
b32_info_hash = base64.b32encode(torrent.info_hash).decode('utf-8')
return 'magnet:?xt=urn:btih:' + b32_info_hash + '&' + urlencode(magnet_parts)
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
2017-05-12 18:51:49 +00:00
metadata_base = {
'created by': 'NyaaV2',
'creation date': int(time.time()),
'comment': 'NyaaV2 Torrent #' + str(torrent.id), # Throw the url here or something neat
# '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[:MAX_TRACKERS]]
2017-05-12 18:51:49 +00:00
# Add webseeds
if webseeds:
metadata_base['url-list'] = webseeds
2017-05-12 18:51:49 +00:00
return metadata_base
def create_bencoded_torrent(torrent, 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_info = torrent.info.info_dict
bencoded_torrent = prefix[:-1] + b'4:info' + bencoded_info + suffix[1:]
2017-05-12 18:51:49 +00:00
return bencoded_torrent