Make sidebar translatable

This commit is contained in:
shortcutme 2016-11-18 20:13:54 +01:00
parent 1ef3338f9e
commit 84fb82a574

View file

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