From bd7e76628b2a6f2e399aeb0b6c4e229d24987b35 Mon Sep 17 00:00:00 2001
From: HelloZeroNet <hello@noloop.me>
Date: Thu, 26 Feb 2015 01:32:27 +0100
Subject: [PATCH] version 0.2.5, download and update progress bar, we are on
 gitter, log on filerequest error, faster update

---
 README.md                    |  2 +-
 src/Config.py                |  2 +-
 src/File/FileRequest.py      |  1 +
 src/Site/Site.py             | 13 +++++++------
 src/Ui/UiWebsocket.py        |  3 ++-
 src/Ui/media/Loading.coffee  |  9 +++++++++
 src/Ui/media/Wrapper.coffee  |  5 +++++
 src/Ui/media/Wrapper.css     |  7 +++++++
 src/Ui/media/all.css         |  7 +++++++
 src/Ui/media/all.js          | 15 +++++++++++++++
 src/Ui/template/wrapper.html |  4 ++++
 src/Worker/WorkerManager.py  |  4 +++-
 12 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index b0179849..680e6d31 100644
--- a/README.md
+++ b/README.md
@@ -124,4 +124,4 @@ Bitcoin: 1QDhxQ6PraUZa21ET5fYUCPgdrwBomnFgX
 #### Thank you!
 
 * More info, help, changelog, zeronet sites: http://www.reddit.com/r/zeronet/
-* Come, chat with us: [#zeronet @ FreeNode](https://kiwiirc.com/client/irc.freenode.net/zeronet) 
+* Come, chat with us: [#zeronet @ FreeNode](https://kiwiirc.com/client/irc.freenode.net/zeronet) or on [gitter](https://gitter.im/HelloZeroNet/ZeroNet)
diff --git a/src/Config.py b/src/Config.py
index e495b12e..605d0e07 100644
--- a/src/Config.py
+++ b/src/Config.py
@@ -3,7 +3,7 @@ import ConfigParser
 
 class Config(object):
 	def __init__(self):
-		self.version = "0.2.4"
+		self.version = "0.2.5"
 		self.parser = self.createArguments()
 		argv = sys.argv[:] # Copy command line arguments
 		argv = self.parseConfig(argv) # Add arguments from config file
diff --git a/src/File/FileRequest.py b/src/File/FileRequest.py
index 682b9911..1a4894b8 100644
--- a/src/File/FileRequest.py
+++ b/src/File/FileRequest.py
@@ -104,6 +104,7 @@ class FileRequest:
 			self.response(back)
 			if config.debug_socket: self.log.debug("File %s sent" % file_path)
 		except Exception, err:
+			self.log.debug("GetFile read error: %s" % Debug.formatException(err))
 			self.response({"error": "File read error: %s" % Debug.formatException(err)})
 			return False
 
diff --git a/src/Site/Site.py b/src/Site/Site.py
index 201955c1..03e772a5 100644
--- a/src/Site/Site.py
+++ b/src/Site/Site.py
@@ -29,7 +29,6 @@ class Site:
 		self.worker_manager = WorkerManager(self) # Handle site download from other peers
 		self.bad_files = {} # SHA512 check failed files, need to redownload {"inner.content": 1} (key: file, value: failed accept)
 		self.content_updated = None # Content.js update time
-		self.last_downloads = [] # Files downloaded in run of self.download()
 		self.notifications = [] # Pending notifications displayed once on page load [error|ok|info, message, timeout]
 		self.page_requested = False # Page viewed in browser
 
@@ -106,7 +105,6 @@ class Site:
 	def downloadContent(self, inner_path, download_files=True, peer=None):
 		s = time.time()
 		self.log.debug("Downloading %s..." % inner_path)
-		self.last_downloads.append(inner_path)
 		found = self.needFile(inner_path, update=self.bad_files.get(inner_path))
 		content_inner_dir = self.content_manager.toDir(inner_path)
 		if not found: return False # Could not download content.json
@@ -121,7 +119,6 @@ class Site:
 				file_inner_path = content_inner_dir+file_relative_path
 				res = self.needFile(file_inner_path, blocking=False, update=self.bad_files.get(file_inner_path), peer=peer) # No waiting for finish, return the event
 				if res != True: # Need downloading
-					self.last_downloads.append(file_inner_path)
 					file_threads.append(res) # Append evt
 
 		# Wait for includes download
@@ -135,7 +132,7 @@ class Site:
 		gevent.joinall(include_threads)
 		self.log.debug("%s: Includes downloaded" % inner_path)
 		
-		self.log.debug("%s: Downloading %s files..." % (inner_path, len(file_threads)))
+		self.log.debug("%s: Downloading %s files, changed: %s..." % (inner_path, len(file_threads), len(changed)))
 		gevent.joinall(file_threads)
 		self.log.debug("%s: All file downloaded in %.2fs" % (inner_path, time.time()-s))
 
@@ -153,7 +150,6 @@ class Site:
 	def download(self, check_size=False):
 		self.log.debug("Start downloading...%s" % self.bad_files)
 		self.announce()
-		self.last_downloads = []
 		if check_size: # Check the size first
 			valid = downloadContent(download_files=False)
 			if not valid: return False # Cant download content.jsons or size is not fits
@@ -169,8 +165,13 @@ class Site:
 		self.content_manager.loadContent("content.json") # Reload content.json
 		self.content_updated = None
 		# Download all content.json again
+		content_threads = []
 		for inner_path in self.content_manager.contents.keys():
-			self.needFile(inner_path, update=True)
+			content_threads.append(self.needFile(inner_path, update=True, blocking=False))
+
+		self.log.debug("Waiting %s content.json to finish..." % len(content_threads))
+		gevent.joinall(content_threads)
+
 		changed = self.content_manager.loadContent("content.json")
 		if changed:
 			for changed_file in changed:
diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py
index 629a41e8..10234770 100644
--- a/src/Ui/UiWebsocket.py
+++ b/src/Ui/UiWebsocket.py
@@ -183,9 +183,10 @@ class UiWebsocket:
 			"bad_files": len(site.bad_files),
 			"size_limit": site.getSizeLimit(),
 			"next_size_limit": site.getNextSizeLimit(),
-			"last_downloads": len(site.last_downloads),
 			"peers": site.settings.get("peers", len(site.peers)),
+			"started_task_num": site.worker_manager.started_task_num,
 			"tasks": len(site.worker_manager.tasks),
+			"workers": len(site.worker_manager.workers),
 			"content": content
 		}
 		if site.settings["serving"] and content: ret["peers"] += 1 # Add myself if serving
diff --git a/src/Ui/media/Loading.coffee b/src/Ui/media/Loading.coffee
index 2da7a39f..8a0bf7cd 100644
--- a/src/Ui/media/Loading.coffee
+++ b/src/Ui/media/Loading.coffee
@@ -3,6 +3,15 @@ class Loading
 		if window.show_loadingscreen then @showScreen()
 
 
+	setProgress: (percent) ->
+		console.log "Progress:", percent
+		$(".progressbar").css("width", percent*100+"%").css("opacity", "1").css("display", "block")
+
+	hideProgress: ->
+		$(".progressbar").css("width", "100%").css("opacity", "0").cssLater("display", "none", 1000)
+		console.log "Hideprogress"
+
+
 	showScreen: ->
 		$(".loadingscreen").css("display", "block").addClassLater("ready")
 		@screen_visible = true
diff --git a/src/Ui/media/Wrapper.coffee b/src/Ui/media/Wrapper.coffee
index 909b7539..f825c49d 100644
--- a/src/Ui/media/Wrapper.coffee
+++ b/src/Ui/media/Wrapper.coffee
@@ -253,6 +253,11 @@ class Wrapper
 		if @loading.screen_visible and @inner_loaded and site_info.settings.size < site_info.size_limit*1024*1024 # Loading screen still visible, but inner loaded
 			@loading.hideScreen()
 
+		if site_info.tasks > 0 and site_info.started_task_num > 0
+			@loading.setProgress 1-(site_info.tasks / site_info.started_task_num)
+		else
+			@loading.hideProgress()
+
 		@site_info = site_info
 
 
diff --git a/src/Ui/media/Wrapper.css b/src/Ui/media/Wrapper.css
index f6e0bf99..283b0d9b 100644
--- a/src/Ui/media/Wrapper.css
+++ b/src/Ui/media/Wrapper.css
@@ -100,6 +100,13 @@ a { color: black }
 .loadingscreen.done .console { transform: translateY(300px); opacity: 0; transition: all 1.5s }
 .loadingscreen.done .flipper-container { opacity: 0; transition: all 1.5s }
 
+
+.progressbar { background: #26C281; position: fixed; z-index: 100; top: 0; left: 0; width: 0%; height: 2px; transition: width 0.5s, opacity 1s; display: none }
+.progressbar .peg { 
+	display: block; position: absolute; right: 0px; width: 100px; height: 100%;
+	box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; opacity: 1.0; transform: rotate(3deg) translate(0px, -4px);
+}
+
 /* Animations */
 
 @keyframes flip {
diff --git a/src/Ui/media/all.css b/src/Ui/media/all.css
index 72f174e4..d5c48986 100644
--- a/src/Ui/media/all.css
+++ b/src/Ui/media/all.css
@@ -105,6 +105,13 @@ a { color: black }
 .loadingscreen.done .console { -webkit-transform: translateY(300px); -moz-transform: translateY(300px); -o-transform: translateY(300px); -ms-transform: translateY(300px); transform: translateY(300px) ; opacity: 0; -webkit-transition: all 1.5s ; -moz-transition: all 1.5s ; -o-transition: all 1.5s ; -ms-transition: all 1.5s ; transition: all 1.5s  }
 .loadingscreen.done .flipper-container { opacity: 0; -webkit-transition: all 1.5s ; -moz-transition: all 1.5s ; -o-transition: all 1.5s ; -ms-transition: all 1.5s ; transition: all 1.5s  }
 
+
+.progressbar { background: #26C281; position: fixed; z-index: 100; top: 0; left: 0; width: 0%; height: 2px; -webkit-transition: width 0.5s, opacity 1s; -moz-transition: width 0.5s, opacity 1s; -o-transition: width 0.5s, opacity 1s; -ms-transition: width 0.5s, opacity 1s; transition: width 0.5s, opacity 1s ; display: none }
+.progressbar .peg { 
+	display: block; position: absolute; right: 0px; width: 100px; height: 100%;
+	-webkit-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -moz-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -o-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -ms-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d ; opacity: 1.0; -webkit-transform: rotate(3deg) translate(0px, -4px); -moz-transform: rotate(3deg) translate(0px, -4px); -o-transform: rotate(3deg) translate(0px, -4px); -ms-transform: rotate(3deg) translate(0px, -4px); transform: rotate(3deg) translate(0px, -4px) ;
+}
+
 /* Animations */
 
 @keyframes flip {
diff --git a/src/Ui/media/all.js b/src/Ui/media/all.js
index 11807a5c..63637942 100644
--- a/src/Ui/media/all.js
+++ b/src/Ui/media/all.js
@@ -471,6 +471,16 @@ jQuery.extend( jQuery.easing,
       }
     }
 
+    Loading.prototype.setProgress = function(percent) {
+      console.log("Progress:", percent);
+      return $(".progressbar").css("width", percent * 100 + "%").css("opacity", "1").css("display", "block");
+    };
+
+    Loading.prototype.hideProgress = function() {
+      $(".progressbar").css("width", "100%").css("opacity", "0").cssLater("display", "none", 1000);
+      return console.log("Hideprogress");
+    };
+
     Loading.prototype.showScreen = function() {
       $(".loadingscreen").css("display", "block").addClassLater("ready");
       this.screen_visible = true;
@@ -1060,6 +1070,11 @@ jQuery.extend( jQuery.easing,
       if (this.loading.screen_visible && this.inner_loaded && site_info.settings.size < site_info.size_limit * 1024 * 1024) {
         this.loading.hideScreen();
       }
+      if (site_info.tasks > 0 && site_info.started_task_num > 0) {
+        this.loading.setProgress(1 - (site_info.tasks / site_info.started_task_num));
+      } else {
+        this.loading.hideProgress();
+      }
       return this.site_info = site_info;
     };
 
diff --git a/src/Ui/template/wrapper.html b/src/Ui/template/wrapper.html
index 95b9a525..9faf65a2 100644
--- a/src/Ui/template/wrapper.html
+++ b/src/Ui/template/wrapper.html
@@ -11,6 +11,10 @@
 </head>
 <body style="{body_style}">
 
+<div class="progressbar">
+ <div class="peg"></div>
+</div>
+
 <!-- Fixed button -->
 <div class='fixbutton'>
  <div class='fixbutton-text'>0</div>
diff --git a/src/Worker/WorkerManager.py b/src/Worker/WorkerManager.py
index 02e1c1d4..12543d19 100644
--- a/src/Worker/WorkerManager.py
+++ b/src/Worker/WorkerManager.py
@@ -9,6 +9,7 @@ class WorkerManager:
 		self.site = site
 		self.workers = {} # Key: ip:port, Value: Worker.Worker
 		self.tasks = [] # {"evt": evt, "workers_num": 0, "site": self.site, "inner_path": inner_path, "done": False, "time_started": None, "time_added": time.time(), "peers": peers, "priority": 0}
+		self.started_task_num = 0 # Last added task num
 		self.running = True
 		self.log = logging.getLogger("WorkerManager:%s" % self.site.address_short)
 		self.process_taskchecker = gevent.spawn(self.checkTasks)
@@ -142,7 +143,8 @@ class WorkerManager:
 				peers = None
 			task = {"evt": evt, "workers_num": 0, "site": self.site, "inner_path": inner_path, "done": False, "time_added": time.time(), "time_started": None, "peers": peers, "priority": priority, "failed": []}
 			self.tasks.append(task)
-			self.log.debug("New task: %s, peer lock: %s, priority: %s" % (task["inner_path"], peers, priority))
+			self.started_task_num = len(self.tasks)
+			self.log.debug("New task: %s, peer lock: %s, priority: %s, tasks: %s" % (task["inner_path"], peers, priority, self.started_task_num))
 			self.startWorkers(peers)
 			return evt