Rev949, Newsfeed allows items 2min from future, Switch sidebar content.json list to input for faster opening, Promise based sidebar rendering to make it more reliable on slow connections, RateLimit sidebar globe updating, Some PEP8 formatting
This commit is contained in:
parent
bfdccb809c
commit
2901f1e1ba
7 changed files with 77 additions and 27 deletions
|
@ -35,7 +35,7 @@ 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:
|
if row["date_added"] > time.time() + 120:
|
||||||
continue # Feed item is in the future, skip it
|
continue # Feed item is in the future, skip it
|
||||||
row["site"] = address
|
row["site"] = address
|
||||||
row["feed_name"] = name
|
row["feed_name"] = name
|
||||||
|
|
|
@ -148,8 +148,11 @@ class UiWebsocketPlugin(object):
|
||||||
percent = 0
|
percent = 0
|
||||||
else:
|
else:
|
||||||
percent = 100 * (float(size) / size_total)
|
percent = 100 * (float(size) / size_total)
|
||||||
percent = math.floor(percent*100)/100 # Floor to 2 digits
|
percent = math.floor(percent * 100) / 100 # Floor to 2 digits
|
||||||
body.append(u"""<li style='width: %.2f%%' class='%s back-%s' title="%s"></li>""" % (percent, extension, color, extension))
|
body.append(
|
||||||
|
u"""<li style='width: %.2f%%' class='%s back-%s' title="%s"></li>""" %
|
||||||
|
(percent, extension, color, extension)
|
||||||
|
)
|
||||||
|
|
||||||
# Legend
|
# Legend
|
||||||
body.append("</ul><ul class='graph-legend'>")
|
body.append("</ul><ul class='graph-legend'>")
|
||||||
|
@ -334,15 +337,7 @@ class UiWebsocketPlugin(object):
|
||||||
body.append("""
|
body.append("""
|
||||||
<li>
|
<li>
|
||||||
<label>Content publishing</label>
|
<label>Content publishing</label>
|
||||||
<select id='select-contents'>
|
<input type='text' class='text' value="content.json" id='input-contents' style='width: 201px'/>
|
||||||
""")
|
|
||||||
|
|
||||||
for inner_path in sorted(site.content_manager.contents.keys()):
|
|
||||||
body.append(u"<option>%s</option>" % cgi.escape(inner_path, True))
|
|
||||||
|
|
||||||
body.append("""
|
|
||||||
</select>
|
|
||||||
<span class='select-down'>›</span>
|
|
||||||
<a href='#Sign' class='button' id='button-sign'>Sign</a>
|
<a href='#Sign' class='button' id='button-sign'>Sign</a>
|
||||||
<a href='#Publish' class='button' id='button-publish'>Publish</a>
|
<a href='#Publish' class='button' id='button-publish'>Publish</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
14
plugins/Sidebar/media/RateLimit.coffee
Normal file
14
plugins/Sidebar/media/RateLimit.coffee
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
limits = {}
|
||||||
|
call_after_interval = {}
|
||||||
|
window.RateLimit = (interval, fn) ->
|
||||||
|
if not limits[fn]
|
||||||
|
call_after_interval[fn] = false
|
||||||
|
fn() # First call is not delayed
|
||||||
|
limits[fn] = setTimeout (->
|
||||||
|
if call_after_interval[fn]
|
||||||
|
fn()
|
||||||
|
delete limits[fn]
|
||||||
|
delete call_after_interval[fn]
|
||||||
|
), interval
|
||||||
|
else # Called within iterval, delay the call
|
||||||
|
call_after_interval[fn] = true
|
|
@ -114,6 +114,7 @@ class Sidebar extends Class
|
||||||
|
|
||||||
# Create the sidebar html tag
|
# Create the sidebar html tag
|
||||||
createHtmltag: ->
|
createHtmltag: ->
|
||||||
|
@when_loaded = $.Deferred()
|
||||||
if not @container
|
if not @container
|
||||||
@container = $("""
|
@container = $("""
|
||||||
<div class="sidebar-container"><div class="sidebar scrollable"><div class="content-wrapper"><div class="content">
|
<div class="sidebar-container"><div class="sidebar scrollable"><div class="content-wrapper"><div class="content">
|
||||||
|
@ -141,6 +142,7 @@ class Sidebar extends Class
|
||||||
else
|
else
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@when_loaded.resolve()
|
||||||
|
|
||||||
|
|
||||||
animDrag: (e) =>
|
animDrag: (e) =>
|
||||||
|
@ -195,7 +197,8 @@ class Sidebar extends Class
|
||||||
# Opened
|
# Opened
|
||||||
targetx = @width
|
targetx = @width
|
||||||
if not @opened
|
if not @opened
|
||||||
@onOpened()
|
@when_loaded.done =>
|
||||||
|
@onOpened()
|
||||||
@opened = true
|
@opened = true
|
||||||
|
|
||||||
# Revent sidebar transitions
|
# Revent sidebar transitions
|
||||||
|
@ -265,7 +268,7 @@ class Sidebar extends Class
|
||||||
|
|
||||||
# Sign content.json
|
# Sign content.json
|
||||||
@tag.find("#button-sign").off("click").on "click", =>
|
@tag.find("#button-sign").off("click").on "click", =>
|
||||||
inner_path = @tag.find("#select-contents").val()
|
inner_path = @tag.find("#input-contents").val()
|
||||||
|
|
||||||
if wrapper.site_info.privatekey
|
if wrapper.site_info.privatekey
|
||||||
# Privatekey stored in users.json
|
# Privatekey stored in users.json
|
||||||
|
@ -304,12 +307,14 @@ class Sidebar extends Class
|
||||||
|
|
||||||
|
|
||||||
loadGlobe: =>
|
loadGlobe: =>
|
||||||
|
console.log "loadGlobe", @tag.find(".globe").hasClass("loading")
|
||||||
if @tag.find(".globe").hasClass("loading")
|
if @tag.find(".globe").hasClass("loading")
|
||||||
setTimeout (=>
|
setTimeout (=>
|
||||||
if typeof(DAT) == "undefined" # Globe script not loaded, do it first
|
if typeof(DAT) == "undefined" # Globe script not loaded, do it first
|
||||||
$.getScript("/uimedia/globe/all.js", @displayGlobe)
|
$.getScript("/uimedia/globe/all.js", @displayGlobe)
|
||||||
else
|
else
|
||||||
@displayGlobe()
|
RateLimit 5000, =>
|
||||||
|
@displayGlobe()
|
||||||
), 600
|
), 600
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,36 @@
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- plugins/Sidebar/media/RateLimit.coffee ---- */
|
||||||
|
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var call_after_interval, limits;
|
||||||
|
|
||||||
|
limits = {};
|
||||||
|
|
||||||
|
call_after_interval = {};
|
||||||
|
|
||||||
|
window.RateLimit = function(interval, fn) {
|
||||||
|
if (!limits[fn]) {
|
||||||
|
call_after_interval[fn] = false;
|
||||||
|
fn();
|
||||||
|
return limits[fn] = setTimeout((function() {
|
||||||
|
if (call_after_interval[fn]) {
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
delete limits[fn];
|
||||||
|
return delete call_after_interval[fn];
|
||||||
|
}), interval);
|
||||||
|
} else {
|
||||||
|
return call_after_interval[fn] = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ---- plugins/Sidebar/media/Scrollable.js ---- */
|
/* ---- plugins/Sidebar/media/Scrollable.js ---- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -291,6 +321,7 @@ window.initScrollable = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
Sidebar.prototype.createHtmltag = function() {
|
Sidebar.prototype.createHtmltag = function() {
|
||||||
|
this.when_loaded = $.Deferred();
|
||||||
if (!this.container) {
|
if (!this.container) {
|
||||||
this.container = $("<div class=\"sidebar-container\"><div class=\"sidebar scrollable\"><div class=\"content-wrapper\"><div class=\"content\">\n</div></div></div></div>");
|
this.container = $("<div class=\"sidebar-container\"><div class=\"sidebar scrollable\"><div class=\"content-wrapper\"><div class=\"content\">\n</div></div></div></div>");
|
||||||
this.container.appendTo(document.body);
|
this.container.appendTo(document.body);
|
||||||
|
@ -305,10 +336,10 @@ window.initScrollable = function () {
|
||||||
return function(res) {
|
return function(res) {
|
||||||
if (_this.tag.find(".content").children().length === 0) {
|
if (_this.tag.find(".content").children().length === 0) {
|
||||||
_this.log("Creating content");
|
_this.log("Creating content");
|
||||||
return morphdom(_this.tag.find(".content")[0], '<div class="content">' + res + '</div>');
|
morphdom(_this.tag.find(".content")[0], '<div class="content">' + res + '</div>');
|
||||||
} else {
|
} else {
|
||||||
_this.log("Patching content");
|
_this.log("Patching content");
|
||||||
return morphdom(_this.tag.find(".content")[0], '<div class="content">' + res + '</div>', {
|
morphdom(_this.tag.find(".content")[0], '<div class="content">' + res + '</div>', {
|
||||||
onBeforeMorphEl: function(from_el, to_el) {
|
onBeforeMorphEl: function(from_el, to_el) {
|
||||||
if (from_el.className === "globe") {
|
if (from_el.className === "globe") {
|
||||||
return false;
|
return false;
|
||||||
|
@ -318,6 +349,7 @@ window.initScrollable = function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return _this.when_loaded.resolve();
|
||||||
};
|
};
|
||||||
})(this));
|
})(this));
|
||||||
};
|
};
|
||||||
|
@ -371,7 +403,11 @@ window.initScrollable = function () {
|
||||||
} else {
|
} else {
|
||||||
targetx = this.width;
|
targetx = this.width;
|
||||||
if (!this.opened) {
|
if (!this.opened) {
|
||||||
this.onOpened();
|
this.when_loaded.done((function(_this) {
|
||||||
|
return function() {
|
||||||
|
return _this.onOpened();
|
||||||
|
};
|
||||||
|
})(this));
|
||||||
}
|
}
|
||||||
this.opened = true;
|
this.opened = true;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +493,7 @@ window.initScrollable = function () {
|
||||||
this.tag.find("#button-sign").off("click").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("#input-contents").val();
|
||||||
if (wrapper.site_info.privatekey) {
|
if (wrapper.site_info.privatekey) {
|
||||||
wrapper.ws.cmd("siteSign", ["stored", inner_path], function(res) {
|
wrapper.ws.cmd("siteSign", ["stored", inner_path], function(res) {
|
||||||
return wrapper.notifications.add("sign", "done", inner_path + " Signed!", 5000);
|
return wrapper.notifications.add("sign", "done", inner_path + " Signed!", 5000);
|
||||||
|
@ -505,13 +541,16 @@ window.initScrollable = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
Sidebar.prototype.loadGlobe = function() {
|
Sidebar.prototype.loadGlobe = function() {
|
||||||
|
console.log("loadGlobe", this.tag.find(".globe").hasClass("loading"));
|
||||||
if (this.tag.find(".globe").hasClass("loading")) {
|
if (this.tag.find(".globe").hasClass("loading")) {
|
||||||
return setTimeout(((function(_this) {
|
return setTimeout(((function(_this) {
|
||||||
return function() {
|
return function() {
|
||||||
if (typeof DAT === "undefined") {
|
if (typeof DAT === "undefined") {
|
||||||
return $.getScript("/uimedia/globe/all.js", _this.displayGlobe);
|
return $.getScript("/uimedia/globe/all.js", _this.displayGlobe);
|
||||||
} else {
|
} else {
|
||||||
return _this.displayGlobe();
|
return RateLimit(5000, function() {
|
||||||
|
return _this.displayGlobe();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})(this)), 600);
|
})(this)), 600);
|
||||||
|
|
|
@ -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 = 948
|
self.rev = 949
|
||||||
self.argv = argv
|
self.argv = argv
|
||||||
self.action = None
|
self.action = None
|
||||||
self.config_file = "zeronet.conf"
|
self.config_file = "zeronet.conf"
|
||||||
|
|
|
@ -190,8 +190,6 @@ class UiRequest(object):
|
||||||
return self.actionSiteMedia("/media" + path) # Only serve html files with frame
|
return self.actionSiteMedia("/media" + path) # Only serve html files with frame
|
||||||
if self.isAjaxRequest():
|
if self.isAjaxRequest():
|
||||||
return self.error403("Ajax request not allowed to load wrapper") # No ajax allowed on wrapper
|
return self.error403("Ajax request not allowed to load wrapper") # No ajax allowed on wrapper
|
||||||
# if self.env.get("HTTP_ORIGIN") and self.env.get("HTTP_ORIGIN").strip("/") != self.env.get("HTTP_HOST", "").strip("/"):
|
|
||||||
# return self.error403("Origin does not match")
|
|
||||||
|
|
||||||
site = SiteManager.site_manager.get(address)
|
site = SiteManager.site_manager.get(address)
|
||||||
|
|
||||||
|
@ -261,7 +259,6 @@ class UiRequest(object):
|
||||||
if content.get("postmessage_nonce_security"):
|
if content.get("postmessage_nonce_security"):
|
||||||
postmessage_nonce_security = "true"
|
postmessage_nonce_security = "true"
|
||||||
|
|
||||||
|
|
||||||
if site.settings.get("own"):
|
if site.settings.get("own"):
|
||||||
sandbox_permissions = "allow-modals" # For coffeescript compile errors
|
sandbox_permissions = "allow-modals" # For coffeescript compile errors
|
||||||
else:
|
else:
|
||||||
|
@ -328,9 +325,9 @@ class UiRequest(object):
|
||||||
allowed_dir = os.path.abspath("%s/%s" % (config.data_dir, address)) # Only files within data/sitehash allowed
|
allowed_dir = os.path.abspath("%s/%s" % (config.data_dir, address)) # Only files within data/sitehash allowed
|
||||||
data_dir = os.path.abspath("data") # No files from data/ allowed
|
data_dir = os.path.abspath("data") # No files from data/ allowed
|
||||||
if (
|
if (
|
||||||
".." in file_path
|
".." in file_path or
|
||||||
or not os.path.dirname(os.path.abspath(file_path)).startswith(allowed_dir)
|
not os.path.dirname(os.path.abspath(file_path)).startswith(allowed_dir) or
|
||||||
or allowed_dir == data_dir
|
allowed_dir == data_dir
|
||||||
): # File not in allowed path
|
): # File not in allowed path
|
||||||
return self.error403()
|
return self.error403()
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue