瀏覽代碼

Rev448, Better file download priority method, Some potential programming error fix, Renamed utils to helper, Moved pack and unpackaddress to helper package, Test new privatekey creation, Test site file download order, Spy test helper to log called parameters, Remove unnecessary fat arrows

HelloZeroNet 8 年之前
父節點
當前提交
4b403da056

+ 4 - 4
src/Config.py

@@ -8,7 +8,7 @@ class Config(object):
 
     def __init__(self, argv):
         self.version = "0.3.2"
-        self.rev = 445
+        self.rev = 448
         self.argv = argv
         self.action = None
         self.createParser()
@@ -203,12 +203,12 @@ class Config(object):
             original_print_message = self.parser._print_message
             original_exit = self.parser.exit
 
-            def silent(parser, function_name):
+            def silencer(parser, function_name):
                 parser.exited = True
                 return None
             self.parser.exited = False
-            self.parser._print_message = lambda *args, **kwargs: silent(self.parser, "_print_message")
-            self.parser.exit = lambda *args, **kwargs: silent(self.parser, "exit")
+            self.parser._print_message = lambda *args, **kwargs: silencer(self.parser, "_print_message")
+            self.parser.exit = lambda *args, **kwargs: silencer(self.parser, "exit")
 
         argv = self.argv[:]  # Copy command line arguments
         if parse_config:

+ 32 - 35
src/Content/ContentManager.py

@@ -528,49 +528,46 @@ class ContentManager(object):
         return file_dir
 
 
-def testSign():
-    global config
-    from Site import Site
-    site = Site("12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH")
-    content_manager = ContentManager(site)
-    content_manager.sign(
-        "data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json", "5JCGE6UUruhfmAfcZ2GYjvrswkaiq7uLo6Gmtf2ep2Jh2jtNzWR"
-    )
-
-
-def testVerify():
-    from Site import Site
-    site = Site("12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH")
-
-    content_manager = ContentManager(site)
-    print "Loaded contents:", content_manager.contents.keys()
+if __name__ == "__main__":
+    def testSign():
+        global config
+        from Site import Site
+        site = Site("12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH")
+        content_manager = ContentManager(site)
+        content_manager.sign(
+            "data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json", "5JCGE6UUruhfmAfcZ2GYjvrswkaiq7uLo6Gmtf2ep2Jh2jtNzWR"
+        )
 
-    file = open(site.storage.getPath("data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json"))
-    print "content.json valid:", content_manager.verifyFile(
-        "data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json", file, ignore_same=False
-    )
+    def testVerify():
+        from Site import Site
+        site = Site("12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH")
 
-    file = open(site.storage.getPath("data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/messages.json"))
-    print "messages.json valid:", content_manager.verifyFile(
-        "data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/messages.json", file, ignore_same=False
-    )
+        content_manager = ContentManager(site)
+        print "Loaded contents:", content_manager.contents.keys()
 
+        file = open(site.storage.getPath("data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json"))
+        print "content.json valid:", content_manager.verifyFile(
+            "data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json", file, ignore_same=False
+        )
 
-def testInfo():
-    from Site import Site
-    site = Site("12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH")
+        file = open(site.storage.getPath("data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/messages.json"))
+        print "messages.json valid:", content_manager.verifyFile(
+            "data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/messages.json", file, ignore_same=False
+        )
 
-    content_manager = ContentManager(site)
-    print content_manager.contents.keys()
+    def testInfo():
+        from Site import Site
+        site = Site("12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH")
 
-    print content_manager.getFileInfo("index.html")
-    print content_manager.getIncludeInfo("data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json")
-    print content_manager.getValidSigners("data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json")
-    print content_manager.getValidSigners("data/users/content.json")
-    print content_manager.getValidSigners("content.json")
+        content_manager = ContentManager(site)
+        print content_manager.contents.keys()
 
+        print content_manager.getFileInfo("index.html")
+        print content_manager.getIncludeInfo("data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json")
+        print content_manager.getValidSigners("data/users/1KRxE1s3oDyNDawuYWpzbLUwNm8oDbeEp6/content.json")
+        print content_manager.getValidSigners("data/users/content.json")
+        print content_manager.getValidSigners("content.json")
 
-if __name__ == "__main__":
     import sys
     import logging
     os.chdir("../..")

+ 4 - 4
src/Crypt/CryptConnection.py

@@ -5,7 +5,7 @@ import ssl
 
 from Config import config
 from util import SslPatch
-from util import utils
+from util import helper
 
 
 class CryptConnectionManager:
@@ -65,7 +65,7 @@ class CryptConnectionManager:
             return True  # Files already exits
 
         proc = subprocess.Popen(
-            "%s req -x509 -newkey rsa:2048 -sha256 -batch -keyout %s -out %s -nodes -config %s" % utils.shellquote(
+            "%s req -x509 -newkey rsa:2048 -sha256 -batch -keyout %s -out %s -nodes -config %s" % helper.shellquote(
                 self.openssl_bin,
                 config.data_dir+"/key-rsa.pem",
                 config.data_dir+"/cert-rsa.pem",
@@ -99,7 +99,7 @@ class CryptConnectionManager:
 
         # Create ECC cert
         proc = subprocess.Popen(
-            "%s req -new -key %s -x509 -nodes -out %s -config %s" % utils.shellquote(
+            "%s req -new -key %s -x509 -nodes -out %s -config %s" % helper.shellquote(
                 self.openssl_bin,
                 config.data_dir+"/key-ecc.pem",
                 config.data_dir+"/cert-ecc.pem",
@@ -118,4 +118,4 @@ class CryptConnectionManager:
             return False
     """
 
-manager = CryptConnectionManager()
+manager = CryptConnectionManager()

+ 3 - 3
src/Debug/DebugMedia.py

@@ -5,7 +5,7 @@ import logging
 import time
 
 from Config import config
-from util import utils
+from util import helper
 
 
 # Find files with extension in path
@@ -23,7 +23,7 @@ def findCoffeescriptCompiler():
     coffeescript_compiler = None
     try:
         import distutils.spawn
-        coffeescript_compiler = utils.shellquote(distutils.spawn.find_executable("coffee")) + " --no-header -p"
+        coffeescript_compiler = helper.shellquote(distutils.spawn.find_executable("coffee")) + " --no-header -p"
     except:
         pass
     if coffeescript_compiler:
@@ -75,7 +75,7 @@ def merge(merged_path):
                     return False  # No coffeescript compiler, skip this file
 
                 # Replace / with os separators and escape it
-                file_path_escaped = utils.shellquote(os.path.join(*file_path.split("/")))
+                file_path_escaped = helper.shellquote(os.path.join(*file_path.split("/")))
 
                 if "%s" in config.coffeescript_compiler:  # Replace %s with coffeescript file
                     command = config.coffeescript_compiler % file_path_escaped

+ 5 - 6
src/File/FileRequest.py

@@ -9,7 +9,9 @@ import gevent
 
 from Debug import Debug
 from Config import config
-from util import RateLimit, StreamingMsgpack
+from util import RateLimit
+from util import StreamingMsgpack
+from util import helper
 
 FILE_BUFF = 1024 * 512
 
@@ -27,9 +29,6 @@ class FileRequest(object):
         self.log = server.log
         self.responded = False  # Responded to the request
 
-    def unpackAddress(self, packed):
-        return socket.inet_ntoa(packed[0:4]), struct.unpack_from("H", packed, 4)[0]
-
     def send(self, msg, streaming=False):
         if not self.connection.closed:
             self.connection.send(msg, streaming)
@@ -221,8 +220,8 @@ class FileRequest(object):
             added += 1
             connected_peer.connect(self.connection)  # Assign current connection to peer
 
-        for peer in params["peers"]:  # Add sent peers to site
-            address = self.unpackAddress(peer)
+        for addr_packed in params["peers"]:  # Add sent peers to site
+            address = helper.unpackAddress(addr_packed)
             got_peer_keys.append("%s:%s" % address)
             if site.addPeer(*address):
                 added += 1

+ 6 - 11
src/Peer/Peer.py

@@ -1,17 +1,16 @@
 import logging
 import gevent
 import time
-import sys
-import socket
-import struct
 
 from cStringIO import StringIO
 from Debug import Debug
 from Config import config
+from util import helper
 
 if config.use_tempfiles:
     import tempfile
 
+
 # Communicate remote peers
 class Peer(object):
     __slots__ = (
@@ -77,12 +76,8 @@ class Peer(object):
     def __repr__(self):
         return "<%s>" % self.__str__()
 
-    # Peer ip:port to packed 6byte format
-    def packAddress(self):
-        return socket.inet_aton(self.ip) + struct.pack("H", self.port)
-
-    def unpackAddress(self, packed):
-        return socket.inet_ntoa(packed[0:4]), struct.unpack_from("H", packed, 4)[0]
+    def packMyAddress(self):
+        return helper.packAddress(self.ip, self.port)
 
     # Found a peer on tracker
     def found(self):
@@ -209,13 +204,13 @@ class Peer(object):
         if not site:
             site = self.site  # If no site defined request peers for this site
         # give him/her 5 connectible peers
-        packed_peers = [peer.packAddress() for peer in self.site.getConnectablePeers(5)]
+        packed_peers = [peer.packMyAddress() for peer in self.site.getConnectablePeers(5)]
         response = self.request("pex", {"site": site.address, "peers": packed_peers, "need": need_num})
         if not response or "error" in response:
             return False
         added = 0
         for peer in response.get("peers", []):
-            address = self.unpackAddress(peer)
+            address = helper.unpackAddress(peer)
             if site.addPeer(*address):
                 added += 1
         if added:

+ 3 - 3
src/Site/Site.py

@@ -24,7 +24,7 @@ from Debug import Debug
 from Content import ContentManager
 from SiteStorage import SiteStorage
 from Crypt import CryptHash
-from util import utils
+from util import helper
 import SiteManager
 
 
@@ -92,7 +92,7 @@ class Site:
     def saveSettings(self):
         sites_settings = json.load(open("%s/sites.json" % config.data_dir))
         sites_settings[self.address] = self.settings
-        utils.atomicWrite("%s/sites.json" % config.data_dir, json.dumps(sites_settings, indent=2, sort_keys=True))
+        helper.atomicWrite("%s/sites.json" % config.data_dir, json.dumps(sites_settings, indent=2, sort_keys=True))
 
     # Max site size in MB
     def getSizeLimit(self):
@@ -172,7 +172,7 @@ class Site:
         )
         gevent.spawn(self.announce)
         if check_size:  # Check the size first
-            valid = self.downloadContent(download_files=False)  # Just download content.json files
+            valid = self.downloadContent("content.json", download_files=False)  # Just download content.json files
             if not valid:
                 return False  # Cant download content.jsons or size is not fits
 

+ 1 - 1
src/Site/SiteStorage.py

@@ -57,7 +57,7 @@ class SiteStorage:
     def getDb(self):
         if not self.db:
             self.log.debug("No database, waiting for dbschema.json...")
-            self.site.needFile("dbschema.json", priority=1)
+            self.site.needFile("dbschema.json", priority=3)
             self.has_db = self.isFile("dbschema.json")  # Recheck if dbschema exist
             if self.has_db:
                 self.openDb()

+ 13 - 0
src/Test/TestCryptBitcoin.py

@@ -42,3 +42,16 @@ class TestCryptBitcoin:
         # Signed by bad privatekey
         sign_bad = CryptBitcoin.sign("hello", privatekey_bad)
         assert not CryptBitcoin.verify("hello", address, sign_bad)
+
+    def testNewPrivatekey(self):
+        assert CryptBitcoin.newPrivatekey() != CryptBitcoin.newPrivatekey()
+        assert CryptBitcoin.privatekeyToAddress(CryptBitcoin.newPrivatekey())
+
+    def testNewSeed(self):
+        assert CryptBitcoin.newSeed() != CryptBitcoin.newSeed()
+        assert CryptBitcoin.privatekeyToAddress(
+            CryptBitcoin.hdPrivatekey(CryptBitcoin.newSeed(), 0)
+        )
+        assert CryptBitcoin.privatekeyToAddress(
+            CryptBitcoin.hdPrivatekey(CryptBitcoin.newSeed(), 2**256)
+        )

+ 17 - 0
src/Test/TestHelper.py

@@ -0,0 +1,17 @@
+class Spy:
+	def __init__(self, obj, func_name):
+		self.obj = obj
+		self.func_name = func_name
+		self.func_original = getattr(self.obj, func_name)
+		self.calls = []
+
+	def __enter__(self, *args, **kwargs):
+		def loggedFunc(cls, *args, **kwags):
+			print "Logging", self, args, kwargs
+			self.calls.append(args)
+			return self.func_original(cls, *args, **kwargs)
+		setattr(self.obj, self.func_name, loggedFunc)
+		return self.calls
+
+	def __exit__(self, *args, **kwargs):
+		setattr(self.obj, self.func_name, self.func_original)

+ 29 - 11
src/Test/TestWorker.py

@@ -1,22 +1,21 @@
-import time
-import os
-
-import gevent
 import pytest
 import mock
+import time
 
-from Crypt import CryptConnection
 from Connection import ConnectionServer
 from Config import config
 from Site import Site
+from File import FileRequest
+import TestHelper
 
 @pytest.mark.usefixtures("resetTempSettings")
 @pytest.mark.usefixtures("resetSettings")
 class TestWorker:
     def testDownload(self, file_server, site, site_temp):
+
         client = ConnectionServer("127.0.0.1", 1545)
-        assert site.storage.directory == config.data_dir+"/"+site.address
-        assert site_temp.storage.directory == config.data_dir+"-temp/"+site.address
+        assert site.storage.directory == config.data_dir + "/" + site.address
+        assert site_temp.storage.directory == config.data_dir + "-temp/" + site.address
 
         # Init source server
         site.connection_server = file_server
@@ -26,10 +25,29 @@ class TestWorker:
         site_temp.connection_server = client
         site_temp.announce = mock.MagicMock(return_value=True)  # Don't try to find peers from the net
 
-        # Download to client from source
         site_temp.addPeer("127.0.0.1", 1544)
-        site_temp.download().join(timeout=5)
-
-        assert not site_temp.bad_files
+        with TestHelper.Spy(FileRequest, "route") as requests:
+            def boostRequest(inner_path):
+                # I really want these file
+                if inner_path == "index.html":
+                    print "needFile"
+                    site_temp.needFile("data/img/multiuser.png", priority=9, blocking=False)
+                    site_temp.needFile("data/img/direct_domains.png", priority=10, blocking=False)
+            site_temp.onFileDone.append(boostRequest)
+            site_temp.download(blind_includes=True).join(timeout=5)
+            file_requests = [request[2]["inner_path"] for request in requests if request[0] in ("getFile", "streamFile")]
+            # Test priority
+            assert file_requests[0:2] == ["content.json", "index.html"]  # Must-have files
+            assert file_requests[2:4] == ["data/img/direct_domains.png", "data/img/multiuser.png"]  # Directly requested files
+            assert file_requests[4:6] == ["css/all.css", "js/all.js"]  # Important assets
+            assert file_requests[6] == "dbschema.json"  # Database map
+            assert "-default" in file_requests[-1]  # Put default files for cloning to the end
+
+        # Check files
+        bad_files = site_temp.storage.verifyFiles(quick_check=True)
+
+        # -1 because data/users/1J6... user has invalid cert
+        assert len(site_temp.content_manager.contents) == len(site.content_manager.contents) - 1
+        assert not bad_files
 
         site_temp.storage.deleteFiles()

+ 1 - 1
src/Ui/UiRequest.py

@@ -330,7 +330,7 @@ class UiRequest(object):
                     return self.actionFile(file_path)
                 else:  # File not exits, try to download
                     site = SiteManager.site_manager.need(address, all_file=False)
-                    result = site.needFile(match.group("inner_path"), priority=1)  # Wait until file downloads
+                    result = site.needFile(match.group("inner_path"), priority=5)  # Wait until file downloads
                     if result:
                         return self.actionFile(file_path)
                     else:

+ 4 - 4
src/Ui/media/Fixbutton.coffee

@@ -1,12 +1,12 @@
 class Fixbutton
 	constructor: ->
 		@dragging = false
-		$(".fixbutton-bg").on "mouseover", =>
+		$(".fixbutton-bg").on "mouseover", ->
 			$(".fixbutton-bg").stop().animate({"scale": 0.7}, 800, "easeOutElastic")
 			$(".fixbutton-burger").stop().animate({"opacity": 1.5, "left": 0}, 800, "easeOutElastic")
 			$(".fixbutton-text").stop().animate({"opacity": 0, "left": 20}, 300, "easeOutCubic")
 
-		$(".fixbutton-bg").on "mouseout", =>
+		$(".fixbutton-bg").on "mouseout", ->
 			if $(".fixbutton").hasClass("dragging")
 				return true
 			$(".fixbutton-bg").stop().animate({"scale": 0.6}, 300, "easeOutCubic")
@@ -18,13 +18,13 @@ class Fixbutton
 			return false
 		###
 
-		$(".fixbutton-bg").on "mousedown", =>
+		$(".fixbutton-bg").on "mousedown", ->
 			# $(".fixbutton-burger").stop().animate({"scale": 0.7, "left": 0}, 300, "easeOutCubic")
 			#$("#inner-iframe").toggleClass("back")
 			#$(".wrapper-iframe").stop().animate({"scale": 0.9}, 600, "easeOutCubic")
 			#$("body").addClass("back")
 
-		$(".fixbutton-bg").on "mouseup", =>
+		$(".fixbutton-bg").on "mouseup", ->
 			# $(".fixbutton-burger").stop().animate({"scale": 1, "left": 0}, 600, "easeOutElastic")
 
 

+ 2 - 2
src/Ui/media/Loading.coffee

@@ -21,7 +21,7 @@ class Loading
 		if $(".console .button-setlimit").length == 0 # Not displaying it yet
 			line = @printLine("Site size: <b>#{parseInt(site_info.settings.size/1024/1024)}MB</b> is larger than default allowed #{parseInt(site_info.size_limit)}MB", "warning")
 			button = $("<a href='#Set+limit' class='button button-setlimit'>Open site and set size limit to #{site_info.next_size_limit}MB</a>")
-			button.on "click", (=> return window.wrapper.setSizeLimit(site_info.next_size_limit) )
+			button.on "click", (-> return window.wrapper.setSizeLimit(site_info.next_size_limit) )
 			line.after(button)
 			setTimeout (=>
 				@printLine('Ready.')
@@ -54,7 +54,7 @@ class Loading
 		if not @screen_visible then return false
 		$(".loadingscreen .console .cursor").remove() # Remove previous cursor
 		if type == "error" then text = "<span class='console-error'>#{text}</span>" else text = text+"<span class='cursor'> </span>"
-			
+
 		line = $("<div class='console-line'>#{text}</div>").appendTo(".loadingscreen .console")
 		if type == "warning" then line.addClass("console-warning")
 		return line

+ 0 - 2
src/Ui/media/Wrapper.coffee

@@ -33,8 +33,6 @@ class Wrapper
 
 		$("#inner-iframe").focus()
 
-		@
-
 
 	# Incoming message from UiServer websocket
 	onMessageWebsocket: (e) =>

+ 11 - 11
src/Ui/media/Wrapper.css

@@ -1,11 +1,11 @@
-body { margin: 0px; padding: 0px; height: 100%; background-color: #D2CECD; overflow: hidden }
+body { margin: 0; padding: 0; height: 100%; background-color: #D2CECD; overflow: hidden }
 body.back { background-color: #090909 }
 a { color: black }
 
 .template { display: none !important }
 
-#inner-iframe { width: 100%; height: 100%; position: absolute; border: 0px } /*; transition: all 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55), opacity 0.8s ease-in-out*/
-#inner-iframe.back { transform: scale(0.95) translate(-300px, 0px); opacity: 0.4 }
+#inner-iframe { width: 100%; height: 100%; position: absolute; border: 0 } /*; transition: all 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55), opacity 0.8s ease-in-out*/
+#inner-iframe.back { transform: scale(0.95) translate(-300px, 0); opacity: 0.4 }
 
 .button { padding: 5px 10px; margin-left: 10px; background-color: #FFF85F; border-bottom: 2px solid #CDBD1E; border-radius: 2px; text-decoration: none; transition: all 0.5s; background-position: left center; }
 .button:hover { background-color: #FFF400; border-bottom: 2px solid #4D4D4C; transition: none }
@@ -29,17 +29,17 @@ a { color: black }
 .fixbutton-bg {
 	border-radius: 80px; background-color: rgba(180, 180, 180, 0.5); cursor: pointer;
 	display: block; width: 80px; height: 80px; transition: background-color 0.2s, box-shadow 0.5s; transform: scale(0.6); margin-left: -20px; margin-top: -20px; /* 2x size to prevent blur on anim */
-	/*box-shadow: inset 105px 260px 0px -200px rgba(0,0,0,0.1);*/ /* box-shadow: inset -75px 183px 0px -200px rgba(0,0,0,0.1); */
+	/*box-shadow: inset 105px 260px 0 -200px rgba(0,0,0,0.1);*/ /* box-shadow: inset -75px 183px 0 -200px rgba(0,0,0,0.1); */
 }
-.fixbutton-text { pointer-events: none; position: absolute; z-index: 999; width: 40px; backface-visibility: hidden; perspective: 1000px; line-height: 0px; padding-top: 20px }
-.fixbutton-burger { pointer-events: none; position: absolute; z-index: 999; width: 40px; opacity: 0; left: -20px; font-size: 40px; line-height: 0px; font-family: Verdana, sans-serif; margin-top: 17px }
+.fixbutton-text { pointer-events: none; position: absolute; z-index: 999; width: 40px; backface-visibility: hidden; perspective: 1000px; line-height: 0; padding-top: 20px }
+.fixbutton-burger { pointer-events: none; position: absolute; z-index: 999; width: 40px; opacity: 0; left: -20px; font-size: 40px; line-height: 0; font-family: Verdana, sans-serif; margin-top: 17px }
 .fixbutton-bg:hover { background-color: #AF3BFF }
 .fixbutton-bg:active { background-color: #9E2FEA; top: 1px; transition: none }
 
 
 /* Notification */
 
-.notifications { position: absolute; top: 0px; right: 80px; display: inline-block; z-index: 999; white-space: nowrap }
+.notifications { position: absolute; top: 0; right: 80px; display: inline-block; z-index: 999; white-space: nowrap }
 .notification {
 	position: relative; float: right; clear: both; margin: 10px; box-sizing: border-box; overflow: hidden; backface-visibility: hidden; perspective: 1000px; padding-bottom: 5px;
 	color: #4F4F4F; font-family: 'Lucida Grande', 'Segoe UI', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px; /*border: 1px solid rgba(210, 206, 205, 0.2)*/
@@ -50,18 +50,18 @@ a { color: black }
 }
 .notification .body {
 	max-width: 560px; padding-left: 14px; padding-right: 60px; height: 40px; vertical-align: middle; display: table;
-	background-color: white; left: 50px; top: 0px; position: relative; padding-top: 5px; padding-bottom: 5px;
+	background-color: white; left: 50px; top: 0; position: relative; padding-top: 5px; padding-bottom: 5px;
 }
 .notification.long .body { padding-top: 10px; padding-bottom: 10px }
 .notification .message { display: table-cell; vertical-align: middle }
 
 .notification.visible { max-width: 350px }
 
-.notification .close { position: absolute; top: 0px; right: 0px; font-size: 19px; line-height: 13px; color: #DDD; padding: 7px; text-decoration: none }
+.notification .close { position: absolute; top: 0; right: 0; font-size: 19px; line-height: 13px; color: #DDD; padding: 7px; text-decoration: none }
 .notification .close:hover { color: black }
 .notification .close:active, .notification .close:focus { color: #AF3BFF }
 .notification small { color: #AAA }
-.body-white .notification { box-shadow: 0px 1px 9px rgba(0,0,0,0.1) }
+.body-white .notification { box-shadow: 0 1px 9px rgba(0,0,0,0.1) }
 
 /* Notification select */
 .notification .select {
@@ -126,7 +126,7 @@ a { color: black }
 
 .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%;
+	display: block; position: absolute; right: 0; width: 100px; height: 100%;
 	box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; opacity: 1.0; transform: rotate(3deg) translate(0px, -4px);
 }
 

+ 11 - 11
src/Ui/media/all.css

@@ -3,14 +3,14 @@
 /* ---- src/Ui/media/Wrapper.css ---- */
 
 
-body { margin: 0px; padding: 0px; height: 100%; background-color: #D2CECD; overflow: hidden }
+body { margin: 0; padding: 0; height: 100%; background-color: #D2CECD; overflow: hidden }
 body.back { background-color: #090909 }
 a { color: black }
 
 .template { display: none !important }
 
-#inner-iframe { width: 100%; height: 100%; position: absolute; border: 0px } /*; transition: all 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55), opacity 0.8s ease-in-out*/
-#inner-iframe.back { -webkit-transform: scale(0.95) translate(-300px, 0px); -moz-transform: scale(0.95) translate(-300px, 0px); -o-transform: scale(0.95) translate(-300px, 0px); -ms-transform: scale(0.95) translate(-300px, 0px); transform: scale(0.95) translate(-300px, 0px) ; opacity: 0.4 }
+#inner-iframe { width: 100%; height: 100%; position: absolute; border: 0 } /*; transition: all 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55), opacity 0.8s ease-in-out*/
+#inner-iframe.back { -webkit-transform: scale(0.95) translate(-300px, 0); -moz-transform: scale(0.95) translate(-300px, 0); -o-transform: scale(0.95) translate(-300px, 0); -ms-transform: scale(0.95) translate(-300px, 0); transform: scale(0.95) translate(-300px, 0) ; opacity: 0.4 }
 
 .button { padding: 5px 10px; margin-left: 10px; background-color: #FFF85F; border-bottom: 2px solid #CDBD1E; -webkit-border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -ms-border-radius: 2px; border-radius: 2px ; text-decoration: none; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; -o-transition: all 0.5s; -ms-transition: all 0.5s; transition: all 0.5s ; background-position: left center; }
 .button:hover { background-color: #FFF400; border-bottom: 2px solid #4D4D4C; -webkit-transition: none ; -moz-transition: none ; -o-transition: none ; -ms-transition: none ; transition: none  }
@@ -34,17 +34,17 @@ a { color: black }
 .fixbutton-bg {
 	-webkit-border-radius: 80px; -moz-border-radius: 80px; -o-border-radius: 80px; -ms-border-radius: 80px; border-radius: 80px ; background-color: rgba(180, 180, 180, 0.5); cursor: pointer;
 	display: block; width: 80px; height: 80px; -webkit-transition: background-color 0.2s, box-shadow 0.5s; -moz-transition: background-color 0.2s, box-shadow 0.5s; -o-transition: background-color 0.2s, box-shadow 0.5s; -ms-transition: background-color 0.2s, box-shadow 0.5s; transition: background-color 0.2s, box-shadow 0.5s ; -webkit-transform: scale(0.6); -moz-transform: scale(0.6); -o-transform: scale(0.6); -ms-transform: scale(0.6); transform: scale(0.6) ; margin-left: -20px; margin-top: -20px; /* 2x size to prevent blur on anim */
-	/*box-shadow: inset 105px 260px 0px -200px rgba(0,0,0,0.1);*/ /* -webkit-box-shadow: inset -75px 183px 0px -200px rgba(0,0,0,0.1); -moz-box-shadow: inset -75px 183px 0px -200px rgba(0,0,0,0.1); -o-box-shadow: inset -75px 183px 0px -200px rgba(0,0,0,0.1); -ms-box-shadow: inset -75px 183px 0px -200px rgba(0,0,0,0.1); box-shadow: inset -75px 183px 0px -200px rgba(0,0,0,0.1) ; */
+	/*box-shadow: inset 105px 260px 0 -200px rgba(0,0,0,0.1);*/ /* -webkit-box-shadow: inset -75px 183px 0 -200px rgba(0,0,0,0.1); -moz-box-shadow: inset -75px 183px 0 -200px rgba(0,0,0,0.1); -o-box-shadow: inset -75px 183px 0 -200px rgba(0,0,0,0.1); -ms-box-shadow: inset -75px 183px 0 -200px rgba(0,0,0,0.1); box-shadow: inset -75px 183px 0 -200px rgba(0,0,0,0.1) ; */
 }
-.fixbutton-text { pointer-events: none; position: absolute; z-index: 999; width: 40px; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -o-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden ; -webkit-perspective: 1000px; -moz-perspective: 1000px; -o-perspective: 1000px; -ms-perspective: 1000px; perspective: 1000px ; line-height: 0px; padding-top: 20px }
-.fixbutton-burger { pointer-events: none; position: absolute; z-index: 999; width: 40px; opacity: 0; left: -20px; font-size: 40px; line-height: 0px; font-family: Verdana, sans-serif; margin-top: 17px }
+.fixbutton-text { pointer-events: none; position: absolute; z-index: 999; width: 40px; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -o-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden ; -webkit-perspective: 1000px; -moz-perspective: 1000px; -o-perspective: 1000px; -ms-perspective: 1000px; perspective: 1000px ; line-height: 0; padding-top: 20px }
+.fixbutton-burger { pointer-events: none; position: absolute; z-index: 999; width: 40px; opacity: 0; left: -20px; font-size: 40px; line-height: 0; font-family: Verdana, sans-serif; margin-top: 17px }
 .fixbutton-bg:hover { background-color: #AF3BFF }
 .fixbutton-bg:active { background-color: #9E2FEA; top: 1px; -webkit-transition: none ; -moz-transition: none ; -o-transition: none ; -ms-transition: none ; transition: none  }
 
 
 /* Notification */
 
-.notifications { position: absolute; top: 0px; right: 80px; display: inline-block; z-index: 999; white-space: nowrap }
+.notifications { position: absolute; top: 0; right: 80px; display: inline-block; z-index: 999; white-space: nowrap }
 .notification {
 	position: relative; float: right; clear: both; margin: 10px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box ; overflow: hidden; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -o-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden ; -webkit-perspective: 1000px; -moz-perspective: 1000px; -o-perspective: 1000px; -ms-perspective: 1000px; perspective: 1000px ; padding-bottom: 5px;
 	color: #4F4F4F; font-family: 'Lucida Grande', 'Segoe UI', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px; /*border: 1px solid rgba(210, 206, 205, 0.2)*/
@@ -55,18 +55,18 @@ a { color: black }
 }
 .notification .body {
 	max-width: 560px; padding-left: 14px; padding-right: 60px; height: 40px; vertical-align: middle; display: table;
-	background-color: white; left: 50px; top: 0px; position: relative; padding-top: 5px; padding-bottom: 5px;
+	background-color: white; left: 50px; top: 0; position: relative; padding-top: 5px; padding-bottom: 5px;
 }
 .notification.long .body { padding-top: 10px; padding-bottom: 10px }
 .notification .message { display: table-cell; vertical-align: middle }
 
 .notification.visible { max-width: 350px }
 
-.notification .close { position: absolute; top: 0px; right: 0px; font-size: 19px; line-height: 13px; color: #DDD; padding: 7px; text-decoration: none }
+.notification .close { position: absolute; top: 0; right: 0; font-size: 19px; line-height: 13px; color: #DDD; padding: 7px; text-decoration: none }
 .notification .close:hover { color: black }
 .notification .close:active, .notification .close:focus { color: #AF3BFF }
 .notification small { color: #AAA }
-.body-white .notification { -webkit-box-shadow: 0px 1px 9px rgba(0,0,0,0.1) ; -moz-box-shadow: 0px 1px 9px rgba(0,0,0,0.1) ; -o-box-shadow: 0px 1px 9px rgba(0,0,0,0.1) ; -ms-box-shadow: 0px 1px 9px rgba(0,0,0,0.1) ; box-shadow: 0px 1px 9px rgba(0,0,0,0.1)  }
+.body-white .notification { -webkit-box-shadow: 0 1px 9px rgba(0,0,0,0.1) ; -moz-box-shadow: 0 1px 9px rgba(0,0,0,0.1) ; -o-box-shadow: 0 1px 9px rgba(0,0,0,0.1) ; -ms-box-shadow: 0 1px 9px rgba(0,0,0,0.1) ; box-shadow: 0 1px 9px rgba(0,0,0,0.1)  }
 
 /* Notification select */
 .notification .select {
@@ -131,7 +131,7 @@ a { color: black }
 
 .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%;
+	display: block; position: absolute; right: 0; 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) ;
 }
 

+ 40 - 46
src/Ui/media/all.js

@@ -149,11 +149,12 @@
 }).call(this);
 
 
+
 /* ---- src/Ui/media/lib/jquery.cssanim.js ---- */
 
 
 jQuery.cssHooks['scale'] = {
-	get: function(elem, computed, extra) {
+	get: function(elem, computed) {
 		var match = window.getComputedStyle(elem)[transform_property].match("[0-9\.]+")
 		if (match) {
 			var scale = parseFloat(match[0])
@@ -256,6 +257,7 @@ if (window.getComputedStyle(document.body).transform) {
 }).call(this);
 
 
+
 /* ---- src/Ui/media/lib/jquery.easing.1.3.js ---- */
 
 
@@ -475,49 +477,41 @@ jQuery.extend( jQuery.easing,
   Fixbutton = (function() {
     function Fixbutton() {
       this.dragging = false;
-      $(".fixbutton-bg").on("mouseover", (function(_this) {
-        return function() {
-          $(".fixbutton-bg").stop().animate({
-            "scale": 0.7
-          }, 800, "easeOutElastic");
-          $(".fixbutton-burger").stop().animate({
-            "opacity": 1.5,
-            "left": 0
-          }, 800, "easeOutElastic");
-          return $(".fixbutton-text").stop().animate({
-            "opacity": 0,
-            "left": 20
-          }, 300, "easeOutCubic");
-        };
-      })(this));
-      $(".fixbutton-bg").on("mouseout", (function(_this) {
-        return function() {
-          if ($(".fixbutton").hasClass("dragging")) {
-            return true;
-          }
-          $(".fixbutton-bg").stop().animate({
-            "scale": 0.6
-          }, 300, "easeOutCubic");
-          $(".fixbutton-burger").stop().animate({
-            "opacity": 0,
-            "left": -20
-          }, 300, "easeOutCubic");
-          return $(".fixbutton-text").stop().animate({
-            "opacity": 1,
-            "left": 0
-          }, 300, "easeOutBack");
-        };
-      })(this));
+      $(".fixbutton-bg").on("mouseover", function() {
+        $(".fixbutton-bg").stop().animate({
+          "scale": 0.7
+        }, 800, "easeOutElastic");
+        $(".fixbutton-burger").stop().animate({
+          "opacity": 1.5,
+          "left": 0
+        }, 800, "easeOutElastic");
+        return $(".fixbutton-text").stop().animate({
+          "opacity": 0,
+          "left": 20
+        }, 300, "easeOutCubic");
+      });
+      $(".fixbutton-bg").on("mouseout", function() {
+        if ($(".fixbutton").hasClass("dragging")) {
+          return true;
+        }
+        $(".fixbutton-bg").stop().animate({
+          "scale": 0.6
+        }, 300, "easeOutCubic");
+        $(".fixbutton-burger").stop().animate({
+          "opacity": 0,
+          "left": -20
+        }, 300, "easeOutCubic");
+        return $(".fixbutton-text").stop().animate({
+          "opacity": 1,
+          "left": 0
+        }, 300, "easeOutBack");
+      });
 
       /*$(".fixbutton-bg").on "click", ->
       			return false
        */
-      $(".fixbutton-bg").on("mousedown", (function(_this) {
-        return function() {};
-      })(this));
-      $(".fixbutton-bg").on("mouseup", (function(_this) {
-        return function() {};
-      })(this));
+      $(".fixbutton-bg").on("mousedown", function() {});
+      $(".fixbutton-bg").on("mouseup", function() {});
     }
 
     return Fixbutton;
@@ -529,6 +523,7 @@ jQuery.extend( jQuery.easing,
 }).call(this);
 
 
+
 /* ---- src/Ui/media/Loading.coffee ---- */
 
 
@@ -562,11 +557,9 @@ jQuery.extend( jQuery.easing,
       if ($(".console .button-setlimit").length === 0) {
         line = this.printLine("Site size: <b>" + (parseInt(site_info.settings.size / 1024 / 1024)) + "MB</b> is larger than default allowed " + (parseInt(site_info.size_limit)) + "MB", "warning");
         button = $("<a href='#Set+limit' class='button button-setlimit'>Open site and set size limit to " + site_info.next_size_limit + "MB</a>");
-        button.on("click", ((function(_this) {
-          return function() {
-            return window.wrapper.setSizeLimit(site_info.next_size_limit);
-          };
-        })(this)));
+        button.on("click", (function() {
+          return window.wrapper.setSizeLimit(site_info.next_size_limit);
+        }));
         line.after(button);
         return setTimeout(((function(_this) {
           return function() {
@@ -634,6 +627,7 @@ jQuery.extend( jQuery.easing,
 }).call(this);
 
 
+
 /* ---- src/Ui/media/Notifications.coffee ---- */
 
 
@@ -753,6 +747,7 @@ jQuery.extend( jQuery.easing,
 }).call(this);
 
 
+
 /* ---- src/Ui/media/Wrapper.coffee ---- */
 
 
@@ -803,7 +798,6 @@ jQuery.extend( jQuery.easing,
         };
       })(this));
       $("#inner-iframe").focus();
-      this;
     }
 
     Wrapper.prototype.onMessageWebsocket = function(e) {

+ 1 - 1
src/Ui/media/lib/jquery.cssanim.js

@@ -1,5 +1,5 @@
 jQuery.cssHooks['scale'] = {
-	get: function(elem, computed, extra) {
+	get: function(elem, computed) {
 		var match = window.getComputedStyle(elem)[transform_property].match("[0-9\.]+")
 		if (match) {
 			var scale = parseFloat(match[0])

+ 2 - 2
src/User/User.py

@@ -5,7 +5,7 @@ import time
 from Crypt import CryptBitcoin
 from Plugin import PluginManager
 from Config import config
-from util import utils
+from util import helper
 
 @PluginManager.acceptPlugins
 class User(object):
@@ -35,7 +35,7 @@ class User(object):
             user_data["master_seed"] = self.master_seed
         user_data["sites"] = self.sites
         user_data["certs"] = self.certs
-        utils.atomicWrite("%s/users.json" % config.data_dir, json.dumps(users, indent=2, sort_keys=True))
+        helper.atomicWrite("%s/users.json" % config.data_dir, json.dumps(users, indent=2, sort_keys=True))
         self.log.debug("Saved")
 
     def getAddressAuthIndex(self, address):

+ 14 - 7
src/Worker/WorkerManager.py

@@ -72,16 +72,23 @@ class WorkerManager:
 
     # Tasks sorted by this
     def taskSorter(self, task):
-        if task["inner_path"] == "content.json":
+        inner_path = task["inner_path"]
+        if inner_path == "content.json":
             return 9999  # Content.json always prority
-        if task["inner_path"] == "index.html":
+        if inner_path == "index.html":
             return 9998  # index.html also important
         priority = task["priority"]
-        if task["inner_path"].endswith(".js") or task["inner_path"].endswith(".css"):
-            priority += 2  # boost js and css files priority
-        elif task["inner_path"].endswith(".json"):
-            priority += 1  # boost json files priority
-        return priority - task["workers_num"]  # Prefer more priority and less workers
+        if "-default" in inner_path:
+            priority -= 4  # Default files are cloning not important
+        elif inner_path.endswith(".css"):
+            priority += 5  # boost css files priority
+        elif inner_path.endswith(".js"):
+            priority += 3  # boost js files priority
+        elif inner_path.endswith("content.json"):
+            priority += 1  # boost included content.json files priority a bit
+        elif inner_path.endswith(".json"):
+            priority += 2  # boost data json files priority more
+        return priority - task["workers_num"]*5  # Prefer more priority and less workers
 
     # Returns the next free or less worked task
     def getTask(self, peer):

+ 0 - 52
src/util/GeventSslPatch.py

@@ -1,52 +0,0 @@
-# Re-add sslwrap to Python 2.7.9
-# https://github.com/gevent/gevent/issues/477
-
-import inspect
-__ssl__ = __import__('ssl')
-
-try:
-    _ssl = __ssl__._ssl
-except AttributeError:
-    _ssl = __ssl__._ssl2
-
-
-OldSSLSocket = __ssl__.SSLSocket
-
-
-class NewSSLSocket(OldSSLSocket):
-
-    """Fix SSLSocket constructor."""
-
-    def __init__(
-        self, sock, keyfile=None, certfile=None, server_side=False, cert_reqs=0,
-        ssl_version=2, ca_certs=None, do_handshake_on_connect=True,
-        suppress_ragged_eofs=True, ciphers=None,
-        server_hostname=None, _context=None
-    ):
-        OldSSLSocket.__init__(
-            self, sock, keyfile=None, certfile=None, server_side=False, cert_reqs=0,
-            ssl_version=2, ca_certs=None, do_handshake_on_connect=True,
-            suppress_ragged_eofs=True, ciphers=None
-        )
-
-
-def new_sslwrap(
-    sock, server_side=False, keyfile=None, certfile=None,
-    cert_reqs=__ssl__.CERT_NONE, ssl_version=__ssl__.PROTOCOL_SSLv23,
-    ca_certs=None, ciphers=None
-):
-    context = __ssl__.SSLContext(ssl_version)
-    context.verify_mode = cert_reqs or __ssl__.CERT_NONE
-    if ca_certs:
-        context.load_verify_locations(ca_certs)
-    if certfile:
-        context.load_cert_chain(certfile, keyfile)
-    if ciphers:
-        context.set_ciphers(ciphers)
-
-    caller_self = inspect.currentframe().f_back.f_locals['self']
-    return context._wrap_socket(sock, server_side=server_side, ssl_sock=caller_self)
-
-if not hasattr(_ssl, 'sslwrap'):
-    _ssl.sslwrap = new_sslwrap
-    __ssl__.SSLSocket = NewSSLSocket

+ 2 - 3
src/util/Http.py

@@ -1,13 +1,12 @@
 import urllib2
 import logging
 
-import GeventSslPatch
 from Config import config
 
 
-def get(url):
+def get(url, accept="application/json"):
     logging.debug("Get %s" % url)
     req = urllib2.Request(url)
     req.add_header('User-Agent', "ZeroNet %s (https://github.com/HelloZeroNet/ZeroNet)" % config.version)
-    req.add_header('Accept', 'application/json')
+    req.add_header('Accept', accept)
     return urllib2.urlopen(req)

+ 10 - 0
src/util/utils.py → src/util/helper.py

@@ -1,4 +1,6 @@
 import os
+import socket
+import struct
 
 
 def atomicWrite(dest, content, mode="w"):
@@ -13,3 +15,11 @@ def shellquote(*args):
         return '"%s"' % args[0].replace('"', "")
     else:
         return tuple(['"%s"' % arg.replace('"', "") for arg in args])
+
+# ip, port to packed 6byte format
+def packAddress(ip, port):
+    return socket.inet_aton(ip) + struct.pack("H", port)
+
+# From 6byte format to ip, port
+def unpackAddress(packed):
+    return socket.inet_ntoa(packed[0:4]), struct.unpack_from("H", packed, 4)[0]