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
|
||||
for row in res:
|
||||
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
|
||||
row["site"] = address
|
||||
row["feed_name"] = name
|
||||
|
|
|
@ -149,7 +149,10 @@ class UiWebsocketPlugin(object):
|
|||
else:
|
||||
percent = 100 * (float(size) / size_total)
|
||||
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
|
||||
body.append("</ul><ul class='graph-legend'>")
|
||||
|
@ -334,15 +337,7 @@ class UiWebsocketPlugin(object):
|
|||
body.append("""
|
||||
<li>
|
||||
<label>Content publishing</label>
|
||||
<select id='select-contents'>
|
||||
""")
|
||||
|
||||
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>
|
||||
<input type='text' class='text' value="content.json" id='input-contents' style='width: 201px'/>
|
||||
<a href='#Sign' class='button' id='button-sign'>Sign</a>
|
||||
<a href='#Publish' class='button' id='button-publish'>Publish</a>
|
||||
</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
|
||||
createHtmltag: ->
|
||||
@when_loaded = $.Deferred()
|
||||
if not @container
|
||||
@container = $("""
|
||||
<div class="sidebar-container"><div class="sidebar scrollable"><div class="content-wrapper"><div class="content">
|
||||
|
@ -141,6 +142,7 @@ class Sidebar extends Class
|
|||
else
|
||||
return true
|
||||
}
|
||||
@when_loaded.resolve()
|
||||
|
||||
|
||||
animDrag: (e) =>
|
||||
|
@ -195,6 +197,7 @@ class Sidebar extends Class
|
|||
# Opened
|
||||
targetx = @width
|
||||
if not @opened
|
||||
@when_loaded.done =>
|
||||
@onOpened()
|
||||
@opened = true
|
||||
|
||||
|
@ -265,7 +268,7 @@ class Sidebar extends Class
|
|||
|
||||
# Sign content.json
|
||||
@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
|
||||
# Privatekey stored in users.json
|
||||
|
@ -304,11 +307,13 @@ class Sidebar extends Class
|
|||
|
||||
|
||||
loadGlobe: =>
|
||||
console.log "loadGlobe", @tag.find(".globe").hasClass("loading")
|
||||
if @tag.find(".globe").hasClass("loading")
|
||||
setTimeout (=>
|
||||
if typeof(DAT) == "undefined" # Globe script not loaded, do it first
|
||||
$.getScript("/uimedia/globe/all.js", @displayGlobe)
|
||||
else
|
||||
RateLimit 5000, =>
|
||||
@displayGlobe()
|
||||
), 600
|
||||
|
||||
|
|
|
@ -57,6 +57,36 @@
|
|||
}).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 ---- */
|
||||
|
||||
|
||||
|
@ -291,6 +321,7 @@ window.initScrollable = function () {
|
|||
};
|
||||
|
||||
Sidebar.prototype.createHtmltag = function() {
|
||||
this.when_loaded = $.Deferred();
|
||||
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.appendTo(document.body);
|
||||
|
@ -305,10 +336,10 @@ window.initScrollable = function () {
|
|||
return function(res) {
|
||||
if (_this.tag.find(".content").children().length === 0) {
|
||||
_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 {
|
||||
_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) {
|
||||
if (from_el.className === "globe") {
|
||||
return false;
|
||||
|
@ -318,6 +349,7 @@ window.initScrollable = function () {
|
|||
}
|
||||
});
|
||||
}
|
||||
return _this.when_loaded.resolve();
|
||||
};
|
||||
})(this));
|
||||
};
|
||||
|
@ -371,7 +403,11 @@ window.initScrollable = function () {
|
|||
} else {
|
||||
targetx = this.width;
|
||||
if (!this.opened) {
|
||||
this.onOpened();
|
||||
this.when_loaded.done((function(_this) {
|
||||
return function() {
|
||||
return _this.onOpened();
|
||||
};
|
||||
})(this));
|
||||
}
|
||||
this.opened = true;
|
||||
}
|
||||
|
@ -457,7 +493,7 @@ window.initScrollable = function () {
|
|||
this.tag.find("#button-sign").off("click").on("click", (function(_this) {
|
||||
return function() {
|
||||
var inner_path;
|
||||
inner_path = _this.tag.find("#select-contents").val();
|
||||
inner_path = _this.tag.find("#input-contents").val();
|
||||
if (wrapper.site_info.privatekey) {
|
||||
wrapper.ws.cmd("siteSign", ["stored", inner_path], function(res) {
|
||||
return wrapper.notifications.add("sign", "done", inner_path + " Signed!", 5000);
|
||||
|
@ -505,13 +541,16 @@ window.initScrollable = function () {
|
|||
};
|
||||
|
||||
Sidebar.prototype.loadGlobe = function() {
|
||||
console.log("loadGlobe", this.tag.find(".globe").hasClass("loading"));
|
||||
if (this.tag.find(".globe").hasClass("loading")) {
|
||||
return setTimeout(((function(_this) {
|
||||
return function() {
|
||||
if (typeof DAT === "undefined") {
|
||||
return $.getScript("/uimedia/globe/all.js", _this.displayGlobe);
|
||||
} else {
|
||||
return RateLimit(5000, function() {
|
||||
return _this.displayGlobe();
|
||||
});
|
||||
}
|
||||
};
|
||||
})(this)), 600);
|
||||
|
|
|
@ -8,7 +8,7 @@ class Config(object):
|
|||
|
||||
def __init__(self, argv):
|
||||
self.version = "0.3.6"
|
||||
self.rev = 948
|
||||
self.rev = 949
|
||||
self.argv = argv
|
||||
self.action = None
|
||||
self.config_file = "zeronet.conf"
|
||||
|
|
|
@ -190,8 +190,6 @@ class UiRequest(object):
|
|||
return self.actionSiteMedia("/media" + path) # Only serve html files with frame
|
||||
if self.isAjaxRequest():
|
||||
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)
|
||||
|
||||
|
@ -261,7 +259,6 @@ class UiRequest(object):
|
|||
if content.get("postmessage_nonce_security"):
|
||||
postmessage_nonce_security = "true"
|
||||
|
||||
|
||||
if site.settings.get("own"):
|
||||
sandbox_permissions = "allow-modals" # For coffeescript compile errors
|
||||
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
|
||||
data_dir = os.path.abspath("data") # No files from data/ allowed
|
||||
if (
|
||||
".." in file_path
|
||||
or not os.path.dirname(os.path.abspath(file_path)).startswith(allowed_dir)
|
||||
or allowed_dir == data_dir
|
||||
".." in file_path or
|
||||
not os.path.dirname(os.path.abspath(file_path)).startswith(allowed_dir) or
|
||||
allowed_dir == data_dir
|
||||
): # File not in allowed path
|
||||
return self.error403()
|
||||
else:
|
||||
|
|
Loading…
Reference in a new issue