Make sidebar translatable
This commit is contained in:
parent
1ef3338f9e
commit
84fb82a574
1 changed files with 113 additions and 100 deletions
|
@ -77,23 +77,24 @@ class UiWebsocketPlugin(object):
|
|||
percent_onion = float(onion) / peers_total
|
||||
else:
|
||||
percent_connectable = percent_connected = percent_onion = 0
|
||||
body.append("""
|
||||
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Peers</label>
|
||||
<label>{_[Peers]}</label>
|
||||
<ul class='graph'>
|
||||
<li style='width: 100%' class='total back-black' title="Total peers"></li>
|
||||
<li style='width: {percent_connectable:.0%}' class='connectable back-blue' title='Connectable peers'></li>
|
||||
<li style='width: {percent_onion:.0%}' class='connected back-purple' title='Onion'></li>
|
||||
<li style='width: {percent_connected:.0%}' class='connected back-green' title='Connected peers'></li>
|
||||
<li style='width: 100%' class='total back-black' title="{_[Total peers]}"></li>
|
||||
<li style='width: {percent_connectable:.0%}' class='connectable back-blue' title='{_[Connectable peers]}'></li>
|
||||
<li style='width: {percent_onion:.0%}' class='connected back-purple' title='{_[Onion]}'></li>
|
||||
<li style='width: {percent_connected:.0%}' class='connected back-green' title='{_[Connected peers]}'></li>
|
||||
</ul>
|
||||
<ul class='graph-legend'>
|
||||
<li class='color-green'><span>connected:</span><b>{connected}</b></li>
|
||||
<li class='color-blue'><span>Connectable:</span><b>{connectable}</b></li>
|
||||
<li class='color-purple'><span>Onion:</span><b>{onion}</b></li>
|
||||
<li class='color-black'><span>Total:</span><b>{peers_total}</b></li>
|
||||
<li class='color-green'><span>{_[Connected]}:</span><b>{connected}</b></li>
|
||||
<li class='color-blue'><span>{_[Connectable]}:</span><b>{connectable}</b></li>
|
||||
<li class='color-purple'><span>{_[Onion]}:</span><b>{onion}</b></li>
|
||||
<li class='color-black'><span>{_[Total]}:</span><b>{peers_total}</b></li>
|
||||
</ul>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
def sidebarRenderTransferStats(self, body, site):
|
||||
recv = float(site.settings.get("bytes_recv", 0)) / 1024 / 1024
|
||||
|
@ -105,32 +106,33 @@ class UiWebsocketPlugin(object):
|
|||
else:
|
||||
percent_recv = 0.5
|
||||
percent_sent = 0.5
|
||||
body.append("""
|
||||
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Data transfer</label>
|
||||
<label>{_[Data transfer]}</label>
|
||||
<ul class='graph graph-stacked'>
|
||||
<li style='width: {percent_recv:.0%}' class='received back-yellow' title="Received bytes"></li>
|
||||
<li style='width: {percent_sent:.0%}' class='sent back-green' title="Sent bytes"></li>
|
||||
<li style='width: {percent_recv:.0%}' class='received back-yellow' title="{_[Received bytes]}"></li>
|
||||
<li style='width: {percent_sent:.0%}' class='sent back-green' title="{_[Sent bytes]}"></li>
|
||||
</ul>
|
||||
<ul class='graph-legend'>
|
||||
<li class='color-yellow'><span>Received:</span><b>{recv:.2f}MB</b></li>
|
||||
<li class='color-green'<span>Sent:</span><b>{sent:.2f}MB</b></li>
|
||||
<li class='color-yellow'><span>{_[Received]}:</span><b>{recv:.2f}MB</b></li>
|
||||
<li class='color-green'<span>{_[Sent]}:</span><b>{sent:.2f}MB</b></li>
|
||||
</ul>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
def sidebarRenderFileStats(self, body, site):
|
||||
body.append("<li><label>Files</label><ul class='graph graph-stacked'>")
|
||||
body.append(_(u"<li><label>{_[Files]}</label><ul class='graph graph-stacked'>"))
|
||||
|
||||
extensions = (
|
||||
("html", "yellow"),
|
||||
("css", "orange"),
|
||||
("js", "purple"),
|
||||
("image", "green"),
|
||||
("Image", "green"),
|
||||
("json", "darkblue"),
|
||||
("user data", "blue"),
|
||||
("other", "white"),
|
||||
("total", "black")
|
||||
("User data", "blue"),
|
||||
("Other", "white"),
|
||||
("Total", "black")
|
||||
)
|
||||
# Collect stats
|
||||
size_filetypes = {}
|
||||
|
@ -152,7 +154,7 @@ class UiWebsocketPlugin(object):
|
|||
).fetchone()["size"]
|
||||
if not size_user_content:
|
||||
size_user_content = 0
|
||||
size_filetypes["user data"] = size_user_content
|
||||
size_filetypes["User data"] = size_user_content
|
||||
size_total += size_user_content
|
||||
|
||||
# The missing difference is content.json sizes
|
||||
|
@ -162,11 +164,11 @@ class UiWebsocketPlugin(object):
|
|||
|
||||
# Bar
|
||||
for extension, color in extensions:
|
||||
if extension == "total":
|
||||
if extension == "Total":
|
||||
continue
|
||||
if extension == "other":
|
||||
if extension == "Other":
|
||||
size = max(0, size_other)
|
||||
elif extension == "image":
|
||||
elif extension == "Image":
|
||||
size = size_filetypes.get("jpg", 0) + size_filetypes.get("png", 0) + size_filetypes.get("gif", 0)
|
||||
size_other -= size
|
||||
else:
|
||||
|
@ -179,15 +181,15 @@ class UiWebsocketPlugin(object):
|
|||
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, _[extension], color, _[extension])
|
||||
)
|
||||
|
||||
# Legend
|
||||
body.append("</ul><ul class='graph-legend'>")
|
||||
for extension, color in extensions:
|
||||
if extension == "other":
|
||||
if extension == "Other":
|
||||
size = max(0, size_other)
|
||||
elif extension == "image":
|
||||
elif extension == "Image":
|
||||
size = size_filetypes.get("jpg", 0) + size_filetypes.get("png", 0) + size_filetypes.get("gif", 0)
|
||||
elif extension == "total":
|
||||
size = size_total
|
||||
|
@ -204,7 +206,7 @@ class UiWebsocketPlugin(object):
|
|||
else:
|
||||
size_formatted = "%.0fkB" % (size / 1024)
|
||||
|
||||
body.append(u"<li class='color-%s'><span>%s:</span><b>%s</b></li>" % (color, title, size_formatted))
|
||||
body.append(u"<li class='color-%s'><span>%s:</span><b>%s</b></li>" % (color, _[title], size_formatted))
|
||||
|
||||
body.append("</ul></li>")
|
||||
|
||||
|
@ -213,13 +215,14 @@ class UiWebsocketPlugin(object):
|
|||
size = float(site.settings["size"]) / 1024 / 1024
|
||||
size_limit = site.getSizeLimit()
|
||||
percent_used = size / size_limit
|
||||
body.append("""
|
||||
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Size limit <small>(limit used: {percent_used:.0%}, free space: {free_space:,d}MB)</small></label>
|
||||
<label>{_[Size limit]} <small>({_[limit used]}: {percent_used:.0%}, {_[free space]}: {free_space:,d}MB)</small></label>
|
||||
<input type='text' class='text text-num' value="{size_limit}" id='input-sitelimit'/><span class='text-post'>MB</span>
|
||||
<a href='#Set' class='button' id='button-sitelimit'>Set</a>
|
||||
<a href='#Set' class='button' id='button-sitelimit'>{_[Set]}</a>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
def sidebarRenderOptionalFileStats(self, body, site):
|
||||
size_total = float(site.settings["size_optional"])
|
||||
|
@ -233,19 +236,19 @@ class UiWebsocketPlugin(object):
|
|||
size_formatted_total = size_total / 1024 / 1024
|
||||
size_formatted_downloaded = size_downloaded / 1024 / 1024
|
||||
|
||||
body.append("""
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Optional files</label>
|
||||
<label>{_[Optional files]}</label>
|
||||
<ul class='graph'>
|
||||
<li style='width: 100%' class='total back-black' title="Total size"></li>
|
||||
<li style='width: {percent_downloaded:.0%}' class='connected back-green' title='Downloaded files'></li>
|
||||
<li style='width: 100%' class='total back-black' title="{_[Total size]}"></li>
|
||||
<li style='width: {percent_downloaded:.0%}' class='connected back-green' title='{_[Downloaded files]}'></li>
|
||||
</ul>
|
||||
<ul class='graph-legend'>
|
||||
<li class='color-green'><span>Downloaded:</span><b>{size_formatted_downloaded:.2f}MB</b></li>
|
||||
<li class='color-black'><span>Total:</span><b>{size_formatted_total:.2f}MB</b></li>
|
||||
<li class='color-green'><span>{_[Downloaded]}:</span><b>{size_formatted_downloaded:.2f}MB</b></li>
|
||||
<li class='color-black'><span>{_[Total]}:</span><b>{size_formatted_total:.2f}MB</b></li>
|
||||
</ul>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
return True
|
||||
|
||||
|
@ -254,31 +257,33 @@ class UiWebsocketPlugin(object):
|
|||
checked = "checked='checked'"
|
||||
else:
|
||||
checked = ""
|
||||
body.append("""
|
||||
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Download and help distribute all files</label>
|
||||
<label>{_[Download and help distribute all files]}</label>
|
||||
<input type="checkbox" class="checkbox" id="checkbox-autodownloadoptional" {checked}/><div class="checkbox-skin"></div>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
def sidebarRenderBadFiles(self, body, site):
|
||||
body.append("""
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Missing files:</label>
|
||||
<label>{_[Missing files]}:</label>
|
||||
<ul class='filelist'>
|
||||
""")
|
||||
"""))
|
||||
|
||||
i = 0
|
||||
for bad_file, tries in site.bad_files.iteritems():
|
||||
i += 1
|
||||
body.append("""<li class='color-red' title="%s (%s tries)">%s</li>""" % (
|
||||
cgi.escape(bad_file, True), tries, cgi.escape(bad_file, True))
|
||||
)
|
||||
body.append(_(u"""<li class='color-red' title="{bad_file} ({tries})">{bad_file}</li>""", {
|
||||
"bad_file": cgi.escape(bad_file, True), "tries": _.pluralize(tries, "{} try", "{} tries")
|
||||
}))
|
||||
if i > 30:
|
||||
break
|
||||
|
||||
if len(site.bad_files) > 30:
|
||||
body.append("""<li class='color-red'>+ %s more</li>""" % (len(site.bad_files) - 30))
|
||||
num_bad_files = len(site.bad_files) - 30
|
||||
body.append(_(u"""<li class='color-red'>{_[+ {num_bad_files} more]}</li>""", nested=True))
|
||||
|
||||
body.append("""
|
||||
</ul>
|
||||
|
@ -291,18 +296,20 @@ class UiWebsocketPlugin(object):
|
|||
size = float(site.storage.getSize(inner_path)) / 1024
|
||||
feeds = len(site.storage.db.schema.get("feeds", {}))
|
||||
else:
|
||||
inner_path = "No database found"
|
||||
inner_path = _[u"No database found"]
|
||||
size = 0.0
|
||||
feeds = 0
|
||||
|
||||
body.append(u"""
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Database <small>({size:.2f}kB, search feeds: {feeds} query)</small></label>
|
||||
<input type='text' class='text disabled' value="{inner_path}" disabled='disabled' style='width: 180px;'/>
|
||||
<a href='#Reload' id="button-dbreload" class='button'>Reload</a>
|
||||
<a href='#Rebuild' id="button-dbrebuild" class='button'>Rebuild</a>
|
||||
<label>{_[Database]} <small>({size:.2f}kB, {_[search feeds]}: {_[{feeds} query]})</small></label>
|
||||
<div class='flex'>
|
||||
<input type='text' class='text disabled' value="{inner_path}" disabled='disabled' style='width: 180px;'/>
|
||||
<a href='#Reload' id="button-dbreload" class='button'>{_[Reload]}</a>
|
||||
<a href='#Rebuild' id="button-dbrebuild" class='button'>{_[Rebuild]}</a>
|
||||
</div>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
""", nested=True))
|
||||
|
||||
def sidebarRenderIdentity(self, body, site):
|
||||
auth_address = self.user.getAuthAddress(self.site.address)
|
||||
|
@ -318,13 +325,15 @@ class UiWebsocketPlugin(object):
|
|||
else:
|
||||
quota = used = 0
|
||||
|
||||
body.append("""
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Identity address <small>(limit used: {used:.2f}kB / {quota:.2f}kB)</small></label>
|
||||
<span class='input text disabled'>{auth_address}</span>
|
||||
<a href='#Change' class='button' id='button-identity'>Change</a>
|
||||
<label>{_[Identity address]} <small>({_[limit used]}: {used:.2f}kB / {quota:.2f}kB)</small></label>
|
||||
<div class='flex'>
|
||||
<span class='input text disabled'>{auth_address}</span>
|
||||
<a href='#Change' class='button' id='button-identity'>{_[Change]}</a>
|
||||
</div>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
def sidebarRenderControls(self, body, site):
|
||||
auth_address = self.user.getAuthAddress(self.site.address)
|
||||
|
@ -335,24 +344,26 @@ class UiWebsocketPlugin(object):
|
|||
class_pause = "hidden"
|
||||
class_resume = ""
|
||||
|
||||
body.append("""
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Site control</label>
|
||||
<a href='#Update' class='button noupdate' id='button-update'>Update</a>
|
||||
<a href='#Pause' class='button {class_pause}' id='button-pause'>Pause</a>
|
||||
<a href='#Resume' class='button {class_resume}' id='button-resume'>Resume</a>
|
||||
<a href='#Delete' class='button noupdate' id='button-delete'>Delete</a>
|
||||
<label>{_[Site control]}</label>
|
||||
<a href='#Update' class='button noupdate' id='button-update'>{_[Update]}</a>
|
||||
<a href='#Pause' class='button {class_pause}' id='button-pause'>{_[Pause]}</a>
|
||||
<a href='#Resume' class='button {class_resume}' id='button-resume'>{_[Resume]}</a>
|
||||
<a href='#Delete' class='button noupdate' id='button-delete'>{_[Delete]}</a>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
site_address = self.site.address
|
||||
body.append("""
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Site address</label><br>
|
||||
<span class='input text disabled'>{site_address}</span>
|
||||
<a href='bitcoin:{site_address}' class='button' id='button-donate'>Donate</a>
|
||||
<label>{_[Site address]}</label><br>
|
||||
<div class='flex'>
|
||||
<span class='input text disabled'>{site_address}</span>
|
||||
<a href='bitcoin:{site_address}' class='button' id='button-donate'>{_[Donate]}</a>
|
||||
</div>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
def sidebarRenderOwnedCheckbox(self, body, site):
|
||||
if self.site.settings["own"]:
|
||||
|
@ -360,59 +371,61 @@ class UiWebsocketPlugin(object):
|
|||
else:
|
||||
checked = ""
|
||||
|
||||
body.append("""
|
||||
<h2 class='owned-title'>This is my site</h2>
|
||||
body.append(_(u"""
|
||||
<h2 class='owned-title'>{_[This is my site]}</h2>
|
||||
<input type="checkbox" class="checkbox" id="checkbox-owned" {checked}/><div class="checkbox-skin"></div>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
def sidebarRenderOwnSettings(self, body, site):
|
||||
title = cgi.escape(site.content_manager.contents.get("content.json", {}).get("title", ""), True)
|
||||
description = cgi.escape(site.content_manager.contents.get("content.json", {}).get("description", ""), True)
|
||||
privatekey = cgi.escape(self.user.getSiteData(site.address, create=False).get("privatekey", ""))
|
||||
|
||||
body.append(u"""
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label for='settings-title'>Site title</label>
|
||||
<label for='settings-title'>{_[Site title]}</label>
|
||||
<input type='text' class='text' value="{title}" id='settings-title'/>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<label for='settings-description'>Site description</label>
|
||||
<label for='settings-description'>{_[Site description]}</label>
|
||||
<input type='text' class='text' value="{description}" id='settings-description'/>
|
||||
</li>
|
||||
|
||||
<li style='display: none'>
|
||||
<label>Private key</label>
|
||||
<input type='text' class='text long' value="{privatekey}" placeholder='[Ask on signing]'/>
|
||||
<label>{_[Private key]}</label>
|
||||
<input type='text' class='text long' value="{privatekey}" placeholder='{_[Ask when signing]}'/>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href='#Save' class='button' id='button-settings'>Save site settings</a>
|
||||
<a href='#Save' class='button' id='button-settings'>{_[Save site settings]}</a>
|
||||
</li>
|
||||
""".format(**locals()))
|
||||
"""))
|
||||
|
||||
def sidebarRenderContents(self, body, site):
|
||||
body.append("""
|
||||
body.append(_(u"""
|
||||
<li>
|
||||
<label>Content publishing</label>
|
||||
""")
|
||||
<label>{_[Content publishing]}</label>
|
||||
"""))
|
||||
|
||||
# Choose content you want to sign
|
||||
contents = ["content.json"]
|
||||
contents += site.content_manager.contents.get("content.json", {}).get("includes", {}).keys()
|
||||
if len(contents) > 1:
|
||||
body.append("<div class='contents'>Choose: ")
|
||||
body.append(_(u"<div class='contents'>{_[Choose]}: "))
|
||||
for content in contents:
|
||||
content = cgi.escape(content, True)
|
||||
body.append("<a href='#{content}' onclick='$(\"#input-contents\").val(\"{content}\"); return false'>{content}</a> ".format(**locals()))
|
||||
body.append(_("<a href='#{content}' onclick='$(\"#input-contents\").val(\"{content}\"); return false'>{content}</a> "))
|
||||
body.append("</div>")
|
||||
|
||||
body.append("""
|
||||
<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>
|
||||
body.append(_(u"""
|
||||
<div class='flex'>
|
||||
<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>
|
||||
</div>
|
||||
</li>
|
||||
""")
|
||||
"""))
|
||||
|
||||
def actionSidebarGetHtmlTag(self, to):
|
||||
site = self.site
|
||||
|
@ -456,7 +469,7 @@ class UiWebsocketPlugin(object):
|
|||
from util import helper
|
||||
|
||||
self.log.info("Downloading GeoLite2 City database...")
|
||||
self.cmd("notification", ["geolite-info", "Downloading GeoLite2 City database (one time only, ~20MB)...", 0])
|
||||
self.cmd("notification", ["geolite-info", _["Downloading GeoLite2 City database (one time only, ~20MB)..."], 0])
|
||||
db_urls = [
|
||||
"https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz",
|
||||
"https://raw.githubusercontent.com/texnikru/GeoLite2-Database/master/GeoLite2-City.mmdb.gz"
|
||||
|
@ -479,7 +492,7 @@ class UiWebsocketPlugin(object):
|
|||
with gzip.GzipFile(fileobj=data) as gzip_file:
|
||||
shutil.copyfileobj(gzip_file, open(db_path, "wb"))
|
||||
|
||||
self.cmd("notification", ["geolite-done", "GeoLite2 City database downloaded!", 5000])
|
||||
self.cmd("notification", ["geolite-done", _["GeoLite2 City database downloaded!"], 5000])
|
||||
time.sleep(2) # Wait for notify animation
|
||||
return True
|
||||
except Exception, err:
|
||||
|
@ -487,7 +500,7 @@ class UiWebsocketPlugin(object):
|
|||
pass
|
||||
self.cmd("notification", [
|
||||
"geolite-error",
|
||||
"GeoLite2 City database download error: %s!<br>Please download and unpack to data dir:<br>%s" % (err, db_urls[0]),
|
||||
_["GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}"].format(err, db_urls[0]),
|
||||
0
|
||||
])
|
||||
|
||||
|
@ -572,7 +585,7 @@ class UiWebsocketPlugin(object):
|
|||
permissions = self.getPermissions(to)
|
||||
|
||||
if "Multiuser" in PluginManager.plugin_manager.plugin_names:
|
||||
self.cmd("notification", ["info", "This function is disabled on this proxy"])
|
||||
self.cmd("notification", ["info", _["This function is disabled on this proxy"]])
|
||||
return False
|
||||
|
||||
if "ADMIN" not in permissions:
|
||||
|
|
Loading…
Reference in a new issue