diff --git a/plugins/Stats/StatsPlugin.py b/plugins/Stats/StatsPlugin.py
index 2961490d..cef76c70 100644
--- a/plugins/Stats/StatsPlugin.py
+++ b/plugins/Stats/StatsPlugin.py
@@ -143,7 +143,8 @@ class UiRequestPlugin(object):
connection_id = peer.connection.id
else:
connection_id = None
- yield "Optional files: %4s " % len(peer.hashfield)
+ if site.content_manager.hashfield:
+ yield "Optional files: %4s " % len(peer.hashfield)
yield "(#%4s, err: %s, found: %5s min ago) %22s -
" % (connection_id, peer.connection_error, time_found, key)
yield "
"
yield ""
diff --git a/src/Config.py b/src/Config.py
index 503108db..4cd80350 100644
--- a/src/Config.py
+++ b/src/Config.py
@@ -8,7 +8,7 @@ class Config(object):
def __init__(self, argv):
self.version = "0.3.3"
- self.rev = 597
+ self.rev = 618
self.argv = argv
self.action = None
self.createParser()
@@ -30,11 +30,11 @@ class Config(object):
# Create command line arguments
def createArguments(self):
trackers = [
- "udp://open.demonii.com:1337",
+ "udp://tracker.coppersurfer.tk:6969",
"udp://tracker.leechers-paradise.org:6969",
"udp://9.rarbg.com:2710",
"http://tracker.aletorrenty.pl:2710/announce",
- "http://retracker.telecom.kz/announce",
+ "http://tracker.skyts.net:6969/announce",
"http://torrent.gresille.org/announce"
]
# Platform specific
diff --git a/src/Debug/Debug.py b/src/Debug/Debug.py
index 3622554c..f3b54fd7 100644
--- a/src/Debug/Debug.py
+++ b/src/Debug/Debug.py
@@ -12,7 +12,7 @@ class Notify(Exception):
return self.message
-def formatException(err=None):
+def formatException(err=None, format="text"):
if type(err) == Notify:
return err
exc_type, exc_obj, exc_tb = sys.exc_info()
@@ -23,7 +23,10 @@ def formatException(err=None):
path, line, function, text = frame
file = os.path.split(path)[1]
tb.append("%s line %s" % (file, line))
- return "%s: %s in %s" % (exc_type.__name__, err, " > ".join(tb))
+ if format == "html":
+ return "%s: %s
%s" % (exc_type.__name__, err, " > ".join(tb))
+ else:
+ return "%s: %s in %s" % (exc_type.__name__, err, " > ".join(tb))
if __name__ == "__main__":
diff --git a/src/File/FileServer.py b/src/File/FileServer.py
index 7e97b4e8..27e681a1 100644
--- a/src/File/FileServer.py
+++ b/src/File/FileServer.py
@@ -182,10 +182,6 @@ class FileServer(ConnectionServer):
else: # If not first run only use PEX
site.announcePex()
- # Reset bad file retry counter
- for inner_path in site.bad_files:
- site.bad_files[inner_path] = 0
-
# Retry failed files
if site.bad_files:
site.retryBadFiles()
diff --git a/src/Site/Site.py b/src/Site/Site.py
index 9b79d68b..4bf5ff3c 100644
--- a/src/Site/Site.py
+++ b/src/Site/Site.py
@@ -169,9 +169,10 @@ class Site:
return [bad_file for bad_file, retry in self.bad_files.iteritems() if retry < 3]
# Retry download bad files
- def retryBadFiles(self):
- for bad_file in self.bad_files.keys():
- self.needFile(bad_file, update=True, blocking=False)
+ def retryBadFiles(self, force=False):
+ 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)
# Download all files of the site
@util.Noparallel(blocking=False)
@@ -189,7 +190,7 @@ class Site:
# Download everything
valid = self.downloadContent("content.json", check_modifications=blind_includes)
- self.retryBadFiles()
+ self.retryBadFiles(force=True)
return valid
@@ -276,6 +277,7 @@ class Site:
changed, deleted = self.content_manager.loadContent("content.json")
if self.bad_files:
+ self.log.debug("Bad files: %s" % self.bad_files)
self.download()
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)
success = self.downloadContent("content.json", download_files=False)
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
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
task = self.worker_manager.addTask(inner_path, peer, priority=priority)
@@ -680,7 +676,8 @@ class Site:
(fileserver_port, announced, time.time() - s, errors, slow)
)
else:
- self.log.error("Announce to %s trackers in %.3fs, failed" % (announced, time.time() - s))
+ if num > 1:
+ self.log.error("Announce to %s trackers in %.3fs, failed" % (announced, time.time() - s))
if pex:
if not [peer for peer in self.peers.values() if peer.connection and peer.connection.connected]:
@@ -778,7 +775,7 @@ class Site:
# Update hashfield
def updateHashfield(self, limit=3):
# 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
queried = 0
diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py
index 523d762b..b834dcd9 100644
--- a/src/Ui/UiWebsocket.py
+++ b/src/Ui/UiWebsocket.py
@@ -66,8 +66,8 @@ class UiWebsocket(object):
except Exception, err:
if config.debug: # Allow websocket errors to appear on /Debug
sys.modules["main"].DebugHook.handleError()
- self.log.error("WebSocket handleRequest error: %s" % err)
- self.cmd("error", "Internal error: %s" % err)
+ self.log.error("WebSocket handleRequest error: %s" % Debug.formatException(err))
+ self.cmd("error", "Internal error: %s" % Debug.formatException(err, "html"))
# Event in a channel
def event(self, channel, *params):
@@ -122,7 +122,7 @@ class UiWebsocket(object):
admin_commands = (
"sitePause", "siteResume", "siteDelete", "siteList", "siteSetLimit", "siteClone",
- "channelJoinAllsite", "serverUpdate", "certSet"
+ "channelJoinAllsite", "serverUpdate", "serverPortcheck", "certSet"
)
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"].file_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)
diff --git a/src/User/User.py b/src/User/User.py
index 1822345e..95c0661d 100644
--- a/src/User/User.py
+++ b/src/User/User.py
@@ -7,9 +7,9 @@ from Plugin import PluginManager
from Config import config
from util import helper
+
@PluginManager.acceptPlugins
class User(object):
-
def __init__(self, master_address=None, master_seed=None, data={}):
if master_seed:
self.master_seed = master_seed
diff --git a/src/lib/subtl/subtl.py b/src/lib/subtl/subtl.py
index 3f8c47aa..a2eb966d 100644
--- a/src/lib/subtl/subtl.py
+++ b/src/lib/subtl/subtl.py
@@ -43,7 +43,7 @@ class UdpTrackerClient:
self.conn_id = 0x41727101980
self.transactions = {}
self.peer_id = self._generate_peer_id()
- self.timeout = 2
+ self.timeout = 5
def connect(self):
return self._send(CONNECT)