diff --git a/README.md b/README.md index d9ce9db8..c3cef26b 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,18 @@ Decentralized websites using Bitcoin crypto and the BitTorrent network unavailable. +## Features + * Real-time updated sites + * Namecoin .bit domains support + * Easy to setup: unpack & run + * Password-less [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) + based authorization: Your account is protected by same cryptography as your Bitcoin wallet + * Built-in SQL server with P2P data synchronization: Allows easier site development and faster page load times + * Tor network support + * Automatic, uPnP port opening + * Plugin for multiuser (openproxy) support + + ## How does it work? * After starting `zeronet.py` you will be able to visit zeronet sites using @@ -30,16 +42,6 @@ Decentralized websites using Bitcoin crypto and the BitTorrent network signature), they download the modified files and publish the new content to other peers. -## Features - * Real-time updated sites - * Namecoin .bit domains support - * Easy to setup: unpack & run - * Password-less [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) - based authorization: Your account is protected by same cryptography as your Bitcoin wallet - * Built-in SQL server with P2P data synchronization: Allows easier site development and faster page load times - * Tor network support - * Automatic, uPnP port opening - * Plugin for multiuser (openproxy) support ## Screenshots diff --git a/plugins/Stats/StatsPlugin.py b/plugins/Stats/StatsPlugin.py index 7aa44ab5..1e36936c 100644 --- a/plugins/Stats/StatsPlugin.py +++ b/plugins/Stats/StatsPlugin.py @@ -129,7 +129,7 @@ class UiRequestPlugin(object): obj_count[obj_type][0] += 1 # Count obj_count[obj_type][1] += float(sys.getsizeof(obj))/1024 # Size - yield "

Objects in memory (total: %s, %.2fkb):
" % (len(obj_count), sum([stat[1] for stat in obj_count.values()])) + yield "

Objects in memory (types: %s, total: %s, %.2fkb):
" % (len(obj_count), sum([stat[0] for stat in obj_count.values()]), sum([stat[1] for stat in obj_count.values()])) for obj, stat in sorted(obj_count.items(), key=lambda x: x[1][0], reverse=True): # Sorted by count yield " - %.1fkb = %s x %s
" % (stat[1], stat[0], obj, cgi.escape(obj)) @@ -177,10 +177,18 @@ class UiRequestPlugin(object): objs = [obj for obj in gc.get_objects() if isinstance(obj, UiRequest)] - yield "
UiRequest (%s):
" % len(objs) + yield "
UiRequests (%s):
" % len(objs) for obj in objs: yield " - %.1fkb: %s
" % (self.getObjSize(obj, hpy), cgi.escape(repr(obj))) + + from Peer import Peer + objs = [obj for obj in gc.get_objects() if isinstance(obj, Peer)] + yield "
Peers (%s):
" % len(objs) + for obj in objs: + yield " - %.1fkb: %s
" % (self.getObjSize(obj, hpy), cgi.escape(repr(obj))) + + objs = [(key, val) for key, val in sys.modules.iteritems() if val is not None] objs.sort() yield "
Modules (%s):
" % len(objs) @@ -212,7 +220,7 @@ class UiRequestPlugin(object): if obj_type != type_filter: continue refs = [ref for ref in gc.get_referrers(obj) if hasattr(ref, "__class__") and ref.__class__.__name__ not in ["list", "dict", "function", "type", "frame", "WeakSet", "tuple"]] if not refs: continue - yield "%.1fkb %s... " % (float(sys.getsizeof(obj))/1024, cgi.escape(str(obj)[0:100].ljust(100)) ) + yield "%.1fkb %s... " % (float(sys.getsizeof(obj))/1024, cgi.escape(str(obj)), cgi.escape(str(obj)[0:100].ljust(100)) ) for ref in refs: yield " [" if "object at" in str(ref) or len(str(ref)) > 100: diff --git a/src/Config.py b/src/Config.py index d4eb20df..43bade8a 100644 --- a/src/Config.py +++ b/src/Config.py @@ -4,7 +4,7 @@ import ConfigParser class Config(object): def __init__(self): self.version = "0.2.9" - self.rev = 110 + self.rev = 115 self.parser = self.createArguments() argv = sys.argv[:] # Copy command line arguments argv = self.parseConfig(argv) # Add arguments from config file diff --git a/src/Ui/UiRequest.py b/src/Ui/UiRequest.py index ed45096f..fe6c3ff3 100644 --- a/src/Ui/UiRequest.py +++ b/src/Ui/UiRequest.py @@ -69,6 +69,10 @@ class UiRequest(object): return self.env["PATH_INFO"].startswith("http://") + def isAjaxRequest(self): + return self.env.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest" + + # Get mime by filename def getContentType(self, file_name): content_type = mimetypes.guess_type(file_name)[0] @@ -104,8 +108,13 @@ class UiRequest(object): headers = [] headers.append(("Version", "HTTP/1.1")) headers.append(("Access-Control-Allow-Origin", "*")) # Allow json access - headers.append(("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")) # Allow json access - headers.append(("Cache-Control", "no-cache, no-store, private, must-revalidate, max-age=0")) # No caching at all + if self.env["REQUEST_METHOD"] == "OPTIONS": + headers.append(("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")) # Allow json access + + if (self.env["REQUEST_METHOD"] == "OPTIONS" or not self.isAjaxRequest()) and status == 200 and (content_type == "text/css" or content_type == "application/javascript" or self.env["REQUEST_METHOD"] == "OPTIONS" or content_type.startswith("image")): # Cache Css, Js, Image files for 10min + headers.append(("Cache-Control", "public, max-age=600")) # Cache 10 min + else: # Images, Css, Js + headers.append(("Cache-Control", "no-cache, no-store, private, must-revalidate, max-age=0")) # No caching at all #headers.append(("Cache-Control", "public, max-age=604800")) # Cache 1 week headers.append(("Content-Type", content_type)) for extra_header in extra_headers: @@ -190,6 +199,7 @@ class UiRequest(object): return self.render("src/Ui/template/wrapper.html", server_url=server_url, inner_path=inner_path, + file_inner_path=file_inner_path, address=address, title=title, body_style=body_style, diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py index 0ea13b4d..7e874d55 100644 --- a/src/Ui/UiWebsocket.py +++ b/src/Ui/UiWebsocket.py @@ -199,8 +199,11 @@ class UiWebsocket(object): # Send site details - def actionSiteInfo(self, to): + def actionSiteInfo(self, to, file_status = None): ret = self.formatSiteInfo(self.site) + if file_status: # Client queries file status + if self.site.storage.isFile(file_status): # File exits, add event done + ret["event"] = ("file_done", file_status) self.response(to, ret) diff --git a/src/Ui/media/Loading.coffee b/src/Ui/media/Loading.coffee index 5bd812ac..25cce3eb 100644 --- a/src/Ui/media/Loading.coffee +++ b/src/Ui/media/Loading.coffee @@ -31,6 +31,7 @@ class Loading # We dont need loadingscreen anymore hideScreen: -> + console.log "hideScreen" if not $(".loadingscreen").hasClass("done") # Only if its not animating already if @screen_visible # Hide with animate $(".loadingscreen").addClass("done").removeLater(2000) diff --git a/src/Ui/media/Wrapper.coffee b/src/Ui/media/Wrapper.coffee index da6db5bc..cfdfdd86 100644 --- a/src/Ui/media/Wrapper.coffee +++ b/src/Ui/media/Wrapper.coffee @@ -223,7 +223,12 @@ class Wrapper # Get site info from UiServer reloadSiteInfo: -> - @ws.cmd "siteInfo", {}, (site_info) => + if @loading.screen_visible # Loading screen visible + params = {"file_status": window.file_inner_path} # Query the current required file status + else + params = {} + + @ws.cmd "siteInfo", params, (site_info) => @address = site_info.address @setSiteInfo site_info @@ -244,12 +249,12 @@ class Wrapper # File finished downloading else if site_info.event[0] == "file_done" @loading.printLine("#{site_info.event[1]} downloaded") - if site_info.event[1] == window.inner_path # File downloaded we currently on + if site_info.event[1] == window.file_inner_path # File downloaded we currently on @loading.hideScreen() if not @site_info then @reloadSiteInfo() if site_info.content window.document.title = site_info.content.title+" - ZeroNet" - @log "Setting title to", window.document.title + @log "Required file done, setting title to", window.document.title if not $(".loadingscreen").length # Loading screen already removed (loaded +2sec) @notifications.add("modified", "info", "New version of this page has just released.
Reload to see the modified content.") # File failed downloading @@ -304,7 +309,7 @@ class Wrapper @loading.printLine res @inner_loaded = false # Inner frame not loaded, just a 404 page displayed if reload - $("iframe").attr "src", $("iframe").attr("src")+"?"+(+new Date) # Reload iframe + $("iframe").attr "src", $("iframe").attr("src")+"&"+(+new Date) # Reload iframe return false diff --git a/src/Ui/media/all.js b/src/Ui/media/all.js index 53374939..0dd62f37 100644 --- a/src/Ui/media/all.js +++ b/src/Ui/media/all.js @@ -506,6 +506,7 @@ jQuery.extend( jQuery.easing, }; Loading.prototype.hideScreen = function() { + console.log("hideScreen"); if (!$(".loadingscreen").hasClass("done")) { if (this.screen_visible) { $(".loadingscreen").addClass("done").removeLater(2000); @@ -1047,7 +1048,15 @@ jQuery.extend( jQuery.easing, }; Wrapper.prototype.reloadSiteInfo = function() { - return this.ws.cmd("siteInfo", {}, (function(_this) { + var params; + if (this.loading.screen_visible) { + params = { + "file_status": window.file_inner_path + }; + } else { + params = {}; + } + return this.ws.cmd("siteInfo", params, (function(_this) { return function(site_info) { _this.address = site_info.address; _this.setSiteInfo(site_info); @@ -1068,14 +1077,14 @@ jQuery.extend( jQuery.easing, this.loading.printLine(site_info.bad_files + " files needs to be downloaded"); } else if (site_info.event[0] === "file_done") { this.loading.printLine(site_info.event[1] + " downloaded"); - if (site_info.event[1] === window.inner_path) { + if (site_info.event[1] === window.file_inner_path) { this.loading.hideScreen(); if (!this.site_info) { this.reloadSiteInfo(); } if (site_info.content) { window.document.title = site_info.content.title + " - ZeroNet"; - this.log("Setting title to", window.document.title); + this.log("Required file done, setting title to", window.document.title); } if (!$(".loadingscreen").length) { this.notifications.add("modified", "info", "New version of this page has just released.
Reload to see the modified content."); @@ -1147,7 +1156,7 @@ jQuery.extend( jQuery.easing, _this.loading.printLine(res); _this.inner_loaded = false; if (reload) { - return $("iframe").attr("src", $("iframe").attr("src") + "?" + (+(new Date))); + return $("iframe").attr("src", $("iframe").attr("src") + "&" + (+(new Date))); } }; })(this)); diff --git a/src/Ui/template/wrapper.html b/src/Ui/template/wrapper.html index cc20d1fd..3a888067 100644 --- a/src/Ui/template/wrapper.html +++ b/src/Ui/template/wrapper.html @@ -45,7 +45,7 @@ - +