");
+ formatted = formatted.replace(/(\== Result ==[^]*)/, "
$1
");
var is_bottom = document.body.scrollTop + document.body.clientHeight >= document.body.scrollHeight - 5;
elem.innerHTML = formatted.trim();
if (is_bottom)
diff --git a/plugins/ContentFilter/languages/jp.json b/plugins/ContentFilter/languages/jp.json
new file mode 100644
index 00000000..ef586a1a
--- /dev/null
+++ b/plugins/ContentFilter/languages/jp.json
@@ -0,0 +1,6 @@
+{
+ "Hide all content from %s?": "%s のコンテンツをすべて隠しますか?",
+ "Mute": "ミュート",
+ "Unmute %s?": "%s のミュートを解除しますか?",
+ "Unmute": "ミュート解除"
+}
diff --git a/plugins/MergerSite/languages/jp.json b/plugins/MergerSite/languages/jp.json
new file mode 100644
index 00000000..7216f268
--- /dev/null
+++ b/plugins/MergerSite/languages/jp.json
@@ -0,0 +1,5 @@
+{
+ "Add %s new site?": "サイト: %s を追加しますか?",
+ "Added %s new site": "サイト: %s を追加しました",
+ "Site deleted: %s": "サイト: %s を削除しました"
+}
diff --git a/plugins/OptionalManager/UiWebsocketPlugin.py b/plugins/OptionalManager/UiWebsocketPlugin.py
index 103bbe84..0acc53cf 100644
--- a/plugins/OptionalManager/UiWebsocketPlugin.py
+++ b/plugins/OptionalManager/UiWebsocketPlugin.py
@@ -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
diff --git a/plugins/OptionalManager/languages/jp.json b/plugins/OptionalManager/languages/jp.json
new file mode 100644
index 00000000..af6dc79e
--- /dev/null
+++ b/plugins/OptionalManager/languages/jp.json
@@ -0,0 +1,7 @@
+{
+ "Pinned %s files": "%s 件のファイルを固定",
+ "Removed pin from %s files": "%s 件のファイルの固定を解除",
+ "You started to help distribute %s. Directory: %s": "あなたはサイト: %s の配布の援助を開始しました。 ディレクトリ: %s",
+ "Help distribute all new optional files on site %s": "サイト: %s のすべての新しいオプションファイルの配布を援助しますか?",
+ "Yes, I want to help!": "はい、やります!"
+}
diff --git a/plugins/Sidebar/languages/jp.json b/plugins/Sidebar/languages/jp.json
index 99b34564..38bbd420 100644
--- a/plugins/Sidebar/languages/jp.json
+++ b/plugins/Sidebar/languages/jp.json
@@ -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: {}! Please download manually and unpack to data dir: {}": "GeoLite2 Cityデータベースのダウンロードエラー: {}! 手動でダウンロードして、フォルダに解凍してください。: {}",
@@ -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はサポートされていません"
}
diff --git a/plugins/Sidebar/media/Sidebar.css b/plugins/Sidebar/media/Sidebar.css
index 8ce16ec7..04ae1ba7 100644
--- a/plugins/Sidebar/media/Sidebar.css
+++ b/plugins/Sidebar/media/Sidebar.css
@@ -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; }
diff --git a/plugins/Sidebar/media/all.css b/plugins/Sidebar/media/all.css
index 056d7e89..9411d32a 100644
--- a/plugins/Sidebar/media/all.css
+++ b/plugins/Sidebar/media/all.css
@@ -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; }
diff --git a/plugins/Stats/StatsPlugin.py b/plugins/Stats/StatsPlugin.py
index f164ce8f..32fd06c5 100644
--- a/plugins/Stats/StatsPlugin.py
+++ b/plugins/Stats/StatsPlugin.py
@@ -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 """
-
- """
+ from Crypt import CryptConnection
# Memory
yield "rev%s | " % config.rev
@@ -99,9 +69,13 @@ class UiRequestPlugin(object):
pass
yield " "
+ def renderConnectionsTable(self):
+ import main
+
# Connections
yield "Connections (%s, total made: %s, in: %s, out: %s): " % (
- 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 "
id
type
ip
open
crypt
ping
"
yield "
buff
bad
idle
open
delay
cpu
out
in
last sent
"
@@ -140,10 +114,11 @@ class UiRequestPlugin(object):
])
yield "
"
+ def renderTrackers(self):
# Trackers
yield "
Trackers: "
yield "
address
request
successive errors
last_request
"
- 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 "
"
- # Tor hidden services
+ def renderTor(self):
+ import main
yield "
Tor hidden services (status: %s): " % main.file_server.tor_manager.status
for site_address, onion in list(main.file_server.tor_manager.site_onions.items()):
yield "- %-34s: %s " % (site_address, onion)
- # Db
+ def renderDbStats(self):
yield "
Db: "
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 "
"
- # Big files
+ def renderBigfiles(self):
yield "
Big files: "
for site in list(self.server.sites.values()):
if not site.settings.get("has_bigfile"):
@@ -250,7 +225,8 @@ class UiRequestPlugin(object):
yield ""
yield ""
- # Cmd stats
+ def renderRequests(self):
+ import main
yield "
"
yield "
Sent commands: "
yield "
"
@@ -268,9 +244,18 @@ class UiRequestPlugin(object):
yield ""
yield ""
- # 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 " % (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 """
+
+ """
+
+ 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 %s... " % (
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 """
+
+ """
+
+ 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 "
%s
" % title
+ else:
+ return "\n* %s\n" % title
+
+ def formatTableHtml(self, *rows):
+ yield "
"
+ for row in rows:
+ yield "
"
+ for col in row:
+ yield "
%s
" % html.escape(str(col))
+ yield "
"
+ yield "
"
+
+ 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 " % html.escape(repr(pkg_resources.get_distribution(lib_name)))
+ except Exception as err:
+ yield " ! %s " % 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
+ )
diff --git a/plugins/Trayicon/languages/fr.json b/plugins/Trayicon/languages/fr.json
index ec335318..a6fca769 100644
--- a/plugins/Trayicon/languages/fr.json
+++ b/plugins/Trayicon/languages/fr.json
@@ -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)",
diff --git a/plugins/Trayicon/languages/jp.json b/plugins/Trayicon/languages/jp.json
new file mode 100644
index 00000000..aa28457b
--- /dev/null
+++ b/plugins/Trayicon/languages/jp.json
@@ -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も起動する"
+}
diff --git a/plugins/UiConfig/languages/jp.json b/plugins/UiConfig/languages/jp.json
new file mode 100644
index 00000000..08184b65
--- /dev/null
+++ b/plugins/UiConfig/languages/jp.json
@@ -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クライアントを再起動"
+}
diff --git a/plugins/UiFileManager/UiFileManagerPlugin.py b/plugins/UiFileManager/UiFileManagerPlugin.py
index 0af5bea9..040e1d22 100644
--- a/plugins/UiFileManager/UiFileManagerPlugin.py
+++ b/plugins/UiFileManager/UiFileManagerPlugin.py
@@ -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))
diff --git a/plugins/UiFileManager/languages/jp.json b/plugins/UiFileManager/languages/jp.json
new file mode 100644
index 00000000..6d874a61
--- /dev/null
+++ b/plugins/UiFileManager/languages/jp.json
@@ -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!": "保存完了!"
+}
diff --git a/plugins/UiFileManager/media/js/Config.coffee b/plugins/UiFileManager/media/js/Config.coffee
new file mode 100644
index 00000000..0e156bef
--- /dev/null
+++ b/plugins/UiFileManager/media/js/Config.coffee
@@ -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"
+]
diff --git a/plugins/UiFileManager/media/js/FileList.coffee b/plugins/UiFileManager/media/js/FileList.coffee
index 2e38c2ae..1b5089b0 100644
--- a/plugins/UiFileManager/media/js/FileList.coffee
+++ b/plugins/UiFileManager/media/js/FileList.coffee
@@ -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
\ No newline at end of file
+window.FileList = FileList
diff --git a/plugins/UiFileManager/media/js/all.js b/plugins/UiFileManager/media/js/all.js
index e8f866ff..4f9b2cbd 100644
--- a/plugins/UiFileManager/media/js/all.js
+++ b/plugins/UiFileManager/media/js/all.js
@@ -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);
diff --git a/src/Config.py b/src/Config.py
index a9e05a6f..f4a230dd 100644
--- a/src/Config.py
+++ b/src/Config.py
@@ -14,7 +14,7 @@ class Config(object):
def __init__(self, argv):
self.version = "0.7.2"
- self.rev = 4538
+ self.rev = 4555
self.argv = argv
self.action = None
self.test_parser = None
diff --git a/src/Crypt/CryptBitcoin.py b/src/Crypt/CryptBitcoin.py
index c81999dd..68b2caa2 100644
--- a/src/Crypt/CryptBitcoin.py
+++ b/src/Crypt/CryptBitcoin.py
@@ -7,6 +7,8 @@ import hashlib
from util.Electrum import dbl_format
from Config import config
+import util.OpensslFindPatch
+
lib_verify_best = "sslcrypto"
from lib import sslcrypto
@@ -28,6 +30,8 @@ def loadLib(lib_name, silent=False):
)
elif lib_name == "sslcrypto":
sslcurve = sslcurve_native
+ if sslcurve_native == sslcurve_fallback:
+ logging.warning("SSLCurve fallback loaded instead of native")
elif lib_name == "sslcrypto_fallback":
sslcurve = sslcurve_fallback
diff --git a/src/Debug/Debug.py b/src/Debug/Debug.py
index 12f084bc..0ec42615 100644
--- a/src/Debug/Debug.py
+++ b/src/Debug/Debug.py
@@ -28,7 +28,11 @@ def formatExceptionMessage(err):
return "%s: %s" % (err_type, err_message)
-python_lib_dir = os.path.dirname(os.__file__)
+python_lib_dirs = [path.replace("\\", "/") for path in sys.path if re.sub(r".*[\\/]", "", path) in ("site-packages", "dist-packages")]
+python_lib_dirs.append(os.path.dirname(os.__file__).replace("\\", "/")) # TODO: check if returns the correct path for PyPy
+
+root_dir = os.path.realpath(os.path.dirname(__file__) + "/../../")
+root_dir = root_dir.replace("\\", "/")
def formatTraceback(items, limit=None, fold_builtin=True):
@@ -40,30 +44,63 @@ def formatTraceback(items, limit=None, fold_builtin=True):
for path, line in items:
i += 1
is_last = i == len(items)
- dir_name, file_name = os.path.split(path.replace("\\", "/"))
+ path = path.replace("\\", "/")
- plugin_match = re.match(".*/plugins/(.+)$", dir_name)
- if plugin_match:
- file_title = "%s/%s" % (plugin_match.group(1), file_name)
- is_prev_builtin = False
- elif path.startswith(python_lib_dir):
- if is_prev_builtin and not is_last and fold_builtin:
- if back[-1] != "...":
- back.append("...")
- continue
+ if path.startswith("src/gevent/"):
+ file_title = "/" + path[len("src/gevent/"):]
+ is_builtin = True
+ is_skippable_builtin = False
+ elif path in ("", ""):
+ file_title = "(importlib)"
+ is_builtin = True
+ is_skippable_builtin = True
+ else:
+ is_skippable_builtin = False
+ for base in python_lib_dirs:
+ if path.startswith(base + "/"):
+ file_title = path[len(base + "/"):]
+ module_name, *tail = file_title.split("/")
+ if module_name.endswith(".py"):
+ module_name = module_name[:-3]
+ file_title = "/".join(["<%s>" % module_name] + tail)
+ is_builtin = True
+ break
else:
- file_title = path.replace(python_lib_dir, "").replace("\\", "/").strip("/").replace("site-packages/", "")
- is_prev_builtin = True
- else:
- file_title = file_name
- is_prev_builtin = False
+ is_builtin = False
+ for base in (root_dir + "/src", root_dir + "/plugins", root_dir):
+ if path.startswith(base + "/"):
+ file_title = path[len(base + "/"):]
+ break
+ else:
+ # For unknown paths, do our best to hide absolute path
+ file_title = path
+ for needle in ("/zeronet/", "/core/"):
+ if needle in file_title.lower():
+ file_title = "?/" + file_title[file_title.lower().rindex(needle) + len(needle):]
- if file_title == prev_file_title:
- back.append("%s" % line)
+ # Path compression: A/AB/ABC/X/Y.py -> ABC/X/Y.py
+ # E.g.: in 'Db/DbCursor.py' the directory part is unnecessary
+ if not file_title.startswith("/"):
+ prev_part = ""
+ for i, part in enumerate(file_title.split("/") + [""]):
+ if not part.startswith(prev_part):
+ break
+ prev_part = part
+ file_title = "/".join(file_title.split("/")[i - 1:])
+
+ if is_skippable_builtin and fold_builtin:
+ pass
+ elif is_builtin and is_prev_builtin and not is_last and fold_builtin:
+ if back[-1] != "...":
+ back.append("...")
else:
- back.append("%s line %s" % (file_title, line))
+ if file_title == prev_file_title:
+ back.append("%s" % line)
+ else:
+ back.append("%s line %s" % (file_title, line))
prev_file_title = file_title
+ is_prev_builtin = is_builtin
if limit and i >= limit:
back.append("...")
diff --git a/src/File/FileServer.py b/src/File/FileServer.py
index 66cefd39..7114849b 100644
--- a/src/File/FileServer.py
+++ b/src/File/FileServer.py
@@ -760,10 +760,6 @@ class FileServer(ConnectionServer):
self.stream_server.start()
except Exception as err:
log.error("Error listening on: %s:%s: %s" % (self.ip, self.port, err))
- if "ui_server" in dir(sys.modules["main"]):
- log.debug("Stopping UI Server.")
- sys.modules["main"].ui_server.stop()
- return False
if config.debug:
# Auto reload FileRequest on change
diff --git a/src/Test/TestDebug.py b/src/Test/TestDebug.py
new file mode 100644
index 00000000..e3eb20b3
--- /dev/null
+++ b/src/Test/TestDebug.py
@@ -0,0 +1,52 @@
+from Debug import Debug
+import gevent
+import os
+import re
+
+import pytest
+
+
+class TestDebug:
+ @pytest.mark.parametrize("items,expected", [
+ (["@/src/A/B/C.py:17"], ["A/B/C.py line 17"]), # basic test
+ (["@/src/Db/Db.py:17"], ["Db.py line 17"]), # path compression
+ (["%s:1" % __file__], ["TestDebug.py line 1"]),
+ (["@/plugins/Chart/ChartDb.py:100"], ["ChartDb.py line 100"]), # plugins
+ (["@/main.py:17"], ["main.py line 17"]), # root
+ (["@\\src\\Db\\__init__.py:17"], ["Db/__init__.py line 17"]), # Windows paths
+ ([":1"], []), # importlib builtins
+ ([":1"], []), # importlib builtins
+ (["/home/ivanq/ZeroNet/src/main.py:13"], ["?/src/main.py line 13"]), # best-effort anonymization
+ (["C:\\ZeroNet\\core\\src\\main.py:13"], ["?/src/main.py line 13"]),
+ (["/root/main.py:17"], ["/root/main.py line 17"]),
+ (["{gevent}:13"], ["/__init__.py line 13"]), # modules
+ (["{os}:13"], [" line 13"]), # python builtin modules
+ (["src/gevent/event.py:17"], ["/event.py line 17"]), # gevent-overriden __file__
+ (["@/src/Db/Db.py:17", "@/src/Db/DbQuery.py:1"], ["Db.py line 17", "DbQuery.py line 1"]), # mutliple args
+ (["@/src/Db/Db.py:17", "@/src/Db/Db.py:1"], ["Db.py line 17", "1"]), # same file
+ (["{os}:1", "@/src/Db/Db.py:17"], [" line 1", "Db.py line 17"]), # builtins
+ (["{gevent}:1"] + ["{os}:3"] * 4 + ["@/src/Db/Db.py:17"], ["/__init__.py line 1", "...", "Db.py line 17"])
+ ])
+ def testFormatTraceback(self, items, expected):
+ q_items = []
+ for item in items:
+ file, line = item.rsplit(":", 1)
+ if file.startswith("@"):
+ file = Debug.root_dir + file[1:]
+ file = file.replace("{os}", os.__file__)
+ file = file.replace("{gevent}", gevent.__file__)
+ q_items.append((file, int(line)))
+ assert Debug.formatTraceback(q_items) == expected
+
+ def testFormatException(self):
+ try:
+ raise ValueError("Test exception")
+ except Exception:
+ assert re.match(r"ValueError: Test exception in TestDebug.py line [0-9]+", Debug.formatException())
+ try:
+ os.path.abspath(1)
+ except Exception:
+ assert re.search(r"in TestDebug.py line [0-9]+ > <(posixpath|ntpath)> line ", Debug.formatException())
+
+ def testFormatStack(self):
+ assert re.match(r"TestDebug.py line [0-9]+ > <_pytest>/python.py line [0-9]+", Debug.formatStack())
diff --git a/src/Translate/languages/jp.json b/src/Translate/languages/jp.json
index 5f858dd6..ff10aee4 100644
--- a/src/Translate/languages/jp.json
+++ b/src/Translate/languages/jp.json
@@ -8,11 +8,13 @@
"or configure Tor to become a full member of the ZeroNet network.": "または、TorをZeroNetネットワークのメンバーになるように設定してください。",
"Select account you want to use in this site:": "このサイトで使用するアカウントを選択:",
+ "No certificate": "証明書がありません",
"currently selected": "現在選択中",
"Unique to site": "サイト固有",
"Content signing failed": "コンテンツの署名に失敗",
"Content publish queued for {0:.0f} seconds.": "コンテンツの公開は{0:.0f}秒のキューに入れられました。",
+ "Content published to {0}/{1} peers.": "サイトの更新を通知済 {0}/{1} ピア",
"Content published to {0} peers.": "{0}ピアに公開されたコンテンツ。",
"No peers found, but your content is ready to access.": "ピアは見つかりませんでしたが、コンテンツにアクセスする準備ができました。",
"Your network connection is restricted. Please, open {0} port": "ネットワーク接続が制限されています。ポート {0} を開いて、",
@@ -43,6 +45,7 @@
"No peers found": "ピアが見つかりません",
"Running out of size limit (": "サイズ制限を使い果たしました (",
"Set limit to \" + site_info.next_size_limit + \"MB": "制限を \" + site_info.next_size_limit + \"MB に設定",
+ "Cloning site...": "サイトを複製中…",
"Site size limit changed to {0}MB": "サイトのサイズ制限が {0}MB に変更されました",
" New version of this page has just released. Reload to see the modified content.": " このページの新しいバージョンが公開されました。 変更されたコンテンツを見るには再読み込みしてください。",
"This site requests permission:": "このサイトは権限を要求しています:",
@@ -52,6 +55,12 @@
"Trackers announcing": "トラッカーをお知らせ",
"Error": "エラー",
"Done": "完了",
- "Tracker connection error detected.": "トラッカー接続エラーが検出されました。"
+ "Tracker connection error detected.": "トラッカー接続エラーが検出されました。",
+ "Update ZeroNet client to latest version?": "ZeroNetクライアントを最新版に更新しますか?",
+ "Update": "更新",
+ "Restart ZeroNet client?": "ZeroNetクライアントを再起動しますか?",
+ "Restart": "再起動",
+ "Shut down ZeroNet client?": "ZeroNetクライアントを終了しますか?",
+ "Shut down": "終了"
}
diff --git a/src/Ui/UiRequest.py b/src/Ui/UiRequest.py
index afbe3226..8f00efcb 100644
--- a/src/Ui/UiRequest.py
+++ b/src/Ui/UiRequest.py
@@ -33,6 +33,9 @@ content_types = {
"html": "text/html",
"js": "application/javascript",
"json": "application/json",
+ "oga": "audio/ogg",
+ "ogg": "application/ogg",
+ "ogv": "video/ogg",
"sig": "application/pgp-signature",
"txt": "text/plain",
"webmanifest": "application/manifest+json",
diff --git a/src/Ui/media/Infopanel.coffee b/src/Ui/media/Infopanel.coffee
index d728ccbe..3a490364 100644
--- a/src/Ui/media/Infopanel.coffee
+++ b/src/Ui/media/Infopanel.coffee
@@ -9,9 +9,16 @@ class Infopanel
else
@open()
+ unfold: =>
+ @elem.toggleClass("unfolded")
+ return false
+
updateEvents: =>
@elem.off("click")
@elem.find(".close").off("click")
+ @elem.find(".line").off("click")
+
+ @elem.find(".line").on("click", @unfold)
if @elem.hasClass("closed")
@elem.on "click", =>
diff --git a/src/Ui/media/Wrapper.coffee b/src/Ui/media/Wrapper.coffee
index 43cd033f..1b98855e 100644
--- a/src/Ui/media/Wrapper.coffee
+++ b/src/Ui/media/Wrapper.coffee
@@ -658,7 +658,7 @@ class Wrapper
else
@announcer_line = @loading.printLine(status_line)
- if status_db.error.length > (status_db.announced.length + status_db.announcing.length)
+ if status_db.error.length > (status_db.announced.length + status_db.announcing.length) and status_db.announced.length < 3
@loading.showTrackerTorBridge(@server_info)
updateProgress: (site_info) ->
diff --git a/src/Ui/media/Wrapper.css b/src/Ui/media/Wrapper.css
index 4ce0f61f..7c486081 100644
--- a/src/Ui/media/Wrapper.css
+++ b/src/Ui/media/Wrapper.css
@@ -131,6 +131,7 @@ a { color: black }
padding: 4px; border-top-left-radius: 6px; border-bottom-left-radius: 6px; font-size: 10px;
opacity: 0; margin-left: 0px; pointer-events: none; transition: all 0.6s;
}
+.infopanel.unfolded .message .line { overflow: visible; white-space: normal; }
.body-sidebar .infopanel { right: 425px; }
.body-sidebar .infopanel.closed { right: 0px; }
diff --git a/src/Ui/media/all.css b/src/Ui/media/all.css
index 8f4b459c..bd54cf34 100644
--- a/src/Ui/media/all.css
+++ b/src/Ui/media/all.css
@@ -144,6 +144,7 @@ a { color: black }
padding: 4px; border-top-left-radius: 6px; border-bottom-left-radius: 6px; font-size: 10px;
opacity: 0; margin-left: 0px; pointer-events: none; -webkit-transition: all 0.6s; -moz-transition: all 0.6s; -o-transition: all 0.6s; -ms-transition: all 0.6s; transition: all 0.6s ;
}
+.infopanel.unfolded .message .line { overflow: visible; white-space: normal; }
.body-sidebar .infopanel { right: 425px; }
.body-sidebar .infopanel.closed { right: 0px; }
diff --git a/src/Ui/media/all.js b/src/Ui/media/all.js
index de9ecd79..f5ad947c 100644
--- a/src/Ui/media/all.js
+++ b/src/Ui/media/all.js
@@ -548,6 +548,7 @@ $.extend( $.easing,
this.close = bind(this.close, this);
this.hide = bind(this.hide, this);
this.updateEvents = bind(this.updateEvents, this);
+ this.unfold = bind(this.unfold, this);
this.show = bind(this.show, this);
this.visible = false;
}
@@ -564,9 +565,16 @@ $.extend( $.easing,
}
};
+ Infopanel.prototype.unfold = function() {
+ this.elem.toggleClass("unfolded");
+ return false;
+ };
+
Infopanel.prototype.updateEvents = function() {
this.elem.off("click");
this.elem.find(".close").off("click");
+ this.elem.find(".line").off("click");
+ this.elem.find(".line").on("click", this.unfold);
if (this.elem.hasClass("closed")) {
return this.elem.on("click", (function(_this) {
return function() {
@@ -779,7 +787,6 @@ $.extend( $.easing,
}).call(this);
-
/* ---- Notifications.coffee ---- */
@@ -1910,7 +1917,7 @@ $.extend( $.easing,
} else {
this.announcer_line = this.loading.printLine(status_line);
}
- if (status_db.error.length > (status_db.announced.length + status_db.announcing.length)) {
+ if (status_db.error.length > (status_db.announced.length + status_db.announcing.length) && status_db.announced.length < 3) {
return this.loading.showTrackerTorBridge(this.server_info);
}
};
@@ -2004,6 +2011,7 @@ $.extend( $.easing,
}).call(this);
+
/* ---- WrapperZeroFrame.coffee ---- */
diff --git a/src/Ui/media/img/logo-white.png b/src/Ui/media/img/logo-white.png
deleted file mode 100644
index 3f28fb75..00000000
Binary files a/src/Ui/media/img/logo-white.png and /dev/null differ
diff --git a/src/Ui/media/img/logo-white.svg b/src/Ui/media/img/logo-white.svg
new file mode 100644
index 00000000..a6d85c74
--- /dev/null
+++ b/src/Ui/media/img/logo-white.svg
@@ -0,0 +1 @@
+
diff --git a/src/Ui/template/wrapper.html b/src/Ui/template/wrapper.html
index 8e1c6fbc..fe5a3f9c 100644
--- a/src/Ui/template/wrapper.html
+++ b/src/Ui/template/wrapper.html
@@ -38,7 +38,7 @@ else if (window.opener && window.opener.location.toString()) {
-
+
≡
diff --git a/src/main.py b/src/main.py
index ec04c9e3..80ecab2b 100644
--- a/src/main.py
+++ b/src/main.py
@@ -579,7 +579,7 @@ class Actions(object):
func_name = "test" + test_name[0].upper() + test_name[1:]
if hasattr(self, func_name):
func = getattr(self, func_name)
- print("- Running %s" % test_name, end="")
+ print("- Running test: %s" % test_name, end="")
s = time.time()
ret = func(*args, **kwargs)
if type(ret) is types.GeneratorType:
diff --git a/src/util/OpensslFindPatch.py b/src/util/OpensslFindPatch.py
index 80987876..0f5d2dc6 100644
--- a/src/util/OpensslFindPatch.py
+++ b/src/util/OpensslFindPatch.py
@@ -1,11 +1,12 @@
import logging
import os
import sys
-from ctypes.util import find_library
-from lib.sslcrypto.openssl import discovery
+import ctypes.util
from Config import config
+find_library_original = ctypes.util.find_library
+
def getOpensslPath():
if config.openssl_lib_file:
@@ -47,11 +48,22 @@ def getOpensslPath():
logging.debug("OpenSSL lib not found in: %s (%s)" % (path, err))
lib_path = (
- find_library('ssl.so') or find_library('ssl') or
- find_library('crypto') or find_library('libcrypto') or 'libeay32'
+ find_library_original('ssl.so') or find_library_original('ssl') or
+ find_library_original('crypto') or find_library_original('libcrypto') or 'libeay32'
)
return lib_path
-discovery.discover = getOpensslPath
+def patchCtypesOpensslFindLibrary():
+ def findLibraryPatched(name):
+ if name in ("ssl", "crypto", "libeay32"):
+ lib_path = getOpensslPath()
+ return lib_path
+ else:
+ return find_library_original(name)
+
+ ctypes.util.find_library = findLibraryPatched
+
+
+patchCtypesOpensslFindLibrary()
diff --git a/src/util/UpnpPunch.py b/src/util/UpnpPunch.py
index 48b497b6..18f4aaee 100644
--- a/src/util/UpnpPunch.py
+++ b/src/util/UpnpPunch.py
@@ -339,7 +339,7 @@ def _communicate_with_igd(port=15441,
success = True
break
- # Wait another 10sec for competition or any positibe result
+ # Wait another 10sec for competition or any positive result
for _ in range(10):
all_done = all([thread.value is not None for thread in threads])
any_succeed = any([thread.value for thread in threads])