Rev618, Changed 2 dead torrent trackers, Better exception display on webui, Better broken site with missing files handling, Possible re-check open port using ZeroHello, 5sec udp timeout
This commit is contained in:
parent
3d558a4edf
commit
85c2799cb6
8 changed files with 29 additions and 27 deletions
|
@ -143,6 +143,7 @@ class UiRequestPlugin(object):
|
||||||
connection_id = peer.connection.id
|
connection_id = peer.connection.id
|
||||||
else:
|
else:
|
||||||
connection_id = None
|
connection_id = None
|
||||||
|
if site.content_manager.hashfield:
|
||||||
yield "Optional files: %4s " % len(peer.hashfield)
|
yield "Optional files: %4s " % len(peer.hashfield)
|
||||||
yield "(#%4s, err: %s, found: %5s min ago) %22s -<br>" % (connection_id, peer.connection_error, time_found, key)
|
yield "(#%4s, err: %s, found: %5s min ago) %22s -<br>" % (connection_id, peer.connection_error, time_found, key)
|
||||||
yield "<br></td></tr>"
|
yield "<br></td></tr>"
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Config(object):
|
||||||
|
|
||||||
def __init__(self, argv):
|
def __init__(self, argv):
|
||||||
self.version = "0.3.3"
|
self.version = "0.3.3"
|
||||||
self.rev = 597
|
self.rev = 618
|
||||||
self.argv = argv
|
self.argv = argv
|
||||||
self.action = None
|
self.action = None
|
||||||
self.createParser()
|
self.createParser()
|
||||||
|
@ -30,11 +30,11 @@ class Config(object):
|
||||||
# Create command line arguments
|
# Create command line arguments
|
||||||
def createArguments(self):
|
def createArguments(self):
|
||||||
trackers = [
|
trackers = [
|
||||||
"udp://open.demonii.com:1337",
|
"udp://tracker.coppersurfer.tk:6969",
|
||||||
"udp://tracker.leechers-paradise.org:6969",
|
"udp://tracker.leechers-paradise.org:6969",
|
||||||
"udp://9.rarbg.com:2710",
|
"udp://9.rarbg.com:2710",
|
||||||
"http://tracker.aletorrenty.pl:2710/announce",
|
"http://tracker.aletorrenty.pl:2710/announce",
|
||||||
"http://retracker.telecom.kz/announce",
|
"http://tracker.skyts.net:6969/announce",
|
||||||
"http://torrent.gresille.org/announce"
|
"http://torrent.gresille.org/announce"
|
||||||
]
|
]
|
||||||
# Platform specific
|
# Platform specific
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Notify(Exception):
|
||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
|
|
||||||
def formatException(err=None):
|
def formatException(err=None, format="text"):
|
||||||
if type(err) == Notify:
|
if type(err) == Notify:
|
||||||
return err
|
return err
|
||||||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||||
|
@ -23,6 +23,9 @@ def formatException(err=None):
|
||||||
path, line, function, text = frame
|
path, line, function, text = frame
|
||||||
file = os.path.split(path)[1]
|
file = os.path.split(path)[1]
|
||||||
tb.append("%s line %s" % (file, line))
|
tb.append("%s line %s" % (file, line))
|
||||||
|
if format == "html":
|
||||||
|
return "%s: %s<br><small>%s</small>" % (exc_type.__name__, err, " > ".join(tb))
|
||||||
|
else:
|
||||||
return "%s: %s in %s" % (exc_type.__name__, err, " > ".join(tb))
|
return "%s: %s in %s" % (exc_type.__name__, err, " > ".join(tb))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -182,10 +182,6 @@ class FileServer(ConnectionServer):
|
||||||
else: # If not first run only use PEX
|
else: # If not first run only use PEX
|
||||||
site.announcePex()
|
site.announcePex()
|
||||||
|
|
||||||
# Reset bad file retry counter
|
|
||||||
for inner_path in site.bad_files:
|
|
||||||
site.bad_files[inner_path] = 0
|
|
||||||
|
|
||||||
# Retry failed files
|
# Retry failed files
|
||||||
if site.bad_files:
|
if site.bad_files:
|
||||||
site.retryBadFiles()
|
site.retryBadFiles()
|
||||||
|
|
|
@ -169,8 +169,9 @@ class Site:
|
||||||
return [bad_file for bad_file, retry in self.bad_files.iteritems() if retry < 3]
|
return [bad_file for bad_file, retry in self.bad_files.iteritems() if retry < 3]
|
||||||
|
|
||||||
# Retry download bad files
|
# Retry download bad files
|
||||||
def retryBadFiles(self):
|
def retryBadFiles(self, force=False):
|
||||||
for bad_file in self.bad_files.keys():
|
for bad_file, tries in self.bad_files.iteritems():
|
||||||
|
if force or random.randint(0, min(20, tries)) == 0: # Larger number tries = less likely to check every 15min
|
||||||
self.needFile(bad_file, update=True, blocking=False)
|
self.needFile(bad_file, update=True, blocking=False)
|
||||||
|
|
||||||
# Download all files of the site
|
# Download all files of the site
|
||||||
|
@ -189,7 +190,7 @@ class Site:
|
||||||
# Download everything
|
# Download everything
|
||||||
valid = self.downloadContent("content.json", check_modifications=blind_includes)
|
valid = self.downloadContent("content.json", check_modifications=blind_includes)
|
||||||
|
|
||||||
self.retryBadFiles()
|
self.retryBadFiles(force=True)
|
||||||
|
|
||||||
return valid
|
return valid
|
||||||
|
|
||||||
|
@ -276,6 +277,7 @@ class Site:
|
||||||
changed, deleted = self.content_manager.loadContent("content.json")
|
changed, deleted = self.content_manager.loadContent("content.json")
|
||||||
|
|
||||||
if self.bad_files:
|
if self.bad_files:
|
||||||
|
self.log.debug("Bad files: %s" % self.bad_files)
|
||||||
self.download()
|
self.download()
|
||||||
|
|
||||||
self.settings["size"] = self.content_manager.getTotalSize() # Update site size
|
self.settings["size"] = self.content_manager.getTotalSize() # Update site size
|
||||||
|
@ -485,14 +487,8 @@ class Site:
|
||||||
self.log.debug("No info for %s, waiting for all content.json" % inner_path)
|
self.log.debug("No info for %s, waiting for all content.json" % inner_path)
|
||||||
success = self.downloadContent("content.json", download_files=False)
|
success = self.downloadContent("content.json", download_files=False)
|
||||||
if not success:
|
if not success:
|
||||||
if self.bad_files.get(inner_path, 0) > 10:
|
|
||||||
del self.bad_files[inner_path]
|
|
||||||
self.log.debug("Max retry reached, giving up on %s" % inner_path)
|
|
||||||
return False
|
return False
|
||||||
if not self.content_manager.getFileInfo(inner_path):
|
if not self.content_manager.getFileInfo(inner_path):
|
||||||
if self.bad_files.get(inner_path, 0) > 10:
|
|
||||||
del self.bad_files[inner_path]
|
|
||||||
self.log.debug("Max retry reached, giving up on %s" % inner_path)
|
|
||||||
return False # Still no info for file
|
return False # Still no info for file
|
||||||
|
|
||||||
task = self.worker_manager.addTask(inner_path, peer, priority=priority)
|
task = self.worker_manager.addTask(inner_path, peer, priority=priority)
|
||||||
|
@ -680,6 +676,7 @@ class Site:
|
||||||
(fileserver_port, announced, time.time() - s, errors, slow)
|
(fileserver_port, announced, time.time() - s, errors, slow)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
if num > 1:
|
||||||
self.log.error("Announce to %s trackers in %.3fs, failed" % (announced, time.time() - s))
|
self.log.error("Announce to %s trackers in %.3fs, failed" % (announced, time.time() - s))
|
||||||
|
|
||||||
if pex:
|
if pex:
|
||||||
|
@ -778,7 +775,7 @@ class Site:
|
||||||
# Update hashfield
|
# Update hashfield
|
||||||
def updateHashfield(self, limit=3):
|
def updateHashfield(self, limit=3):
|
||||||
# Return if no optional files
|
# Return if no optional files
|
||||||
if not self.content_manager.hashfield and not self.content_manager.contents.get("content.json", {}).get("files_optional", {}):
|
if not self.content_manager.hashfield and not self.content_manager.contents.get("content.json", {}).get("files_optional"):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
queried = 0
|
queried = 0
|
||||||
|
|
|
@ -66,8 +66,8 @@ class UiWebsocket(object):
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
if config.debug: # Allow websocket errors to appear on /Debug
|
if config.debug: # Allow websocket errors to appear on /Debug
|
||||||
sys.modules["main"].DebugHook.handleError()
|
sys.modules["main"].DebugHook.handleError()
|
||||||
self.log.error("WebSocket handleRequest error: %s" % err)
|
self.log.error("WebSocket handleRequest error: %s" % Debug.formatException(err))
|
||||||
self.cmd("error", "Internal error: %s" % err)
|
self.cmd("error", "Internal error: %s" % Debug.formatException(err, "html"))
|
||||||
|
|
||||||
# Event in a channel
|
# Event in a channel
|
||||||
def event(self, channel, *params):
|
def event(self, channel, *params):
|
||||||
|
@ -122,7 +122,7 @@ class UiWebsocket(object):
|
||||||
|
|
||||||
admin_commands = (
|
admin_commands = (
|
||||||
"sitePause", "siteResume", "siteDelete", "siteList", "siteSetLimit", "siteClone",
|
"sitePause", "siteResume", "siteDelete", "siteList", "siteSetLimit", "siteClone",
|
||||||
"channelJoinAllsite", "serverUpdate", "certSet"
|
"channelJoinAllsite", "serverUpdate", "serverPortcheck", "certSet"
|
||||||
)
|
)
|
||||||
|
|
||||||
if cmd == "response": # It's a response to a command
|
if cmd == "response": # It's a response to a command
|
||||||
|
@ -563,3 +563,8 @@ class UiWebsocket(object):
|
||||||
sys.modules["main"].update_after_shutdown = True
|
sys.modules["main"].update_after_shutdown = True
|
||||||
sys.modules["main"].file_server.stop()
|
sys.modules["main"].file_server.stop()
|
||||||
sys.modules["main"].ui_server.stop()
|
sys.modules["main"].ui_server.stop()
|
||||||
|
|
||||||
|
def actionServerPortcheck(self, to):
|
||||||
|
sys.modules["main"].file_server.port_opened = None
|
||||||
|
res = sys.modules["main"].file_server.openport()
|
||||||
|
self.response(to, res)
|
||||||
|
|
|
@ -7,9 +7,9 @@ from Plugin import PluginManager
|
||||||
from Config import config
|
from Config import config
|
||||||
from util import helper
|
from util import helper
|
||||||
|
|
||||||
|
|
||||||
@PluginManager.acceptPlugins
|
@PluginManager.acceptPlugins
|
||||||
class User(object):
|
class User(object):
|
||||||
|
|
||||||
def __init__(self, master_address=None, master_seed=None, data={}):
|
def __init__(self, master_address=None, master_seed=None, data={}):
|
||||||
if master_seed:
|
if master_seed:
|
||||||
self.master_seed = master_seed
|
self.master_seed = master_seed
|
||||||
|
|
|
@ -43,7 +43,7 @@ class UdpTrackerClient:
|
||||||
self.conn_id = 0x41727101980
|
self.conn_id = 0x41727101980
|
||||||
self.transactions = {}
|
self.transactions = {}
|
||||||
self.peer_id = self._generate_peer_id()
|
self.peer_id = self._generate_peer_id()
|
||||||
self.timeout = 2
|
self.timeout = 5
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
return self._send(CONNECT)
|
return self._send(CONNECT)
|
||||||
|
|
Loading…
Reference in a new issue