Merge branch 'master' of github.com:HelloZeroNet/ZeroNet

This commit is contained in:
sirMackk 2015-02-22 11:40:44 -05:00
commit de31a518dd
15 changed files with 274 additions and 85 deletions

View file

@ -3,7 +3,7 @@ import ConfigParser
class Config(object):
def __init__(self):
self.version = "0.2.1"
self.version = "0.2.3"
self.parser = self.createArguments()
argv = sys.argv[:] # Copy command line arguments
argv = self.parseConfig(argv) # Add arguments from config file
@ -19,7 +19,7 @@ class Config(object):
def createArguments(self):
# Platform specific
if sys.platform.startswith("win"):
upnpc = "tools\\upnpc\\upnpc-static.exe"
upnpc = "tools\\upnpc\\upnpc-shared.exe"
coffeescript = "type %s | tools\\coffee\\coffee.cmd"
else:
upnpc = None

View file

@ -18,6 +18,7 @@ class FileServer:
else:
self.port_opened = None # Is file server opened on router
self.sites = SiteManager.list()
self.running = True
# Handle request to fileserver
@ -168,17 +169,26 @@ class FileServer:
if check_sites: # Open port, Update sites, Check files integrity
gevent.spawn(self.checkSites)
gevent.spawn(self.announceSites)
gevent.spawn(self.wakeupWatcher)
thread_announce_sites = gevent.spawn(self.announceSites)
thread_wakeup_watcher = gevent.spawn(self.wakeupWatcher)
while True:
while self.running:
try:
ret = {}
req = msgpack.unpackb(socket.recv())
self.handleRequest(req)
except Exception, err:
self.log.error(err)
self.socket.send(msgpack.packb({"error": "%s" % Debug.formatException(err)}, use_bin_type=True))
if self.running: self.socket.send(msgpack.packb({"error": "%s" % Debug.formatException(err)}, use_bin_type=True))
if config.debug: # Raise exception
import sys
sys.excepthook(*sys.exc_info())
sys.modules["src.main"].DebugHook.handleError()
thread_wakeup_watcher.kill(exception=Debug.Notify("Stopping FileServer"))
thread_announce_sites.kill(exception=Debug.Notify("Stopping FileServer"))
self.log.debug("Stopped.")
def stop(self):
self.running = False
self.socket.close()

View file

@ -194,9 +194,6 @@ class Site:
self.log.info("[OK] %s: %s" % (peer.key, result["ok"]))
else:
self.log.info("[ERROR] %s: %s" % (peer.key, result))
# Update content.json on peers

View file

@ -11,20 +11,25 @@ from Debug import Debug
# Skip websocket handler if not necessary
class UiWSGIHandler(WSGIHandler):
def __init__(self, *args, **kwargs):
self.server = args[2]
super(UiWSGIHandler, self).__init__(*args, **kwargs)
self.ws_handler = WebSocketHandler(*args, **kwargs)
self.args = args
self.kwargs = kwargs
def run_application(self):
self.server.sockets[self.client_address] = self.socket
if "HTTP_UPGRADE" in self.environ: # Websocket request
self.ws_handler.__dict__ = self.__dict__ # Match class variables
self.ws_handler.run_application()
ws_handler = WebSocketHandler(*self.args, **self.kwargs)
ws_handler.__dict__ = self.__dict__ # Match class variables
ws_handler.run_application()
else: # Standard HTTP request
#print self.application.__class__.__name__
try:
return super(UiWSGIHandler, self).run_application()
except Exception, err:
logging.debug("UiWSGIHandler error: %s" % err)
del self.server.sockets[self.client_address]
class UiServer:
@ -89,4 +94,27 @@ class UiServer:
browser = webbrowser.get(config.open_browser)
browser.open("http://%s:%s" % (config.ui_ip, config.ui_port), new=2)
WSGIServer((self.ip, self.port), handler, handler_class=UiWSGIHandler, log=self.log).serve_forever()
self.server = WSGIServer((self.ip, self.port), handler, handler_class=UiWSGIHandler, log=self.log)
self.server.sockets = {}
self.server.serve_forever()
self.log.debug("Stopped.")
def stop(self):
# Close WS sockets
for client in self.server.clients.values():
client.ws.close()
# Close http sockets
sock_closed = 0
for sock in self.server.sockets.values():
try:
sock._sock.close()
sock.close()
sock_closed += 1
except Exception, err:
pass
self.log.debug("Socket closed: %s" % sock_closed)
self.server.socket.close()
self.server.stop()
time.sleep(1)

View file

@ -121,6 +121,8 @@ class UiWebsocket:
func = self.actionSiteSetLimit
elif cmd == "channelJoinAllsite" and "ADMIN" in permissions:
func = self.actionChannelJoinAllsite
elif cmd == "serverUpdate" and "ADMIN" in permissions:
func = self.actionServerUpdate
# Unknown command
else:
self.response(req["id"], "Unknown command: %s" % cmd)
@ -361,3 +363,12 @@ class UiWebsocket:
self.site.saveSettings()
self.response(to, "Site size limit changed to %sMB" % size_limit)
self.site.download()
def actionServerUpdate(self, to):
import sys
self.cmd("updating")
sys.modules["src.main"].update_after_shutdown = True
sys.modules["src.main"].file_server.stop()
sys.modules["src.main"].ui_server.stop()

View file

@ -46,6 +46,9 @@ class Wrapper
@sendInner message # Pass to inner frame
if message.params.address == window.address # Current page
@setSiteInfo message.params
else if cmd == "updating" # Close connection
@ws.ws.close()
@ws.onCloseWebsocket(null, 4000)
else
@sendInner message # Pass message to inner frame
@ -69,6 +72,10 @@ class Wrapper
@actionWrapperPrompt(message)
else if cmd == "wrapperSetViewport" # Set the viewport
@actionSetViewport(message)
else if cmd == "wrapperGetLocalStorage"
@actionGetLocalStorage(message)
else if cmd == "wrapperSetLocalStorage"
@actionSetLocalStorage(message)
else # Send to websocket
if message.id < 1000000
@ws.send(message) # Pass message to websocket
@ -126,6 +133,16 @@ class Wrapper
$('<meta name="viewport" id="viewport">').attr("content", @toHtmlSafe message.params).appendTo("head")
actionGetLocalStorage: (message) ->
data = localStorage.getItem "site.#{window.address}"
if data then data = JSON.parse(data)
@sendInner {"cmd": "response", "to": message.id, "result": data}
actionSetLocalStorage: (message) ->
back = localStorage.setItem "site.#{window.address}", JSON.stringify(message.params)
# EOF actions
@ -152,7 +169,7 @@ class Wrapper
@wrapperWsInited = false
setTimeout (=> # Wait a bit, maybe its page closing
@sendInner {"cmd": "wrapperClosedWebsocket"} # Send to inner frame
if e.code == 1000 # Server error please reload page
if e and e.code == 1000 and e.wasClean == false # Server error please reload page
@ws_error = @notifications.add("connection", "error", "UiServer Websocket error, please reload the page.")
else if not @ws_error
@ws_error = @notifications.add("connection", "error", "Connection with <b>UiServer Websocket</b> was lost. Reconnecting...")

View file

@ -120,17 +120,20 @@
}
};
ZeroWebsocket.prototype.onCloseWebsocket = function(e) {
ZeroWebsocket.prototype.onCloseWebsocket = function(e, reconnect) {
if (reconnect == null) {
reconnect = 10000;
}
this.log("Closed", e);
if (e.code === 1000) {
this.log("Server error, please reload the page");
if (e && e.code === 1000 && e.wasClean === false) {
this.log("Server error, please reload the page", e.wasClean);
} else {
setTimeout(((function(_this) {
return function() {
_this.log("Reconnecting...");
return _this.connect();
};
})(this)), 10000);
})(this)), reconnect);
}
if (this.onClose != null) {
return this.onClose(e);
@ -780,6 +783,9 @@ jQuery.extend( jQuery.easing,
if (message.params.address === window.address) {
return this.setSiteInfo(message.params);
}
} else if (cmd === "updating") {
this.ws.ws.close();
return this.ws.onCloseWebsocket(null, 4000);
} else {
return this.sendInner(message);
}
@ -807,6 +813,10 @@ jQuery.extend( jQuery.easing,
return this.actionWrapperPrompt(message);
} else if (cmd === "wrapperSetViewport") {
return this.actionSetViewport(message);
} else if (cmd === "wrapperGetLocalStorage") {
return this.actionGetLocalStorage(message);
} else if (cmd === "wrapperSetLocalStorage") {
return this.actionSetLocalStorage(message);
} else {
if (message.id < 1000000) {
return this.ws.send(message);
@ -891,6 +901,24 @@ jQuery.extend( jQuery.easing,
}
};
Wrapper.prototype.actionGetLocalStorage = function(message) {
var data;
data = localStorage.getItem("site." + window.address);
if (data) {
data = JSON.parse(data);
}
return this.sendInner({
"cmd": "response",
"to": message.id,
"result": data
});
};
Wrapper.prototype.actionSetLocalStorage = function(message) {
var back;
return back = localStorage.setItem("site." + window.address, JSON.stringify(message.params));
};
Wrapper.prototype.onOpenWebsocket = function(e) {
this.ws.cmd("channelJoin", {
"channel": "siteChanged"
@ -925,7 +953,7 @@ jQuery.extend( jQuery.easing,
_this.sendInner({
"cmd": "wrapperClosedWebsocket"
});
if (e.code === 1000) {
if (e && e.code === 1000 && e.wasClean === false) {
return _this.ws_error = _this.notifications.add("connection", "error", "UiServer Websocket error, please reload the page.");
} else if (!_this.ws_error) {
return _this.ws_error = _this.notifications.add("connection", "error", "Connection with <b>UiServer Websocket</b> was lost. Reconnecting...");

View file

@ -66,15 +66,15 @@ class ZeroWebsocket
if @onError? then @onError(e)
onCloseWebsocket: (e) =>
onCloseWebsocket: (e, reconnect=10000) =>
@log "Closed", e
if e.code == 1000
@log "Server error, please reload the page"
if e and e.code == 1000 and e.wasClean == false
@log "Server error, please reload the page", e.wasClean
else # Connection error
setTimeout (=>
@log "Reconnecting..."
@connect()
), 10000
), reconnect
if @onClose? then @onClose(e)

View file

@ -25,9 +25,9 @@ class User:
self.log.debug("Saved")
# Get BIP32 address from site address
# Return: BIP32 auth address
def getAuthAddress(self, address):
# Get user site data
# Return: {"auth_address": "xxx", "auth_privatekey": "xxx"}
def getSiteData(self, address):
if not address in self.sites: # Genreate new BIP32 child key based on site address
s = time.time()
address_id = int(address.encode("hex"), 16) # Convert site address to int
@ -38,12 +38,17 @@ class User:
}
self.save()
self.log.debug("Added new site: %s in %.3fs" % (address, time.time()-s))
return self.sites[address]
return self.sites[address]["auth_address"]
# Get BIP32 address from site address
# Return: BIP32 auth address
def getAuthAddress(self, address):
return self.getSiteData(address)["auth_address"]
def getAuthPrivatekey(self, address):
return self.sites[address]["auth_privatekey"]
return self.getSiteData(address)["auth_privatekey"]
@ -51,3 +56,4 @@ class User:
def setData(self, data):
for key, val in data.items():
setattr(self, key, val)

View file

@ -60,6 +60,6 @@ def getCurrent():
def reload():
import imp
global users, User
users.clear() # Remove all items
User = imp.load_source("User", "src/User/User.py").User # Reload source
users.clear() # Remove all items
load()

View file

@ -1,5 +1,5 @@
from Worker import Worker
import gevent, time, logging
import gevent, time, logging, random
MAX_WORKERS = 10
@ -87,10 +87,12 @@ class WorkerManager:
def startWorkers(self, peers=None):
if len(self.workers) >= MAX_WORKERS and not peers: return False # Workers number already maxed
if not self.tasks: return False # No task for workers
for key, peer in self.site.peers.iteritems(): # One worker for every peer
peers = self.site.peers.values()
random.shuffle(peers)
for peer in peers: # One worker for every peer
if peers and peer not in peers: continue # If peers definied and peer not valid
worker = self.addWorker(peer)
if worker: self.log.debug("Added worker: %s, workers: %s/%s" % (key, len(self.workers), MAX_WORKERS))
if worker: self.log.debug("Added worker: %s, workers: %s/%s" % (peer.key, len(self.workers), MAX_WORKERS))
# Stop all worker

View file

@ -1,4 +1,5 @@
import os, sys
update_after_shutdown = False
sys.path.insert(0, os.path.dirname(__file__)) # Imports relative to main.py
# Create necessary files and dirs
@ -43,7 +44,6 @@ else:
import gevent
import time
logging.debug("Starting... %s" % config)
# Starts here when running zeronet.py
@ -56,6 +56,7 @@ def start():
# Start serving UiServer and PeerServer
def main():
global ui_server, file_server
from File import FileServer
from Ui import UiServer
logging.info("Creating UiServer....")