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:
HelloZeroNet 2016-03-06 19:28:22 +01:00
parent bfdccb809c
commit 2901f1e1ba
7 changed files with 77 additions and 27 deletions

View file

@ -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

View file

@ -148,8 +148,11 @@ class UiWebsocketPlugin(object):
percent = 0
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))
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)
)
# 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'>&rsaquo;</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>

View 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

View file

@ -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

View file

@ -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);

View file

@ -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"

View file

@ -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: