import time import os import logging import json import atexit import re import gevent from Config import config from Debug import Debug from Plugin import PluginManager from util import helper class TrackerList(object): def __init__(self): self.log = logging.getLogger("TrackerList") self.tracker_storage = None self.last_rescan_time = 0.0 self.last_rescan_failed = False def parse_list(self, data): for line in data.splitlines(): line = line.strip() if not line: continue if re.match("^udp://", line): line = re.sub("/announce$", "", line) if self.tracker_storage.onTrackerFound(line): self.log.info("Added tracker: %s" % line) def do_rescan(self): url = config.tracker_list_url response = None self.log.info("Rescanning: %s" % url) try: # FIXME: add support of reading from ZeroNet URLs if re.match("^http(s)?://", url): req = helper.httpRequest(url) response = req.read().decode("utf8") req.close() req = None else: response = open(url, 'r').read().decode("utf8") except Exception as err: self.log.error("Error reading %s: %s" % (url, err)) self.last_rescan_failed = True if response: self.parse_list(response); self.last_rescan_failed = False def reload(self): rescan_interval = config.tracker_list_rescan_interval if self.last_rescan_failed: rescan_interval = rescan_interval / 2 if self.last_rescan_time > time.time() - rescan_interval: return self.last_rescan_time = time.time() if "tracker_storage" not in locals(): try: if "TrackerShare" in PluginManager.plugin_manager.plugin_names: from TrackerShare.TrackerSharePlugin import tracker_storage self.tracker_storage = tracker_storage elif "AnnounceShare" in PluginManager.plugin_manager.plugin_names: from AnnounceShare.AnnounceSharePlugin import tracker_storage self.tracker_storage = tracker_storage except Exception as err: self.log.error("%s" % Debug.formatException(err)) if self.tracker_storage: gevent.spawn(self.do_rescan) if "tracker_list" not in locals(): tracker_list = TrackerList() @PluginManager.registerTo("SiteAnnouncer") class SiteAnnouncerPlugin(object): def announceTracker(self, tracker, *args, **kwargs): tracker_list.reload() return super(SiteAnnouncerPlugin, self).announceTracker(tracker, *args, **kwargs) @PluginManager.registerTo("FileServer") class FileServerPlugin(object): def portCheck(self, *args, **kwargs): res = super(FileServerPlugin, self).portCheck(*args, **kwargs) tracker_list.reload() return res @PluginManager.registerTo("ConfigPlugin") class ConfigPlugin(object): def createArguments(self): group = self.parser.add_argument_group("TrackerList plugin") group.add_argument('--tracker_list_url', help='URL of local file path, where the list of additional trackers is located', default='https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all_ip.txt', metavar='url') group.add_argument('--tracker_list_rescan_interval', help='Interval in seconds between rescans of the list of additional trackers', default=60 * 60, type=int, metavar='interval') return super(ConfigPlugin, self).createArguments()