Rev932, Skip news event from future, Disable siteSetOwned and setAutodownloadoptional when multiuser plugin enabled, Fix sidebar double click handlers, Log peer sent commands, Send modification to less peer if have enought peers, Close peers if more than 10 per site

This commit is contained in:
HelloZeroNet 2016-03-03 21:12:16 +01:00
parent 5b821c46e5
commit 3f6f273fb1
7 changed files with 78 additions and 28 deletions

View file

@ -1,5 +1,5 @@
from Plugin import PluginManager from Plugin import PluginManager
import re import re, time
@PluginManager.registerTo("UiWebsocket") @PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object): class UiWebsocketPlugin(object):
@ -35,6 +35,8 @@ class UiWebsocketPlugin(object):
continue continue
for row in res: for row in res:
row = dict(row) row = dict(row)
if row["date_added"] > time.time() + 60:
continue # Feed item is in the future, skip it
row["site"] = address row["site"] = address
row["feed_name"] = name row["feed_name"] = name
rows.append(row) rows.append(row)

View file

@ -492,12 +492,22 @@ class UiWebsocketPlugin(object):
def actionSiteSetOwned(self, to, owned): def actionSiteSetOwned(self, to, owned):
permissions = self.getPermissions(to) permissions = self.getPermissions(to)
if "Multiuser" in PluginManager.plugin_manager.plugin_names:
self.cmd("notification", ["info", "This function is disabled on this proxy"])
return False
if "ADMIN" not in permissions: if "ADMIN" not in permissions:
return self.response(to, "You don't have permission to run this command") return self.response(to, "You don't have permission to run this command")
self.site.settings["own"] = bool(owned) self.site.settings["own"] = bool(owned)
def actionSiteSetAutodownloadoptional(self, to, owned): def actionSiteSetAutodownloadoptional(self, to, owned):
permissions = self.getPermissions(to) permissions = self.getPermissions(to)
if "Multiuser" in PluginManager.plugin_manager.plugin_names:
self.cmd("notification", ["info", "This function is disabled on this proxy"])
return False
if "ADMIN" not in permissions: if "ADMIN" not in permissions:
return self.response(to, "You don't have permission to run this command") return self.response(to, "You don't have permission to run this command")
self.site.settings["autodownloadoptional"] = bool(owned) self.site.settings["autodownloadoptional"] = bool(owned)

View file

@ -225,31 +225,31 @@ class Sidebar extends Class
), 300 ), 300
# Site limit button # Site limit button
@tag.find("#button-sitelimit").on "click", => @tag.find("#button-sitelimit").off("click").on "click", =>
wrapper.ws.cmd "siteSetLimit", $("#input-sitelimit").val(), => wrapper.ws.cmd "siteSetLimit", $("#input-sitelimit").val(), =>
wrapper.notifications.add "done-sitelimit", "done", "Site storage limit modified!", 5000 wrapper.notifications.add "done-sitelimit", "done", "Site storage limit modified!", 5000
@updateHtmlTag() @updateHtmlTag()
return false return false
# Owned checkbox # Owned checkbox
@tag.find("#checkbox-owned").on "click", => @tag.find("#checkbox-owned").off("click").on "click", =>
wrapper.ws.cmd "siteSetOwned", [@tag.find("#checkbox-owned").is(":checked")] wrapper.ws.cmd "siteSetOwned", [@tag.find("#checkbox-owned").is(":checked")]
# Owned checkbox # Owned checkbox
@tag.find("#checkbox-autodownloadoptional").on "click", => @tag.find("#checkbox-autodownloadoptional").off("click").on "click", =>
wrapper.ws.cmd "siteSetAutodownloadoptional", [@tag.find("#checkbox-autodownloadoptional").is(":checked")] wrapper.ws.cmd "siteSetAutodownloadoptional", [@tag.find("#checkbox-autodownloadoptional").is(":checked")]
# Change identity button # Change identity button
@tag.find("#button-identity").on "click", => @tag.find("#button-identity").off("click").on "click", =>
wrapper.ws.cmd "certSelect" wrapper.ws.cmd "certSelect"
return false return false
# Owned checkbox # Owned checkbox
@tag.find("#checkbox-owned").on "click", => @tag.find("#checkbox-owned").off("click").on "click", =>
wrapper.ws.cmd "siteSetOwned", [@tag.find("#checkbox-owned").is(":checked")] wrapper.ws.cmd "siteSetOwned", [@tag.find("#checkbox-owned").is(":checked")]
# Save settings # Save settings
@tag.find("#button-settings").on "click", => @tag.find("#button-settings").off("click").on "click", =>
wrapper.ws.cmd "fileGet", "content.json", (res) => wrapper.ws.cmd "fileGet", "content.json", (res) =>
data = JSON.parse(res) data = JSON.parse(res)
data["title"] = $("#settings-title").val() data["title"] = $("#settings-title").val()
@ -264,7 +264,7 @@ class Sidebar extends Class
return false return false
# Sign content.json # Sign content.json
@tag.find("#button-sign").on "click", => @tag.find("#button-sign").off("click").on "click", =>
inner_path = @tag.find("#select-contents").val() inner_path = @tag.find("#select-contents").val()
if wrapper.site_info.privatekey if wrapper.site_info.privatekey
@ -282,7 +282,7 @@ class Sidebar extends Class
return false return false
# Publish content.json # Publish content.json
@tag.find("#button-publish").on "click", => @tag.find("#button-publish").off("click").on "click", =>
inner_path = @tag.find("#select-contents").val() inner_path = @tag.find("#select-contents").val()
@tag.find("#button-publish").addClass "loading" @tag.find("#button-publish").addClass "loading"
wrapper.ws.cmd "sitePublish", {"inner_path": inner_path, "sign": false}, => wrapper.ws.cmd "sitePublish", {"inner_path": inner_path, "sign": false}, =>

View file

@ -404,7 +404,7 @@ window.initScrollable = function () {
}), 300); }), 300);
}; };
})(this)); })(this));
this.tag.find("#button-sitelimit").on("click", (function(_this) { this.tag.find("#button-sitelimit").off("click").on("click", (function(_this) {
return function() { return function() {
wrapper.ws.cmd("siteSetLimit", $("#input-sitelimit").val(), function() { wrapper.ws.cmd("siteSetLimit", $("#input-sitelimit").val(), function() {
wrapper.notifications.add("done-sitelimit", "done", "Site storage limit modified!", 5000); wrapper.notifications.add("done-sitelimit", "done", "Site storage limit modified!", 5000);
@ -413,28 +413,28 @@ window.initScrollable = function () {
return false; return false;
}; };
})(this)); })(this));
this.tag.find("#checkbox-owned").on("click", (function(_this) { this.tag.find("#checkbox-owned").off("click").on("click", (function(_this) {
return function() { return function() {
return wrapper.ws.cmd("siteSetOwned", [_this.tag.find("#checkbox-owned").is(":checked")]); return wrapper.ws.cmd("siteSetOwned", [_this.tag.find("#checkbox-owned").is(":checked")]);
}; };
})(this)); })(this));
this.tag.find("#checkbox-autodownloadoptional").on("click", (function(_this) { this.tag.find("#checkbox-autodownloadoptional").off("click").on("click", (function(_this) {
return function() { return function() {
return wrapper.ws.cmd("siteSetAutodownloadoptional", [_this.tag.find("#checkbox-autodownloadoptional").is(":checked")]); return wrapper.ws.cmd("siteSetAutodownloadoptional", [_this.tag.find("#checkbox-autodownloadoptional").is(":checked")]);
}; };
})(this)); })(this));
this.tag.find("#button-identity").on("click", (function(_this) { this.tag.find("#button-identity").off("click").on("click", (function(_this) {
return function() { return function() {
wrapper.ws.cmd("certSelect"); wrapper.ws.cmd("certSelect");
return false; return false;
}; };
})(this)); })(this));
this.tag.find("#checkbox-owned").on("click", (function(_this) { this.tag.find("#checkbox-owned").off("click").on("click", (function(_this) {
return function() { return function() {
return wrapper.ws.cmd("siteSetOwned", [_this.tag.find("#checkbox-owned").is(":checked")]); return wrapper.ws.cmd("siteSetOwned", [_this.tag.find("#checkbox-owned").is(":checked")]);
}; };
})(this)); })(this));
this.tag.find("#button-settings").on("click", (function(_this) { this.tag.find("#button-settings").off("click").on("click", (function(_this) {
return function() { return function() {
wrapper.ws.cmd("fileGet", "content.json", function(res) { wrapper.ws.cmd("fileGet", "content.json", function(res) {
var data, json_raw; var data, json_raw;
@ -454,7 +454,7 @@ window.initScrollable = function () {
return false; return false;
}; };
})(this)); })(this));
this.tag.find("#button-sign").on("click", (function(_this) { this.tag.find("#button-sign").off("click").on("click", (function(_this) {
return function() { return function() {
var inner_path; var inner_path;
inner_path = _this.tag.find("#select-contents").val(); inner_path = _this.tag.find("#select-contents").val();
@ -474,7 +474,7 @@ window.initScrollable = function () {
return false; return false;
}; };
})(this)); })(this));
this.tag.find("#button-publish").on("click", (function(_this) { this.tag.find("#button-publish").off("click").on("click", (function(_this) {
return function() { return function() {
var inner_path; var inner_path;
inner_path = _this.tag.find("#select-contents").val(); inner_path = _this.tag.find("#select-contents").val();

View file

@ -8,7 +8,7 @@ class Config(object):
def __init__(self, argv): def __init__(self, argv):
self.version = "0.3.6" self.version = "0.3.6"
self.rev = 915 self.rev = 932
self.argv = argv self.argv = argv
self.action = None self.action = None
self.config_file = "zeronet.conf" self.config_file = "zeronet.conf"
@ -133,6 +133,7 @@ class Config(object):
self.parser.add_argument('--homepage', help='Web interface Homepage', default='1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D', self.parser.add_argument('--homepage', help='Web interface Homepage', default='1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D',
metavar='address') metavar='address')
self.parser.add_argument('--size_limit', help='Default site size limit in MB', default=10, metavar='size') self.parser.add_argument('--size_limit', help='Default site size limit in MB', default=10, metavar='size')
self.parser.add_argument('--connected_limit', help='Max connected peer per site', default=15, metavar='connected_limit')
self.parser.add_argument('--fileserver_ip', help='FileServer bind address', default="*", metavar='ip') self.parser.add_argument('--fileserver_ip', help='FileServer bind address', default="*", metavar='ip')
self.parser.add_argument('--fileserver_port', help='FileServer bind port', default=15441, type=int, metavar='port') self.parser.add_argument('--fileserver_port', help='FileServer bind port', default=15441, type=int, metavar='port')

View file

@ -107,6 +107,9 @@ class Peer(object):
self.onConnectionError() self.onConnectionError()
return None # Connection failed return None # Connection failed
if config.debug:
self.log("Send request: %s %s" % (params.get("site", ""), cmd))
for retry in range(1, 4): # Retry 3 times for retry in range(1, 4): # Retry 3 times
try: try:
res = self.connection.request(cmd, params, stream_to) res = self.connection.request(cmd, params, stream_to)

View file

@ -345,7 +345,7 @@ class Site(object):
if result and "ok" in result: if result and "ok" in result:
published.append(peer) published.append(peer)
self.log.info("[OK] %s: %s" % (peer.key, result["ok"])) self.log.info("[OK] %s: %s %s/%s" % (peer.key, result["ok"], len(published), limit))
else: else:
if result == {"exception": "Timeout"}: if result == {"exception": "Timeout"}:
peer.onConnectionError() peer.onConnectionError()
@ -353,21 +353,29 @@ class Site(object):
# Update content.json on peers # Update content.json on peers
@util.Noparallel() @util.Noparallel()
def publish(self, limit=5, inner_path="content.json"): def publish(self, limit="default", inner_path="content.json"):
published = [] # Successfully published (Peer) published = [] # Successfully published (Peer)
publishers = [] # Publisher threads publishers = [] # Publisher threads
if not self.peers: if not self.peers:
self.announce() self.announce()
threads = 5
if limit == "default":
if len(self.peers) > 50:
limit = 3
threads = 3
else:
limit = 5
connected_peers = self.getConnectedPeers() connected_peers = self.getConnectedPeers()
if len(connected_peers) > limit * 2: # Publish to already connected peers if possible if len(connected_peers) > limit * 2: # Publish to already connected peers if possible
peers = connected_peers peers = connected_peers
else: else:
peers = self.peers.values() peers = self.peers.values()
self.log.info("Publishing to %s/%s peers (connected: %s)..." % ( self.log.info("Publishing %s to %s/%s peers (connected: %s)..." % (
min(len(self.peers), limit), len(self.peers), len(connected_peers) inner_path, limit, len(self.peers), len(connected_peers)
)) ))
if not peers: if not peers:
@ -375,7 +383,7 @@ class Site(object):
random.shuffle(peers) random.shuffle(peers)
event_done = gevent.event.AsyncResult() event_done = gevent.event.AsyncResult()
for i in range(min(len(self.peers), limit, 5)): # Max 5 thread for i in range(min(len(self.peers), limit, threads)):
publisher = gevent.spawn(self.publisher, inner_path, peers, published, limit, event_done) publisher = gevent.spawn(self.publisher, inner_path, peers, published, limit, event_done)
publishers.append(publisher) publishers.append(publisher)
@ -392,12 +400,12 @@ class Site(object):
] # Every connected passive peer that we not published to ] # Every connected passive peer that we not published to
self.log.info( self.log.info(
"Successfuly published to %s peers, publishing to %s more passive peers" % "Successfuly %s published to %s peers, publishing to %s more passive peers" % (
(len(published), len(passive_peers)) inner_path, len(published), len(passive_peers)
) ))
for peer in passive_peers: for peer in passive_peers:
gevent.spawn(self.publisher, inner_path, passive_peers, published, limit=10) gevent.spawn(self.publisher, inner_path, passive_peers, published, limit=limit+3)
# Send my hashfield to every connected peer if changed # Send my hashfield to every connected peer if changed
gevent.spawn(self.sendMyHashfield, 100) gevent.spawn(self.sendMyHashfield, 100)
@ -765,11 +773,13 @@ class Site(object):
def getConnectedPeers(self): def getConnectedPeers(self):
return [peer for peer in self.peers.values() if peer.connection and peer.connection.connected] return [peer for peer in self.peers.values() if peer.connection and peer.connection.connected]
# Cleanup probably dead peers # Cleanup probably dead peers and close connection if too much
def cleanupPeers(self): def cleanupPeers(self):
peers = self.peers.values() peers = self.peers.values()
if len(peers) < 20: if len(peers) < 20:
return False return False
# Cleanup old peers
removed = 0 removed = 0
for peer in peers: for peer in peers:
@ -786,6 +796,30 @@ class Site(object):
if removed: if removed:
self.log.debug("Cleanup peers result: Removed %s, left: %s" % (removed, len(self.peers))) self.log.debug("Cleanup peers result: Removed %s, left: %s" % (removed, len(self.peers)))
# Close peers if too much
closed = 0
connected_peers = self.getConnectedPeers()
need_to_close = len(connected_peers) - config.connected_limit
# First try to remove active peers
if need_to_close > 0:
for peer in connected_peers:
if not peer.key.endswith(":0"): # Connectable peer
peer.remove()
closed += 1
if closed >= need_to_close:
break
# Also remove passive peers if still more than we need
if closed < need_to_close:
for peer in connected_peers:
peer.remove()
closed += 1
if closed >= need_to_close:
break
if need_to_close > 0:
self.log.debug("Connected: %s, Need to close: %s, Closed: %s" % (len(connected_peers), need_to_close, closed))
# Send hashfield to peers # Send hashfield to peers
def sendMyHashfield(self, limit=3): def sendMyHashfield(self, limit=3):
if not self.content_manager.hashfield: # No optional files if not self.content_manager.hashfield: # No optional files