Merge branch 'HelloZeroNet-py3' into massive-rework
# Conflicts: # src/File/FileServer.py
This commit is contained in:
commit
545fe9442c
38 changed files with 588 additions and 120 deletions
|
@ -146,6 +146,7 @@ class ActionsPlugin:
|
|||
|
||||
yield "\n"
|
||||
res = {}
|
||||
res_time_taken = {}
|
||||
multiplers = []
|
||||
for test in tests:
|
||||
s = time.time()
|
||||
|
@ -182,11 +183,35 @@ class ActionsPlugin:
|
|||
yield self.formatResult(time_taken, time_standard)
|
||||
yield "\n"
|
||||
res[key] = "ok"
|
||||
res_time_taken[key] = time_taken
|
||||
multiplers.append(time_standard / max(time_taken, 0.001))
|
||||
except Exception as err:
|
||||
res[key] = err
|
||||
yield "Failed!\n! Error: %s\n\n" % Debug.formatException(err)
|
||||
|
||||
yield "\n== Result ==\n"
|
||||
|
||||
# Check verification speed
|
||||
if "testVerify {'lib_verify': 'sslcrypto'}" in res_time_taken:
|
||||
speed_order = ["sslcrypto_fallback", "sslcrypto", "libsecp256k1"]
|
||||
time_taken = {}
|
||||
for lib_verify in speed_order:
|
||||
time_taken[lib_verify] = res_time_taken["testVerify {'lib_verify': '%s'}" % lib_verify]
|
||||
|
||||
time_taken["sslcrypto_fallback"] *= 10 # fallback benchmark only run 20 times instead of 200
|
||||
speedup_sslcrypto = time_taken["sslcrypto_fallback"] / time_taken["sslcrypto"]
|
||||
speedup_libsecp256k1 = time_taken["sslcrypto_fallback"] / time_taken["libsecp256k1"]
|
||||
|
||||
yield "\n* Verification speedup:\n"
|
||||
yield " - OpenSSL: %.1fx (reference: 7.0x)\n" % speedup_sslcrypto
|
||||
yield " - libsecp256k1: %.1fx (reference: 23.8x)\n" % speedup_libsecp256k1
|
||||
|
||||
if speedup_sslcrypto < 2:
|
||||
res["Verification speed"] = "error: OpenSSL speedup low: %.1fx" % speedup_sslcrypto
|
||||
|
||||
if speedup_libsecp256k1 < speedup_sslcrypto:
|
||||
res["Verification speed"] = "error: libsecp256k1 speedup low: %.1fx" % speedup_libsecp256k1
|
||||
|
||||
if not res:
|
||||
yield "! No tests found"
|
||||
if config.action == "test":
|
||||
|
@ -194,17 +219,22 @@ class ActionsPlugin:
|
|||
else:
|
||||
num_failed = len([res_key for res_key, res_val in res.items() if res_val != "ok"])
|
||||
num_success = len([res_key for res_key, res_val in res.items() if res_val == "ok"])
|
||||
yield "* Result:\n"
|
||||
yield "\n* Tests:\n"
|
||||
yield " - Total: %s tests\n" % len(res)
|
||||
yield " - Success: %s tests\n" % num_success
|
||||
yield " - Failed: %s tests\n" % num_failed
|
||||
if any(multiplers):
|
||||
multipler_avg = sum(multiplers) / len(multiplers)
|
||||
multipler_title = self.getMultiplerTitle(multipler_avg)
|
||||
yield " - Average speed factor: %.2fx (%s)" % (multipler_avg, multipler_title)
|
||||
if num_failed == 0 and config.action == "test":
|
||||
sys.exit(1)
|
||||
yield " - Average speed factor: %.2fx (%s)\n" % (multipler_avg, multipler_title)
|
||||
|
||||
# Display errors
|
||||
for res_key, res_val in res.items():
|
||||
if res_val != "ok":
|
||||
yield " ! %s %s\n" % (res_key, res_val)
|
||||
|
||||
if num_failed != 0 and config.action == "test":
|
||||
sys.exit(1)
|
||||
|
||||
def testHttps(self, num_run=1):
|
||||
"""
|
||||
|
@ -323,13 +353,14 @@ class ActionsPlugin:
|
|||
valid = "G1GXaDauZ8vX/N9Jn+MRiGm9h+I94zUhDnNYFaqMGuOiBHB+kp4cRPZOL7l1yqK5BHa6J+W97bMjvTXtxzljp6w="
|
||||
assert sign == valid, "%s != %s" % (sign, valid)
|
||||
|
||||
def testVerify(self, num_run=1, lib_verify="btctools"):
|
||||
def testVerify(self, num_run=1, lib_verify="sslcrypto"):
|
||||
"""
|
||||
Test verification of generated signatures
|
||||
"""
|
||||
from Crypt import CryptBitcoin
|
||||
CryptBitcoin.loadLib(lib_verify, silent=True)
|
||||
|
||||
|
||||
data = "Hello" * 1024
|
||||
privatekey = "5JsunC55XGVqFQj5kPGK4MWgTL26jKbnPhjnmchSNPo75XXCwtk"
|
||||
address = CryptBitcoin.privatekeyToAddress(privatekey)
|
||||
|
@ -340,6 +371,9 @@ class ActionsPlugin:
|
|||
yield "."
|
||||
assert ok, "does not verify from %s" % address
|
||||
|
||||
if lib_verify == "sslcrypto":
|
||||
yield("(%s)" % CryptBitcoin.sslcrypto.ecc.get_backend())
|
||||
|
||||
def testPortCheckers(self):
|
||||
"""
|
||||
Test all active open port checker
|
||||
|
@ -361,7 +395,6 @@ class ActionsPlugin:
|
|||
"""
|
||||
from Peer import PeerPortchecker
|
||||
peer_portchecker = PeerPortchecker.PeerPortchecker(None)
|
||||
s = time.time()
|
||||
announce_func = getattr(peer_portchecker, func_name)
|
||||
res = announce_func(3894)
|
||||
yield res
|
||||
|
|
|
@ -39,7 +39,7 @@ function setState(elem, text) {
|
|||
}
|
||||
}
|
||||
formatted = formatted.replace(/(\! Error:.*)/, "<div class='test error'>$1</div>");
|
||||
formatted = formatted.replace(/(\* Result:[^]*)/, "<div class='test summary'>$1</div>");
|
||||
formatted = formatted.replace(/(\== Result ==[^]*)/, "<div class='test summary'>$1</div>");
|
||||
var is_bottom = document.body.scrollTop + document.body.clientHeight >= document.body.scrollHeight - 5;
|
||||
elem.innerHTML = formatted.trim();
|
||||
if (is_bottom)
|
||||
|
|
6
plugins/ContentFilter/languages/jp.json
Normal file
6
plugins/ContentFilter/languages/jp.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"Hide all content from <b>%s</b>?": "<b>%s</b> のコンテンツをすべて隠しますか?",
|
||||
"Mute": "ミュート",
|
||||
"Unmute <b>%s</b>?": "<b>%s</b> のミュートを解除しますか?",
|
||||
"Unmute": "ミュート解除"
|
||||
}
|
5
plugins/MergerSite/languages/jp.json
Normal file
5
plugins/MergerSite/languages/jp.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"Add <b>%s</b> new site?": "サイト: <b>%s</b> を追加しますか?",
|
||||
"Added <b>%s</b> new site": "サイト: <b>%s</b> を追加しました",
|
||||
"Site deleted: <b>%s</b>": "サイト: <b>%s</b> を削除しました"
|
||||
}
|
|
@ -139,7 +139,7 @@ class UiWebsocketPlugin(object):
|
|||
wheres = {}
|
||||
wheres_raw = []
|
||||
if "bigfile" in filter:
|
||||
wheres["size >"] = 1024 * 1024 * 10
|
||||
wheres["size >"] = 1024 * 1024 * 1
|
||||
if "downloaded" in filter:
|
||||
wheres_raw.append("(is_downloaded = 1 OR is_pinned = 1)")
|
||||
if "pinned" in filter:
|
||||
|
@ -166,11 +166,14 @@ class UiWebsocketPlugin(object):
|
|||
row["address"] = address
|
||||
|
||||
if row["size"] > 1024 * 1024:
|
||||
has_info = self.addBigfileInfo(row)
|
||||
has_bigfile_info = self.addBigfileInfo(row)
|
||||
else:
|
||||
has_info = False
|
||||
has_bigfile_info = False
|
||||
|
||||
if not has_info:
|
||||
if not has_bigfile_info and "bigfile" in filter:
|
||||
continue
|
||||
|
||||
if not has_bigfile_info:
|
||||
if row["is_downloaded"]:
|
||||
row["bytes_downloaded"] = row["size"]
|
||||
row["downloaded_percent"] = 100
|
||||
|
|
7
plugins/OptionalManager/languages/jp.json
Normal file
7
plugins/OptionalManager/languages/jp.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"Pinned %s files": "%s 件のファイルを固定",
|
||||
"Removed pin from %s files": "%s 件のファイルの固定を解除",
|
||||
"You started to help distribute <b>%s</b>.<br><small>Directory: %s</small>": "あなたはサイト: <b>%s</b> の配布の援助を開始しました。<br><small>ディレクトリ: %s</small>",
|
||||
"Help distribute all new optional files on site <b>%s</b>": "サイト: <b>%s</b> のすべての新しいオプションファイルの配布を援助しますか?",
|
||||
"Yes, I want to help!": "はい、やります!"
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
{
|
||||
"Copy to clipboard": "クリップボードにコピー",
|
||||
"Peers": "ピア",
|
||||
"Connected": "接続済み",
|
||||
"Connectable": "利用可能",
|
||||
"Connectable peers": "ピアに接続可能",
|
||||
"Onion": "Onion",
|
||||
"Local": "ローカル",
|
||||
|
||||
"Data transfer": "データ転送",
|
||||
"Received": "受信",
|
||||
|
@ -11,6 +14,8 @@
|
|||
"Sent bytes": "送信バイト数",
|
||||
|
||||
"Files": "ファイル",
|
||||
"Browse files": "ファイルを見る",
|
||||
"Save as .zip": "ZIP形式で保存",
|
||||
"Total": "合計",
|
||||
"Image": "画像",
|
||||
"Other": "その他",
|
||||
|
@ -23,18 +28,23 @@
|
|||
|
||||
"Optional files": "オプション ファイル",
|
||||
"Downloaded": "ダウンロード済み",
|
||||
"Help distribute added optional files": "オプションファイルの配布を支援する",
|
||||
"Auto download big file size limit": "大きなファイルの自動ダウンロードのサイズ制限",
|
||||
"Download previous files": "以前のファイルのダウンロード",
|
||||
"Optional files download started": "オプションファイルのダウンロードを開始",
|
||||
"Optional files downloaded": "オプションファイルのダウンロードが完了しました",
|
||||
"Download and help distribute all files": "ダウンロードしてすべてのファイルの配布を支援する",
|
||||
"Total size": "合計サイズ",
|
||||
"Downloaded files": "ダウンロードされたファイル",
|
||||
|
||||
"Database": "データベース",
|
||||
"search feeds": "フィードを検索する",
|
||||
"{feeds} query": "{フィード} お問い合わせ",
|
||||
"{feeds} query": "{feeds} お問い合わせ",
|
||||
"Reload": "再読込",
|
||||
"Rebuild": "再ビルド",
|
||||
"No database found": "データベースが見つかりません",
|
||||
|
||||
"Identity address": "Identity address",
|
||||
"Identity address": "あなたの識別アドレス",
|
||||
"Change": "編集",
|
||||
|
||||
"Site control": "サイト管理",
|
||||
|
@ -52,15 +62,23 @@
|
|||
"{} tries": "{} 試行",
|
||||
"+ {num_bad_files} more": "+ {num_bad_files} more",
|
||||
|
||||
"This is my site": "This is my site",
|
||||
"This is my site": "これは私のサイトです",
|
||||
"Site title": "サイトタイトル",
|
||||
"Site description": "サイトの説明",
|
||||
"Save site settings": "サイトの設定を保存する",
|
||||
"Open site directory": "サイトのディレクトリを開く",
|
||||
|
||||
"Content publishing": "コンテンツを公開する",
|
||||
"Add saved private key": "秘密鍵の追加と保存",
|
||||
"Save": "保存",
|
||||
"Private key saved.": "秘密鍵が保存されています",
|
||||
"Private key saved for site signing": "サイトに署名するための秘密鍵を保存",
|
||||
"Forgot": "わすれる",
|
||||
"Saved private key removed": "保存された秘密鍵を削除しました",
|
||||
"Choose": "選択",
|
||||
"Sign": "Sign",
|
||||
"Sign": "署名",
|
||||
"Publish": "公開する",
|
||||
"Sign and publish": "署名して公開",
|
||||
|
||||
"This function is disabled on this proxy": "この機能はこのプロキシで無効になっています",
|
||||
"GeoLite2 City database download error: {}!<br>Please download manually and unpack to data dir:<br>{}": "GeoLite2 Cityデータベースのダウンロードエラー: {}!<br>手動でダウンロードして、フォルダに解凍してください。:<br>{}",
|
||||
|
@ -74,9 +92,13 @@
|
|||
"Database rebuilt!": "データベースが再構築されました!",
|
||||
"Site updated!": "サイトが更新されました!",
|
||||
"Delete this site": "このサイトを削除する",
|
||||
"Blacklist": "NG",
|
||||
"Blacklist this site": "NGリストに入れる",
|
||||
"Reason": "理由",
|
||||
"Delete and Blacklist": "削除してNG",
|
||||
"File write error: ": "ファイル書き込みエラー:",
|
||||
"Site settings saved!": "サイト設定が保存されました!",
|
||||
"Enter your private key:": "秘密鍵を入力してください:",
|
||||
" Signed!": " Signed!",
|
||||
" Signed!": " 署名しました!",
|
||||
"WebGL not supported": "WebGLはサポートされていません"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.menu {
|
||||
font-family: Roboto, 'Segoe UI', 'Helvetica Neue';
|
||||
font-family: Roboto, 'Segoe UI', 'Helvetica Neue'; z-index: 999;
|
||||
}
|
||||
|
||||
.drag-bg { width: 100%; height: 100%; position: fixed; }
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
|
||||
|
||||
.menu {
|
||||
font-family: Roboto, 'Segoe UI', 'Helvetica Neue';
|
||||
font-family: Roboto, 'Segoe UI', 'Helvetica Neue'; z-index: 999;
|
||||
}
|
||||
|
||||
.drag-bg { width: 100%; height: 100%; position: fixed; }
|
||||
|
|
|
@ -2,7 +2,8 @@ import time
|
|||
import html
|
||||
import os
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
import sys
|
||||
import itertools
|
||||
|
||||
from Plugin import PluginManager
|
||||
from Config import config
|
||||
|
@ -35,40 +36,9 @@ class UiRequestPlugin(object):
|
|||
else:
|
||||
return 0
|
||||
|
||||
# /Stats entry point
|
||||
@helper.encodeResponse
|
||||
def actionStats(self):
|
||||
import gc
|
||||
import sys
|
||||
from Ui import UiRequest
|
||||
from Crypt import CryptConnection
|
||||
def renderHead(self):
|
||||
import main
|
||||
|
||||
|
||||
hpy = None
|
||||
if self.get.get("size") == "1": # Calc obj size
|
||||
try:
|
||||
import guppy
|
||||
hpy = guppy.hpy()
|
||||
except:
|
||||
pass
|
||||
self.sendHeader()
|
||||
|
||||
if "Multiuser" in PluginManager.plugin_manager.plugin_names and not config.multiuser_local:
|
||||
yield "This function is disabled on this proxy"
|
||||
return
|
||||
|
||||
s = time.time()
|
||||
|
||||
# Style
|
||||
yield """
|
||||
<style>
|
||||
* { font-family: monospace }
|
||||
table td, table th { text-align: right; padding: 0px 10px }
|
||||
.connections td { white-space: nowrap }
|
||||
.serving-False { opacity: 0.3 }
|
||||
</style>
|
||||
"""
|
||||
from Crypt import CryptConnection
|
||||
|
||||
# Memory
|
||||
yield "rev%s | " % config.rev
|
||||
|
@ -99,9 +69,13 @@ class UiRequestPlugin(object):
|
|||
pass
|
||||
yield "<br>"
|
||||
|
||||
def renderConnectionsTable(self):
|
||||
import main
|
||||
|
||||
# Connections
|
||||
yield "<b>Connections</b> (%s, total made: %s, in: %s, out: %s):<br>" % (
|
||||
len(main.file_server.connections), main.file_server.last_connection_id, main.file_server.num_incoming, main.file_server.num_outgoing
|
||||
len(main.file_server.connections), main.file_server.last_connection_id,
|
||||
main.file_server.num_incoming, main.file_server.num_outgoing
|
||||
)
|
||||
yield "<table class='connections'><tr> <th>id</th> <th>type</th> <th>ip</th> <th>open</th> <th>crypt</th> <th>ping</th>"
|
||||
yield "<th>buff</th> <th>bad</th> <th>idle</th> <th>open</th> <th>delay</th> <th>cpu</th> <th>out</th> <th>in</th> <th>last sent</th>"
|
||||
|
@ -140,10 +114,11 @@ class UiRequestPlugin(object):
|
|||
])
|
||||
yield "</table>"
|
||||
|
||||
def renderTrackers(self):
|
||||
# Trackers
|
||||
yield "<br><br><b>Trackers:</b><br>"
|
||||
yield "<table class='trackers'><tr> <th>address</th> <th>request</th> <th>successive errors</th> <th>last_request</th></tr>"
|
||||
from Site import SiteAnnouncer # importing at the top of the file breaks plugins
|
||||
from Site import SiteAnnouncer # importing at the top of the file breaks plugins
|
||||
for tracker_address, tracker_stat in sorted(SiteAnnouncer.global_stats.items()):
|
||||
yield self.formatTableRow([
|
||||
("%s", tracker_address),
|
||||
|
@ -168,12 +143,13 @@ class UiRequestPlugin(object):
|
|||
])
|
||||
yield "</table>"
|
||||
|
||||
# Tor hidden services
|
||||
def renderTor(self):
|
||||
import main
|
||||
yield "<br><br><b>Tor hidden services (status: %s):</b><br>" % main.file_server.tor_manager.status
|
||||
for site_address, onion in list(main.file_server.tor_manager.site_onions.items()):
|
||||
yield "- %-34s: %s<br>" % (site_address, onion)
|
||||
|
||||
# Db
|
||||
def renderDbStats(self):
|
||||
yield "<br><br><b>Db</b>:<br>"
|
||||
for db in Db.opened_dbs:
|
||||
tables = [row["name"] for row in db.execute("SELECT name FROM sqlite_master WHERE type = 'table'").fetchall()]
|
||||
|
@ -185,8 +161,7 @@ class UiRequestPlugin(object):
|
|||
time.time() - db.last_query_time, db.db_path, db_size, json.dumps(table_rows, sort_keys=True)
|
||||
)
|
||||
|
||||
|
||||
# Sites
|
||||
def renderSites(self):
|
||||
yield "<br><br><b>Sites</b>:"
|
||||
yield "<table>"
|
||||
yield "<tr><th>address</th> <th>connected</th> <th title='connected/good/total'>peers</th> <th>content.json</th> <th>out</th> <th>in</th> </tr>"
|
||||
|
@ -226,7 +201,7 @@ class UiRequestPlugin(object):
|
|||
yield "<br></td></tr>"
|
||||
yield "</table>"
|
||||
|
||||
# Big files
|
||||
def renderBigfiles(self):
|
||||
yield "<br><br><b>Big files</b>:<br>"
|
||||
for site in list(self.server.sites.values()):
|
||||
if not site.settings.get("has_bigfile"):
|
||||
|
@ -250,7 +225,8 @@ class UiRequestPlugin(object):
|
|||
yield "</table>"
|
||||
yield "</div>"
|
||||
|
||||
# Cmd stats
|
||||
def renderRequests(self):
|
||||
import main
|
||||
yield "<div style='float: left'>"
|
||||
yield "<br><br><b>Sent commands</b>:<br>"
|
||||
yield "<table>"
|
||||
|
@ -268,9 +244,18 @@ class UiRequestPlugin(object):
|
|||
yield "</div>"
|
||||
yield "<div style='clear: both'></div>"
|
||||
|
||||
# No more if not in debug mode
|
||||
if not config.debug:
|
||||
return
|
||||
def renderMemory(self):
|
||||
import gc
|
||||
from Ui import UiRequest
|
||||
|
||||
hpy = None
|
||||
if self.get.get("size") == "1": # Calc obj size
|
||||
try:
|
||||
import guppy
|
||||
hpy = guppy.hpy()
|
||||
except Exception:
|
||||
pass
|
||||
self.sendHeader()
|
||||
|
||||
# Object types
|
||||
|
||||
|
@ -371,6 +356,48 @@ class UiRequestPlugin(object):
|
|||
for module_name, module in objs:
|
||||
yield " - %.3fkb: %s %s<br>" % (self.getObjSize(module, hpy), module_name, html.escape(repr(module)))
|
||||
|
||||
# /Stats entry point
|
||||
@helper.encodeResponse
|
||||
def actionStats(self):
|
||||
import gc
|
||||
|
||||
self.sendHeader()
|
||||
|
||||
if "Multiuser" in PluginManager.plugin_manager.plugin_names and not config.multiuser_local:
|
||||
yield "This function is disabled on this proxy"
|
||||
return
|
||||
|
||||
s = time.time()
|
||||
|
||||
# Style
|
||||
yield """
|
||||
<style>
|
||||
* { font-family: monospace }
|
||||
table td, table th { text-align: right; padding: 0px 10px }
|
||||
.connections td { white-space: nowrap }
|
||||
.serving-False { opacity: 0.3 }
|
||||
</style>
|
||||
"""
|
||||
|
||||
renderers = [
|
||||
self.renderHead(),
|
||||
self.renderConnectionsTable(),
|
||||
self.renderTrackers(),
|
||||
self.renderTor(),
|
||||
self.renderDbStats(),
|
||||
self.renderSites(),
|
||||
self.renderBigfiles(),
|
||||
self.renderRequests()
|
||||
|
||||
]
|
||||
|
||||
for part in itertools.chain(*renderers):
|
||||
yield part
|
||||
|
||||
if config.debug:
|
||||
for part in self.renderMemory():
|
||||
yield part
|
||||
|
||||
gc.collect() # Implicit grabage collection
|
||||
yield "Done in %.1f" % (time.time() - s)
|
||||
|
||||
|
@ -457,7 +484,7 @@ class UiRequestPlugin(object):
|
|||
yield "%.1fkb <span title=\"%s\">%s</span>... " % (
|
||||
float(sys.getsizeof(obj)) / 1024, html.escape(str(obj)), html.escape(str(obj)[0:100].ljust(100))
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
continue
|
||||
for ref in refs:
|
||||
yield " ["
|
||||
|
@ -485,3 +512,116 @@ class UiRequestPlugin(object):
|
|||
import gc
|
||||
self.sendHeader()
|
||||
yield str(gc.collect())
|
||||
|
||||
# /About entry point
|
||||
@helper.encodeResponse
|
||||
def actionEnv(self):
|
||||
import main
|
||||
|
||||
self.sendHeader()
|
||||
|
||||
yield """
|
||||
<style>
|
||||
* { font-family: monospace; white-space: pre; }
|
||||
h2 { font-size: 100%; margin-bottom: 0px; }
|
||||
small { opacity: 0.5; }
|
||||
table { border-collapse: collapse; }
|
||||
td { padding-right: 10px; }
|
||||
</style>
|
||||
"""
|
||||
|
||||
if "Multiuser" in PluginManager.plugin_manager.plugin_names and not config.multiuser_local:
|
||||
yield "This function is disabled on this proxy"
|
||||
return
|
||||
|
||||
yield from main.actions.testEnv(format="html")
|
||||
|
||||
|
||||
@PluginManager.registerTo("Actions")
|
||||
class ActionsPlugin:
|
||||
def formatTable(self, *rows, format="text"):
|
||||
if format == "html":
|
||||
return self.formatTableHtml(*rows)
|
||||
else:
|
||||
return self.formatTableText(*rows)
|
||||
|
||||
def formatHead(self, title, format="text"):
|
||||
if format == "html":
|
||||
return "<h2>%s</h2>" % title
|
||||
else:
|
||||
return "\n* %s\n" % title
|
||||
|
||||
def formatTableHtml(self, *rows):
|
||||
yield "<table>"
|
||||
for row in rows:
|
||||
yield "<tr>"
|
||||
for col in row:
|
||||
yield "<td>%s</td>" % html.escape(str(col))
|
||||
yield "</tr>"
|
||||
yield "</table>"
|
||||
|
||||
def formatTableText(self, *rows):
|
||||
for row in rows:
|
||||
yield " "
|
||||
for col in row:
|
||||
yield " " + str(col)
|
||||
yield "\n"
|
||||
|
||||
def testEnv(self, format="text"):
|
||||
import gevent
|
||||
import msgpack
|
||||
import pkg_resources
|
||||
import importlib
|
||||
import coincurve
|
||||
import sqlite3
|
||||
from Crypt import CryptBitcoin
|
||||
|
||||
yield "\n"
|
||||
|
||||
yield from self.formatTable(
|
||||
["ZeroNet version:", "%s rev%s" % (config.version, config.rev)],
|
||||
["Python:", "%s" % sys.version],
|
||||
["Platform:", "%s" % sys.platform],
|
||||
["Crypt verify lib:", "%s" % CryptBitcoin.lib_verify_best],
|
||||
["OpenSSL:", "%s" % CryptBitcoin.sslcrypto.ecc.get_backend()],
|
||||
["Libsecp256k1:", "%s" % type(coincurve._libsecp256k1.lib).__name__],
|
||||
["SQLite:", "%s, API: %s" % (sqlite3.sqlite_version, sqlite3.version)],
|
||||
format=format
|
||||
)
|
||||
|
||||
|
||||
yield self.formatHead("Libraries:")
|
||||
rows = []
|
||||
for lib_name in ["gevent", "greenlet", "msgpack", "base58", "merkletools", "rsa", "socks", "pyasn1", "gevent_ws", "websocket", "maxminddb"]:
|
||||
try:
|
||||
module = importlib.import_module(lib_name)
|
||||
if "__version__" in dir(module):
|
||||
version = module.__version__
|
||||
elif "version" in dir(module):
|
||||
version = module.version
|
||||
else:
|
||||
version = "unknown version"
|
||||
|
||||
if type(version) is tuple:
|
||||
version = ".".join(map(str, version))
|
||||
|
||||
rows.append(["- %s:" % lib_name, version, "at " + module.__file__])
|
||||
except Exception as err:
|
||||
rows.append(["! Error importing %s:", repr(err)])
|
||||
|
||||
"""
|
||||
try:
|
||||
yield " - %s<br>" % html.escape(repr(pkg_resources.get_distribution(lib_name)))
|
||||
except Exception as err:
|
||||
yield " ! %s<br>" % html.escape(repr(err))
|
||||
"""
|
||||
|
||||
yield from self.formatTable(*rows, format=format)
|
||||
|
||||
yield self.formatHead("Library config:", format=format)
|
||||
|
||||
yield from self.formatTable(
|
||||
["- gevent:", gevent.config.loop.__module__],
|
||||
["- msgpack unpacker:", msgpack.Unpacker.__module__],
|
||||
format=format
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"ZeroNet Twitter": "ZeroNet Twitter",
|
||||
"ZeroNet Reddit": "ZeroNet Reddit",
|
||||
"ZeroNet Github": "ZeroNet Github",
|
||||
"Report bug/request feature": "Rapport d'erreur/Demanger une fonctionnalité",
|
||||
"Report bug/request feature": "Rapport d'erreur/Demander une fonctionnalité",
|
||||
"!Open ZeroNet": "!Ouvrir ZeroNet",
|
||||
"Quit": "Quitter",
|
||||
"(active)": "(actif)",
|
||||
|
|
14
plugins/Trayicon/languages/jp.json
Normal file
14
plugins/Trayicon/languages/jp.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"ZeroNet Twitter": "ZeroNet Twitter",
|
||||
"ZeroNet Reddit": "ZeroNet Reddit",
|
||||
"ZeroNet Github": "ZeroNet Github",
|
||||
"Report bug/request feature": "バグ報告/要望",
|
||||
"!Open ZeroNet": "!ZeroNetをブラウザで開く",
|
||||
"Quit": "閉じる",
|
||||
"(active)": "(アクティブ)",
|
||||
"(passive)": "(パッシブ)",
|
||||
"Connections: %s": "接続数: %s",
|
||||
"Received: %.2f MB | Sent: %.2f MB": "受信: %.2f MB | 送信: %.2f MB",
|
||||
"Show console window": "コンソールを表示",
|
||||
"Start ZeroNet when Windows starts": "Windows起動時にZeroNetも起動する"
|
||||
}
|
62
plugins/UiConfig/languages/jp.json
Normal file
62
plugins/UiConfig/languages/jp.json
Normal file
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"ZeroNet config": "ZeroNetの設定",
|
||||
"Web Interface": "WEBインターフェース",
|
||||
"Open web browser on ZeroNet startup": "ZeroNet起動時に自動でブラウザーを開く",
|
||||
|
||||
"Network": "ネットワーク",
|
||||
"Offline mode": "オフラインモード",
|
||||
"Disable network communication.": "通信を無効化します",
|
||||
"File server network": "ファイルサーバネットワーク",
|
||||
"Accept incoming peers using IPv4 or IPv6 address. (default: dual)": "IPv4とIPv6からの受信を許可(既定: 両方)",
|
||||
"Dual (IPv4 & IPv6)": "両方 (IPv4 & IPv6)",
|
||||
"File server port": "ファイルサーバのポート",
|
||||
"Other peers will use this port to reach your served sites. (default: randomize)": "他のピアはこのポートを使用してあなたが所持しているサイトにアクセスします (既定: ランダム)",
|
||||
"File server external ip": "ファイルサーバの外部IP",
|
||||
"Detect automatically": "自動検出",
|
||||
"Your file server is accessible on these ips. (default: detect automatically)": "あなたのファイルサーバへはここで設定したIPでアクセスできます (既定: 自動検出)",
|
||||
|
||||
"Disable: Don't connect to peers on Tor network": "無効: Torネットワーク上のピアに接続しない",
|
||||
"Enable: Only use Tor for Tor network peers": "有効: Torネットワーク上のピアに対してのみTorを使って接続する",
|
||||
"Always: Use Tor for every connections to hide your IP address (slower)": "常時: 全ての接続にTorを使いIPを秘匿する(低速)",
|
||||
|
||||
"Disable": "無効",
|
||||
"Enable": "有効",
|
||||
"Always": "常時",
|
||||
|
||||
"Use Tor bridges": "Torブリッジを使用",
|
||||
"Use obfuscated bridge relays to avoid network level Tor block (even slower)": "難読化されたブリッジリレーを使用してネットワークレベルのTorブロックを避ける(超低速)",
|
||||
|
||||
"Discover new peers using these adresses": "ここで設定したアドレスを用いてピアを発見します",
|
||||
|
||||
"Trackers files": "トラッカーファイル",
|
||||
"Load additional list of torrent trackers dynamically, from a file": "ファイルからトレントラッカーの追加リストを動的に読み込みます",
|
||||
"Eg.: data/trackers.json": "例: data/trackers.json",
|
||||
|
||||
"Proxy for tracker connections": "トラッカーへの接続に使うプロキシ",
|
||||
"Custom": "カスタム",
|
||||
"Custom socks proxy address for trackers": "トラッカーに接続するためのカスタムsocksプロキシのアドレス",
|
||||
|
||||
"Performance": "性能",
|
||||
"Level of logging to file": "ログレベル",
|
||||
"Everything": "全て",
|
||||
"Only important messages": "重要なメッセージのみ",
|
||||
"Only errors": "エラーのみ",
|
||||
"Threads for async file system reads": "非同期ファイルシステムの読み込みに使うスレッド",
|
||||
"Threads for async file system writes": "非同期ファイルシステムの書き込みに使うスレッド",
|
||||
"Threads for cryptographic functions": "暗号機能に使うスレッド",
|
||||
"Threads for database operations": "データベースの操作に使うスレッド",
|
||||
"Sync read": "同期読み取り",
|
||||
"Sync write": "同期書き込み",
|
||||
"Sync execution": "同期実行",
|
||||
"1 thread": "1スレッド",
|
||||
"2 threads": "2スレッド",
|
||||
"3 threads": "3スレッド",
|
||||
"4 threads": "4スレッド",
|
||||
"5 threads": "5スレッド",
|
||||
"10 threads": "10スレッド",
|
||||
|
||||
" configuration item value changed": " の項目の値が変更されました",
|
||||
"Save settings": "設定を保存",
|
||||
"Some changed settings requires restart": "一部の変更の適用には再起動が必要です。",
|
||||
"Restart ZeroNet client": "ZeroNetクライアントを再起動"
|
||||
}
|
|
@ -73,11 +73,17 @@ class UiFileManagerPlugin(object):
|
|||
return super().error404(path)
|
||||
|
||||
path_parts = self.parsePath(path)
|
||||
if not path_parts:
|
||||
return super().error404(path)
|
||||
|
||||
site = self.server.site_manager.get(path_parts["request_address"])
|
||||
|
||||
if not site or not site.content_manager.contents.get("content.json"):
|
||||
return super().error404(path)
|
||||
|
||||
if path_parts["inner_path"] in site.content_manager.contents.get("content.json").get("files", {}):
|
||||
return super().error404(path)
|
||||
|
||||
self.sendHeader(200)
|
||||
path_redirect = "/list" + re.sub("^/media/", "/", path)
|
||||
self.log.debug("Index.html not found: %s, redirecting to: %s" % (path, path_redirect))
|
||||
|
|
20
plugins/UiFileManager/languages/jp.json
Normal file
20
plugins/UiFileManager/languages/jp.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"New file name:": "新しいファイルの名前:",
|
||||
"Delete": "削除",
|
||||
"Cancel": "キャンセル",
|
||||
"Selected:": "選択済み: ",
|
||||
"Delete and remove optional:": "オプションを削除",
|
||||
" files": " ファイル",
|
||||
" (modified)": " (編集済み)",
|
||||
" (new)": " (新しい)",
|
||||
" (optional)": " (オプション)",
|
||||
" (ignored from content.json)": " (content.jsonから無視されます)",
|
||||
"Total: ": "合計: ",
|
||||
" dir, ": " のディレクトリ, ",
|
||||
" file in ": " のファイル, ",
|
||||
"+ New": "+ 新規作成",
|
||||
"Edit": "編集",
|
||||
"View": "閲覧",
|
||||
"Save": "保存",
|
||||
"Save: done!": "保存完了!"
|
||||
}
|
15
plugins/UiFileManager/media/js/Config.coffee
Normal file
15
plugins/UiFileManager/media/js/Config.coffee
Normal file
|
@ -0,0 +1,15 @@
|
|||
window.BINARY_EXTENSIONS = [
|
||||
"3dm", "3ds", "3g2", "3gp", "7z", "a", "aac", "adp", "ai", "aif", "aiff", "alz", "ape", "apk", "appimage", "ar", "arj", "asc", "asf", "au", "avi", "bak",
|
||||
"baml", "bh", "bin", "bk", "bmp", "btif", "bz2", "bzip2", "cab", "caf", "cgm", "class", "cmx", "cpio", "cr2", "cur", "dat", "dcm", "deb", "dex", "djvu",
|
||||
"dll", "dmg", "dng", "doc", "docm", "docx", "dot", "dotm", "dra", "DS_Store", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ecelp4800", "ecelp7470",
|
||||
"ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "flatpak", "fli", "flv", "fpx", "fst", "fvt", "g3", "gh", "gif",
|
||||
"gpg", "graffle", "gz", "gzip", "h261", "h263", "h264", "icns", "ico", "ief", "img", "ipa", "iso", "jar", "jpeg", "jpg", "jpgv", "jpm", "jxr", "key",
|
||||
"ktx", "lha", "lib", "lvp", "lz", "lzh", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mht", "mid", "midi", "mj2", "mka", "mkv", "mmr", "mng",
|
||||
"mobi", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "msgpack", "mxu", "nef", "npx", "numbers", "nupkg", "o", "oga", "ogg", "ogv",
|
||||
"otf", "pages", "pbm", "pcx", "pdb", "pdf", "pea", "pgm", "pic", "png", "pnm", "pot", "potm", "potx", "ppa", "ppam", "ppm", "pps", "ppsm", "ppsx",
|
||||
"ppt", "pptm", "pptx", "psd", "pya", "pyc", "pyo", "pyv", "qt", "rar", "ras", "raw", "resources", "rgb", "rip", "rlc", "rmf", "rmvb", "rpm", "rtf",
|
||||
"rz", "s3m", "s7z", "scpt", "sgi", "shar", "sig", "sil", "sketch", "slk", "smv", "snap", "snk", "so", "stl", "sub", "suo", "swf", "tar", "tbz2", "tbz",
|
||||
"tga", "tgz", "thmx", "tif", "tiff", "tlz", "ttc", "ttf", "txz", "udf", "uvh", "uvi", "uvm", "uvp", "uvs", "uvu", "viv", "vob", "war", "wav", "wax",
|
||||
"wbmp", "wdp", "weba", "webm", "webp", "whl", "wim", "wm", "wma", "wmv", "wmx", "woff2", "woff", "wrm", "wvx", "xbm", "xif", "xla", "xlam", "xls",
|
||||
"xlsb", "xlsm", "xlsx", "xlt", "xltm", "xltx", "xm", "xmind", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx"
|
||||
]
|
|
@ -1,5 +1,3 @@
|
|||
BINARY_EXTENSIONS = ["png", "gif", "jpg", "pdf", "doc", "msgpack", "zip", "rar", "gz", "tar", "exe"]
|
||||
|
||||
class FileList extends Class
|
||||
constructor: (@site, @inner_path, @is_owner=false) ->
|
||||
@need_update = true
|
||||
|
@ -179,7 +177,7 @@ class FileList extends Class
|
|||
ext = item.name.split(".").pop()
|
||||
|
||||
is_editing = inner_path == Page.file_editor?.inner_path
|
||||
is_editable = not is_dir and item.size < 1024 * 1024 and ext not in BINARY_EXTENSIONS
|
||||
is_editable = not is_dir and item.size < 1024 * 1024 and ext not in window.BINARY_EXTENSIONS
|
||||
is_modified = @item_list.isModified(inner_path)
|
||||
is_added = @item_list.isAdded(inner_path)
|
||||
optional_info = @item_list.getOptionalInfo(inner_path)
|
||||
|
@ -267,4 +265,4 @@ class FileList extends Class
|
|||
@renderFoot()
|
||||
])
|
||||
|
||||
window.FileList = FileList
|
||||
window.FileList = FileList
|
||||
|
|
|
@ -1918,6 +1918,15 @@
|
|||
}));
|
||||
|
||||
|
||||
/* ---- Config.coffee ---- */
|
||||
|
||||
|
||||
(function() {
|
||||
window.BINARY_EXTENSIONS = ["3dm", "3ds", "3g2", "3gp", "7z", "a", "aac", "adp", "ai", "aif", "aiff", "alz", "ape", "apk", "appimage", "ar", "arj", "asc", "asf", "au", "avi", "bak", "baml", "bh", "bin", "bk", "bmp", "btif", "bz2", "bzip2", "cab", "caf", "cgm", "class", "cmx", "cpio", "cr2", "cur", "dat", "dcm", "deb", "dex", "djvu", "dll", "dmg", "dng", "doc", "docm", "docx", "dot", "dotm", "dra", "DS_Store", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ecelp4800", "ecelp7470", "ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "flatpak", "fli", "flv", "fpx", "fst", "fvt", "g3", "gh", "gif", "gpg", "graffle", "gz", "gzip", "h261", "h263", "h264", "icns", "ico", "ief", "img", "ipa", "iso", "jar", "jpeg", "jpg", "jpgv", "jpm", "jxr", "key", "ktx", "lha", "lib", "lvp", "lz", "lzh", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mht", "mid", "midi", "mj2", "mka", "mkv", "mmr", "mng", "mobi", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "msgpack", "mxu", "nef", "npx", "numbers", "nupkg", "o", "oga", "ogg", "ogv", "otf", "pages", "pbm", "pcx", "pdb", "pdf", "pea", "pgm", "pic", "png", "pnm", "pot", "potm", "potx", "ppa", "ppam", "ppm", "pps", "ppsm", "ppsx", "ppt", "pptm", "pptx", "psd", "pya", "pyc", "pyo", "pyv", "qt", "rar", "ras", "raw", "resources", "rgb", "rip", "rlc", "rmf", "rmvb", "rpm", "rtf", "rz", "s3m", "s7z", "scpt", "sgi", "shar", "sig", "sil", "sketch", "slk", "smv", "snap", "snk", "so", "stl", "sub", "suo", "swf", "tar", "tbz2", "tbz", "tga", "tgz", "thmx", "tif", "tiff", "tlz", "ttc", "ttf", "txz", "udf", "uvh", "uvi", "uvm", "uvp", "uvs", "uvu", "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wim", "wm", "wma", "wmv", "wmx", "woff2", "woff", "wrm", "wvx", "xbm", "xif", "xla", "xlam", "xls", "xlsb", "xlsm", "xlsx", "xlt", "xltm", "xltx", "xm", "xmind", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx"];
|
||||
|
||||
}).call(this);
|
||||
|
||||
|
||||
/* ---- FileEditor.coffee ---- */
|
||||
|
||||
|
||||
|
@ -2187,7 +2196,6 @@
|
|||
|
||||
}).call(this);
|
||||
|
||||
|
||||
/* ---- FileItemList.coffee ---- */
|
||||
|
||||
|
||||
|
@ -2477,14 +2485,12 @@
|
|||
|
||||
|
||||
(function() {
|
||||
var BINARY_EXTENSIONS, FileList,
|
||||
var FileList,
|
||||
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
hasProp = {}.hasOwnProperty,
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
BINARY_EXTENSIONS = ["png", "gif", "jpg", "pdf", "doc", "msgpack", "zip", "rar", "gz", "tar", "exe"];
|
||||
|
||||
FileList = (function(superClass) {
|
||||
extend(FileList, superClass);
|
||||
|
||||
|
@ -2759,7 +2765,7 @@
|
|||
is_dir = (ref = item.type) === "dir" || ref === "parent";
|
||||
ext = item.name.split(".").pop();
|
||||
is_editing = inner_path === ((ref1 = Page.file_editor) != null ? ref1.inner_path : void 0);
|
||||
is_editable = !is_dir && item.size < 1024 * 1024 && indexOf.call(BINARY_EXTENSIONS, ext) < 0;
|
||||
is_editable = !is_dir && item.size < 1024 * 1024 && indexOf.call(window.BINARY_EXTENSIONS, ext) < 0;
|
||||
is_modified = this.item_list.isModified(inner_path);
|
||||
is_added = this.item_list.isAdded(inner_path);
|
||||
optional_info = this.item_list.getOptionalInfo(inner_path);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue