From 4b403da0568dd83e99c89483aac9d21d71acc3f7 Mon Sep 17 00:00:00 2001 From: HelloZeroNet Date: Sun, 27 Sep 2015 02:08:53 +0200 Subject: [PATCH] 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 --- src/Config.py | 8 +-- src/Content/ContentManager.py | 81 ++++++++++++++-------------- src/Crypt/CryptConnection.py | 8 +-- src/Debug/DebugMedia.py | 6 +-- src/File/FileRequest.py | 11 ++-- src/Peer/Peer.py | 17 +++--- src/Site/Site.py | 6 +-- src/Site/SiteStorage.py | 2 +- src/Test/TestCryptBitcoin.py | 13 +++++ src/Test/TestHelper.py | 17 ++++++ src/Test/TestWorker.py | 38 +++++++++---- src/Ui/UiRequest.py | 2 +- src/Ui/media/Fixbutton.coffee | 8 +-- src/Ui/media/Loading.coffee | 4 +- src/Ui/media/Wrapper.coffee | 2 - src/Ui/media/Wrapper.css | 22 ++++---- src/Ui/media/all.css | 22 ++++---- src/Ui/media/all.js | 86 ++++++++++++++---------------- src/Ui/media/lib/jquery.cssanim.js | 2 +- src/User/User.py | 4 +- src/Worker/WorkerManager.py | 21 +++++--- src/util/GeventSslPatch.py | 52 ------------------ src/util/Http.py | 5 +- src/util/{utils.py => helper.py} | 10 ++++ 24 files changed, 221 insertions(+), 226 deletions(-) create mode 100644 src/Test/TestHelper.py delete mode 100644 src/util/GeventSslPatch.py rename src/util/{utils.py => helper.py} (56%) diff --git a/src/Config.py b/src/Config.py index 8fb8d133..41a57406 100644 --- a/src/Config.py +++ b/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: diff --git a/src/Content/ContentManager.py b/src/Content/ContentManager.py index 0211b8fc..fa0ae8f1 100644 --- a/src/Content/ContentManager.py +++ b/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() - - 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 - ) - - 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 - ) - - -def testInfo(): - from Site import Site - site = Site("12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH") - - 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__": + 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() + + 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 + ) + + 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 + ) + + def testInfo(): + from Site import Site + site = Site("12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH") + + 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") + import sys import logging os.chdir("../..") diff --git a/src/Crypt/CryptConnection.py b/src/Crypt/CryptConnection.py index 5608b740..fb2c0920 100644 --- a/src/Crypt/CryptConnection.py +++ b/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() \ No newline at end of file +manager = CryptConnectionManager() diff --git a/src/Debug/DebugMedia.py b/src/Debug/DebugMedia.py index abe49a79..27256d09 100644 --- a/src/Debug/DebugMedia.py +++ b/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 diff --git a/src/File/FileRequest.py b/src/File/FileRequest.py index 96ed4c2f..bb4dc3f4 100644 --- a/src/File/FileRequest.py +++ b/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 diff --git a/src/Peer/Peer.py b/src/Peer/Peer.py index 09f4702e..77b689b7 100644 --- a/src/Peer/Peer.py +++ b/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: diff --git a/src/Site/Site.py b/src/Site/Site.py index 7d6f0fe5..61ae9ccc 100644 --- a/src/Site/Site.py +++ b/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 diff --git a/src/Site/SiteStorage.py b/src/Site/SiteStorage.py index 02f58f5f..9368fbb6 100644 --- a/src/Site/SiteStorage.py +++ b/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() diff --git a/src/Test/TestCryptBitcoin.py b/src/Test/TestCryptBitcoin.py index dad17d0d..bebf906e 100644 --- a/src/Test/TestCryptBitcoin.py +++ b/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) + ) diff --git a/src/Test/TestHelper.py b/src/Test/TestHelper.py new file mode 100644 index 00000000..c017dea9 --- /dev/null +++ b/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) \ No newline at end of file diff --git a/src/Test/TestWorker.py b/src/Test/TestWorker.py index 36a329ef..f5d1abf7 100644 --- a/src/Test/TestWorker.py +++ b/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) + 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 - assert not site_temp.bad_files + # 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() diff --git a/src/Ui/UiRequest.py b/src/Ui/UiRequest.py index decd05f5..d2a34ac7 100644 --- a/src/Ui/UiRequest.py +++ b/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: diff --git a/src/Ui/media/Fixbutton.coffee b/src/Ui/media/Fixbutton.coffee index 1eb4f2e7..9e644a4e 100644 --- a/src/Ui/media/Fixbutton.coffee +++ b/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") diff --git a/src/Ui/media/Loading.coffee b/src/Ui/media/Loading.coffee index 25cce3eb..a18ae4f9 100644 --- a/src/Ui/media/Loading.coffee +++ b/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: #{parseInt(site_info.settings.size/1024/1024)}MB is larger than default allowed #{parseInt(site_info.size_limit)}MB", "warning") button = $("Open site and set size limit to #{site_info.next_size_limit}MB") - 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 = "#{text}" else text = text+" " - + line = $("
#{text}
").appendTo(".loadingscreen .console") if type == "warning" then line.addClass("console-warning") return line diff --git a/src/Ui/media/Wrapper.coffee b/src/Ui/media/Wrapper.coffee index e811dee6..4625a99c 100644 --- a/src/Ui/media/Wrapper.coffee +++ b/src/Ui/media/Wrapper.coffee @@ -33,8 +33,6 @@ class Wrapper $("#inner-iframe").focus() - @ - # Incoming message from UiServer websocket onMessageWebsocket: (e) => diff --git a/src/Ui/media/Wrapper.css b/src/Ui/media/Wrapper.css index f22099e2..5c91e88e 100644 --- a/src/Ui/media/Wrapper.css +++ b/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); } diff --git a/src/Ui/media/all.css b/src/Ui/media/all.css index b29b9068..bcf20b3a 100644 --- a/src/Ui/media/all.css +++ b/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) ; } diff --git a/src/Ui/media/all.js b/src/Ui/media/all.js index f4caf715..a18312fb 100644 --- a/src/Ui/media/all.js +++ b/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: " + (parseInt(site_info.settings.size / 1024 / 1024)) + "MB is larger than default allowed " + (parseInt(site_info.size_limit)) + "MB", "warning"); button = $("Open site and set size limit to " + site_info.next_size_limit + "MB"); - 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) { diff --git a/src/Ui/media/lib/jquery.cssanim.js b/src/Ui/media/lib/jquery.cssanim.js index be93a386..04879b62 100644 --- a/src/Ui/media/lib/jquery.cssanim.js +++ b/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]) diff --git a/src/User/User.py b/src/User/User.py index 6e13c793..1822345e 100644 --- a/src/User/User.py +++ b/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): diff --git a/src/Worker/WorkerManager.py b/src/Worker/WorkerManager.py index ba4b9f1a..06d438e6 100644 --- a/src/Worker/WorkerManager.py +++ b/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): diff --git a/src/util/GeventSslPatch.py b/src/util/GeventSslPatch.py deleted file mode 100644 index 8eb8be80..00000000 --- a/src/util/GeventSslPatch.py +++ /dev/null @@ -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 diff --git a/src/util/Http.py b/src/util/Http.py index f8c62c72..05f6446e 100644 --- a/src/util/Http.py +++ b/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) diff --git a/src/util/utils.py b/src/util/helper.py similarity index 56% rename from src/util/utils.py rename to src/util/helper.py index 3381d9e6..2d8c4f33 100644 --- a/src/util/utils.py +++ b/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] \ No newline at end of file