From 16f1a683d2955ad5ac1fd0ca3794cc9abaa39d28 Mon Sep 17 00:00:00 2001 From: tianxiu2b2t Date: Thu, 18 Apr 2024 22:05:54 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BF=AEstats=EF=BC=88=E4=BF=AE=E7=9A=84?= =?UTF-8?q?=E6=88=91=E4=BA=BA=E8=A6=81=E7=82=B8=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/stats.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/core/stats.py b/core/stats.py index abc6811..1ce8bc1 100644 --- a/core/stats.py +++ b/core/stats.py @@ -5,8 +5,7 @@ from pathlib import Path import sqlite3 import time -import traceback -from typing import Any +import tracebackfrom typing import Any, Optional import pyzstd as zstd from tqdm import tqdm @@ -191,8 +190,8 @@ class GEOInfo: last_storages: dict[str, int] = {} last_ip: dict[str, int] = {} last_ua: int = 0 -last_hour: int = 0 -last_day: int = 0 +last_hour: Optional[int] = None +last_day: Optional[int] = None db: sqlite3.Connection = sqlite3.Connection("./cache/stats.db", check_same_thread=False) @@ -370,13 +369,16 @@ def _write_database(first: bool = False): executemany(*cmds) if first: logger.debug(f"执行SQL语句耗时 {time.monotonic() - start:.2f}") - if last_hour and last_hour != hour: + cur_day = get_day(0) + cur_hour = get_day(0) + if cur_hour != hour: for storage in storages.values(): storage.reset() - if last_day and last_day != day: + if cur_day != day: globalStats.reset() - last_day = get_day(0) - last_hour = get_hour(0) + last_day = cur_day + last_hour = cur_hour + def get_hour(hour: int) -> int: From c1ca071c428275b81f033cf282710610b3641746 Mon Sep 17 00:00:00 2001 From: tianxiu2b2t Date: Thu, 18 Apr 2024 22:06:58 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=88vscode=E5=B9=B2=E7=9A=84=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/stats.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/stats.py b/core/stats.py index 1ce8bc1..7530859 100644 --- a/core/stats.py +++ b/core/stats.py @@ -5,7 +5,8 @@ from pathlib import Path import sqlite3 import time -import tracebackfrom typing import Any, Optional +import traceback +from typing import Any, Optional import pyzstd as zstd from tqdm import tqdm From 1e9840c66eb0bacb9077d72e5a09b73cd59eef7a Mon Sep 17 00:00:00 2001 From: tianxiu2b2t Date: Thu, 18 Apr 2024 22:13:03 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E4=BF=AE=E7=BB=9F=E8=AE=A1=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/stats.py b/core/stats.py index 7530859..31de5a2 100644 --- a/core/stats.py +++ b/core/stats.py @@ -371,7 +371,7 @@ def _write_database(first: bool = False): if first: logger.debug(f"执行SQL语句耗时 {time.monotonic() - start:.2f}") cur_day = get_day(0) - cur_hour = get_day(0) + cur_hour = get_hour(0) if cur_hour != hour: for storage in storages.values(): storage.reset() From 801cb36caf62fe6cf1eee11fd66a586837d161ee Mon Sep 17 00:00:00 2001 From: tianxiu2b2t Date: Thu, 18 Apr 2024 22:15:32 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E5=A6=82=E6=9E=9C=E6=82=A8=E6=9C=89?= =?UTF-8?q?=E5=BC=BA=E8=BF=AB=E7=97=87=EF=BC=8C=E8=AF=B7=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1stats.db=E5=92=8Cstorage.bin=EF=BC=8C?= =?UTF-8?q?=E8=B0=A2=E8=B0=A2:)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bmclapi_dashboard/static/js/index.min.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/bmclapi_dashboard/static/js/index.min.js b/bmclapi_dashboard/static/js/index.min.js index 5152af8..86adecc 100644 --- a/bmclapi_dashboard/static/js/index.min.js +++ b/bmclapi_dashboard/static/js/index.min.js @@ -2569,16 +2569,18 @@ app.$Menu.add("dashboard", new class { value: e.value } }) - var name = $Country.filter(c => c.code == "CN")[0] || { - code: '', - name: '', - name_en: '' + if (cn_data != 0) { + var name = $Country.filter(c => c.code == "CN")[0] || { + code: '', + name: '', + name_en: '' + } + data.push({ + name: name.name_en, + display_name: name.name, + value: cn_data + }) } - data.push({ - name: name.name_en, - display_name: name.name, - value: cn_data - }) } else { data = this.global_stats.addresses.filter(e => e.country == "CN").map(e => { return { From 52cb7baf00e045f39d6a6abb82f4329f38af4470 Mon Sep 17 00:00:00 2001 From: tianxiu2b2t Date: Thu, 18 Apr 2024 23:08:01 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E5=85=A8=E9=83=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BA=86=E4=B8=AD=E6=96=87=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BA=86=E5=89=8D=E7=AB=AF=E9=80=9F=E5=BA=A6=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bmclapi_dashboard/static/js/index.min.js | 69 ++++++++++++++++++------ core/dashboard.py | 2 + core/stats.py | 33 ++---------- 3 files changed, 60 insertions(+), 44 deletions(-) diff --git a/bmclapi_dashboard/static/js/index.min.js b/bmclapi_dashboard/static/js/index.min.js index 86adecc..a7fccc3 100644 --- a/bmclapi_dashboard/static/js/index.min.js +++ b/bmclapi_dashboard/static/js/index.min.js @@ -525,15 +525,16 @@ class Application { this.$Style.applyTheme("light") } document.cookie = `theme=${this.$theme.containsClass("bxs-sun") ? "1" : "0"}; path=/` - }), + }) + this.menuButton = this.createElement("i").class("bx bx-menu").style("font-size: 32px").event("click", () => { + this.$side.toggle("hidden") + setTimeout(() => { + window.dispatchEvent(new Event("resize")) + }, 500) + }) this.$header = this.createElement("header").append( this.createElement("div").class("content").append( - this.createElement("i").class("bx bx-menu").style("font-size: 32px").event("click", () => { - this.$side.toggle("hidden") - setTimeout(() => { - window.dispatchEvent(new Event("resize")) - }, 500) - }), + this.menuButton, this.$theme, this.createElement("h3").append( this.createElement("a").setAttribute("href", $github).setText(document.title) @@ -553,6 +554,7 @@ class Application { this.$Style.setStyles(this.$styles) this.$Menu = new Menu(this, this.$side); this.$flexes = [] + if (window.outerWidth <= window.outerHeight * 1.75) this.menuButton.valueOf().click() window.addEventListener("resize", () => { for (const flex of this.$flexes) { flex.update(false) @@ -788,7 +790,7 @@ class Menu { for (const key in this.$menus) { const object = this.$menus[key] const div = app.createElement("div").class("menu") - div.append(app.createElement("div").setHTML(object.icon || ""), app.createElement("span").setText(key)).event("click", () => { + div.append(app.createElement("div").setHTML(object.icon || ""), app.createElement("span").setI18N("menu." + key)).event("click", () => { let page = key if (object.children.length != 0) { page += "/" + object.children[0].key @@ -806,7 +808,7 @@ class Menu { const subIndex = {} for (const subObject of object.children) { const subdiv = app.createElement("div").class("submenu") - subdiv.append(app.createElement("div").class("cycle").append(app.createElement("span")), app.createElement("div").class("text").append(app.createElement("span").setText(subObject.key))).event("click", () => { + subdiv.append(app.createElement("div").class("cycle").append(app.createElement("span")), app.createElement("div").class("text").append(app.createElement("span").setI18N("menu." + key + "." + subObject.key))).event("click", () => { let page = key + "/" + subObject.key this.$Router.route("/" + page) this.$Router.handler() @@ -1593,7 +1595,7 @@ class ElementSwitch extends Element { this.class("app-swtich-container") this.handlers = [] for (const bi in this.buttons) { - this.instancedbuttons.push((new Element("button")).class("app-switch-button").setText(this.buttons[bi]).event("click", (event) => { + this.instancedbuttons.push((new Element("button")).class("app-switch-button").setI18N(this.buttons[bi]).event("click", (event) => { this.click(this.instancedbuttons[bi], bi) })) } @@ -1823,7 +1825,26 @@ $I18N.addLangs("zh_cn", { "dashboard.cache.bytes": "缓存击中量", "dashboard.geo": "地理位置", "dashboard.distincts": "独立 IP", - "dashboard.peer": "峰值 %peer%" + "dashboard.peer": "峰值 %peer%", + "dashboard.basic": "基础统计", + "dashboard.pro": "高级统计", + "dashboard.geo.world": "世界", + "dashboard.geo.china": "中国", + "menu.dashboard": "数据统计", + "menu.config": "配置", + "menu.config.storage": "存储设置", + "tqdm": "%value%/%total%, %item%/s", + "storage.webdav": "正在获取WebDav文件中", + "cluster.want_enable": "正在启用", + "cluster.enabled.trusted": "正常工作", + "cluster.enabled": "正常工作(节点信任度过低)", + "files.checking": "正在检查文件中", + "files.downloading": "下载文件中", + "files.delete_old": "删除旧文件中", + "files.copying": "复制文件中", + "cluster.got.cert": "成功获取证书", + "cluster.get.cert": "获取证书中", + "files.fetching": "获取文件中" }) const $Country = [{code:"AF",name:"阿富汗",name_en:"Afghanistan"},{code:"AX",name:"奥兰",name_en:"Åland Islands"},{code:"AL",name:"阿尔巴尼亚",name_en:"Albania"},{code:"DZ",name:"阿尔及利亚",name_en:"Algeria"},{code:"AS",name:"美属萨摩亚",name_en:"American Samoa"},{code:"AD",name:"安道尔",name_en:"Andorra"},{code:"AO",name:"安哥拉",name_en:"Angola"},{code:"AI",name:"安圭拉",name_en:"Anguilla"},{code:"AQ",name:"南极洲",name_en:"Antarctica"},{code:"AG",name:"安提瓜和巴布达",name_en:"Antigua and Barbuda"},{code:"AR",name:"阿根廷",name_en:"Argentina"},{code:"AM",name:"亚美尼亚",name_en:"Armenia"},{code:"AW",name:"阿鲁巴",name_en:"Aruba"},{code:"AU",name:"澳大利亚",name_en:"Australia"},{code:"AT",name:"奥地利",name_en:"Austria"},{code:"AZ",name:"阿塞拜疆",name_en:"Azerbaijan"},{code:"BS",name:"巴哈马",name_en:"Bahamas"},{code:"BH",name:"巴林",name_en:"Bahrain"},{code:"BD",name:"孟加拉国",name_en:"Bangladesh"},{code:"BB",name:"巴巴多斯",name_en:"Barbados"},{code:"BY",name:"白俄罗斯",name_en:"Belarus"},{code:"BE",name:"比利时",name_en:"Belgium"},{code:"BZ",name:"伯利兹",name_en:"Belize"},{code:"BJ",name:"贝宁",name_en:"Benin"},{code:"BM",name:"百慕大",name_en:"Bermuda"},{code:"BT",name:"不丹",name_en:"Bhutan"},{code:"BO",name:"玻利维亚",name_en:"Bolivia (Plurinational State of)"},{code:"BQ",name:"荷兰加勒比区",name_en:"Bonaire,Sint Eustatius and Saba"},{code:"BA",name:"波黑",name_en:"Bosnia and Herzegovina"},{code:"BW",name:"博茨瓦纳",name_en:"Botswana"},{code:"BV",name:"布韦岛",name_en:"Bouvet Island"},{code:"BR",name:"巴西",name_en:"Brazil"},{code:"IO",name:"英属印度洋领地",name_en:"British Indian Ocean Territory"},{code:"BN",name:"文莱",name_en:"Brunei Darussalam"},{code:"BG",name:"保加利亚",name_en:"Bulgaria"},{code:"BF",name:"布基纳法索",name_en:"Burkina Faso"},{code:"BI",name:"布隆迪",name_en:"Burundi"},{code:"CV",name:"佛得角",name_en:"Cabo Verde"},{code:"KH",name:"柬埔寨",name_en:"Cambodia"},{code:"CM",name:"喀麦隆",name_en:"Cameroon"},{code:"CA",name:"加拿大",name_en:"Canada"},{code:"KY",name:"开曼群岛",name_en:"Cayman Islands"},{code:"CF",name:"中非",name_en:"Central African Republic"},{code:"TD",name:"乍得",name_en:"Chad"},{code:"CL",name:"智利",name_en:"Chile"},{code:"CN",name:"中国",name_en:"China"},{code:"CX",name:"圣诞岛",name_en:"Christmas Island"},{code:"CC",name:"科科斯(基林)群岛",name_en:"Cocos (Keeling) Islands"},{code:"CO",name:"哥伦比亚",name_en:"Colombia"},{code:"KM",name:"科摩罗",name_en:"Comoros"},{code:"CG",name:"刚果共和国",name_en:"Congo"},{code:"CD",name:"刚果民主共和国",name_en:"Congo (Democratic Republic of the)"},{code:"CK",name:"库克群岛",name_en:"Cook Islands"},{code:"CR",name:"哥斯达黎加",name_en:"Costa Rica"},{code:"CI",name:"科特迪瓦",name_en:"Côte d'Ivoire"},{code:"HR",name:"克罗地亚",name_en:"Croatia"},{code:"CU",name:"古巴",name_en:"Cuba"},{code:"CW",name:"库拉索",name_en:"Curacao !Curaçao"},{code:"CY",name:"塞浦路斯",name_en:"Cyprus"},{code:"CZ",name:"捷克",name_en:"Czechia"},{code:"DK",name:"丹麦",name_en:"Denmark"},{code:"DJ",name:"吉布提",name_en:"Djibouti"},{code:"DM",name:"多米尼克",name_en:"Dominica"},{code:"DO",name:"多米尼加",name_en:"Dominican Republic"},{code:"EC",name:"厄瓜多尔",name_en:"Ecuador"},{code:"EG",name:"埃及",name_en:"Egypt"},{code:"SV",name:"萨尔瓦多",name_en:"El Salvador"},{code:"GQ",name:"赤道几内亚",name_en:"Equatorial Guinea"},{code:"ER",name:"厄立特里亚",name_en:"Eritrea"},{code:"EE",name:"爱沙尼亚",name_en:"Estonia"},{code:"SZ",name:"斯威士兰",name_en:"Eswatini"},{code:"ET",name:"埃塞俄比亚",name_en:"Ethiopia"},{code:"FK",name:"福克兰群岛",name_en:"Falkland Islands (Malvinas)"},{code:"FO",name:"法罗群岛",name_en:"Faroe Islands"},{code:"FJ",name:"斐济",name_en:"Fiji"},{code:"FI",name:"芬兰",name_en:"Finland"},{code:"FR",name:"法国",name_en:"France"},{code:"GF",name:"法属圭亚那",name_en:"French Guiana"},{code:"PF",name:"法属波利尼西亚",name_en:"French Polynesia"},{code:"TF",name:"法属南部和南极领地",name_en:"French Southern Territories"},{code:"GA",name:"加蓬",name_en:"Gabon"},{code:"GM",name:"冈比亚",name_en:"Gambia"},{code:"GE",name:"格鲁吉亚",name_en:"Georgia"},{code:"DE",name:"德国",name_en:"Germany"},{code:"GH",name:"加纳",name_en:"Ghana"},{code:"GI",name:"直布罗陀",name_en:"Gibraltar"},{code:"GR",name:"希腊",name_en:"Greece"},{code:"GL",name:"格陵兰",name_en:"Greenland"},{code:"GD",name:"格林纳达",name_en:"Grenada"},{code:"GP",name:"瓜德罗普",name_en:"Guadeloupe"},{code:"GU",name:"关岛",name_en:"Guam"},{code:"GT",name:"危地马拉",name_en:"Guatemala"},{code:"GG",name:"根西",name_en:"Guernsey"},{code:"GN",name:"几内亚",name_en:"Guinea"},{code:"GW",name:"几内亚比绍",name_en:"Guinea-Bissau"},{code:"GY",name:"圭亚那",name_en:"Guyana"},{code:"HT",name:"海地",name_en:"Haiti"},{code:"HM",name:"赫德岛和麦克唐纳群岛",name_en:"Heard Island and McDonald Islands"},{code:"VA",name:"梵蒂冈",name_en:"Holy See"},{code:"HN",name:"洪都拉斯",name_en:"Honduras"},{code:"HU",name:"匈牙利",name_en:"Hungary"},{code:"IS",name:"冰岛",name_en:"Iceland"},{code:"IN",name:"印度",name_en:"India"},{code:"ID",name:"印尼",name_en:"Indonesia"},{code:"IR",name:"伊朗",name_en:"Iran (Islamic Republic of)"},{code:"IQ",name:"伊拉克",name_en:"Iraq"},{code:"IE",name:"爱尔兰",name_en:"Ireland"},{code:"IM",name:"马恩岛",name_en:"Isle of Man"},{code:"IL",name:"以色列",name_en:"Israel"},{code:"IT",name:"意大利",name_en:"Italy"},{code:"JM",name:"牙买加",name_en:"Jamaica"},{code:"JP",name:"日本",name_en:"Japan"},{code:"JE",name:"泽西",name_en:"Jersey"},{code:"JO",name:"约旦",name_en:"Jordan"},{code:"KZ",name:"哈萨克斯坦",name_en:"Kazakhstan"},{code:"KE",name:"肯尼亚",name_en:"Kenya"},{code:"KI",name:"基里巴斯",name_en:"Kiribati"},{code:"KP",name:"朝鲜",name_en:"Korea (Democratic People's Republic of)"},{code:"KR",name:"韩国",name_en:"Korea (Republic of)"},{code:"XK",name:"科索沃",name_en:"Kosovo"},{code:"KW",name:"科威特",name_en:"Kuwait"},{code:"KG",name:"吉尔吉斯斯坦",name_en:"Kyrgyzstan"},{code:"LA",name:"老挝",name_en:"Lao People's Democratic Republic"},{code:"LV",name:"拉脱维亚",name_en:"Latvia"},{code:"LB",name:"黎巴嫩",name_en:"Lebanon"},{code:"LS",name:"莱索托",name_en:"Lesotho"},{code:"LR",name:"利比里亚",name_en:"Liberia"},{code:"LY",name:"利比亚",name_en:"Libya"},{code:"LI",name:"列支敦士登",name_en:"Liechtenstein"},{code:"LT",name:"立陶宛",name_en:"Lithuania"},{code:"LU",name:"卢森堡",name_en:"Luxembourg"},{code:"MG",name:"马达加斯加",name_en:"Madagascar"},{code:"MW",name:"马拉维",name_en:"Malawi"},{code:"MY",name:"马来西亚",name_en:"Malaysia"},{code:"MV",name:"马尔代夫",name_en:"Maldives"},{code:"ML",name:"马里",name_en:"Mali"},{code:"MT",name:"马耳他",name_en:"Malta"},{code:"MH",name:"马绍尔群岛",name_en:"Marshall Islands"},{code:"MQ",name:"马提尼克",name_en:"Martinique"},{code:"MR",name:"毛里塔尼亚",name_en:"Mauritania"},{code:"MU",name:"毛里求斯",name_en:"Mauritius"},{code:"YT",name:"马约特",name_en:"Mayotte"},{code:"MX",name:"墨西哥",name_en:"Mexico"},{code:"FM",name:"密克罗尼西亚联邦",name_en:"Micronesia (Federated States of)"},{code:"MD",name:"摩尔多瓦",name_en:"Moldova (Republic of)"},{code:"MC",name:"摩纳哥",name_en:"Monaco"},{code:"MN",name:"蒙古",name_en:"Mongolia"},{code:"ME",name:"黑山",name_en:"Montenegro"},{code:"MS",name:"蒙特塞拉特",name_en:"Montserrat"},{code:"MA",name:"摩洛哥",name_en:"Morocco"},{code:"MZ",name:"莫桑比克",name_en:"Mozambique"},{code:"MM",name:"缅甸",name_en:"Myanmar"},{code:"NA",name:"纳米比亚",name_en:"Namibia"},{code:"NR",name:"瑙鲁",name_en:"Nauru"},{code:"NP",name:"尼泊尔",name_en:"Nepal"},{code:"NL",name:"荷兰",name_en:"Netherlands"},{code:"NC",name:"新喀里多尼亚",name_en:"New Caledonia"},{code:"NZ",name:"新西兰",name_en:"New Zealand"},{code:"NI",name:"尼加拉瓜",name_en:"Nicaragua"},{code:"NE",name:"尼日尔",name_en:"Niger"},{code:"NG",name:"尼日利亚",name_en:"Nigeria"},{code:"NU",name:"纽埃",name_en:"Niue"},{code:"NF",name:"诺福克岛",name_en:"Norfolk Island"},{code:"MK",name:"北马其顿",name_en:"North Macedonia"},{code:"MP",name:"北马里亚纳群岛",name_en:"Northern Mariana Islands"},{code:"NO",name:"挪威",name_en:"Norway"},{code:"OM",name:"阿曼",name_en:"Oman"},{code:"PK",name:"巴基斯坦",name_en:"Pakistan"},{code:"PW",name:"帕劳",name_en:"Palau"},{code:"PS",name:"巴勒斯坦",name_en:"Palestine,State of"},{code:"PA",name:"巴拿马",name_en:"Panama"},{code:"PG",name:"巴布亚新几内亚",name_en:"Papua New Guinea"},{code:"PY",name:"巴拉圭",name_en:"Paraguay"},{code:"PE",name:"秘鲁",name_en:"Peru"},{code:"PH",name:"菲律宾",name_en:"Philippines"},{code:"PN",name:"皮特凯恩群岛",name_en:"Pitcairn"},{code:"PL",name:"波兰",name_en:"Poland"},{code:"PT",name:"葡萄牙",name_en:"Portugal"},{code:"PR",name:"波多黎各",name_en:"Puerto Rico"},{code:"QA",name:"卡塔尔",name_en:"Qatar"},{code:"RE",name:"留尼汪",name_en:"Réunion"},{code:"RO",name:"罗马尼亚",name_en:"Romania"},{code:"RU",name:"俄罗斯",name_en:"Russian Federation"},{code:"RW",name:"卢旺达",name_en:"Rwanda"},{code:"BL",name:"圣巴泰勒米",name_en:"Saint Barthélemy"},{code:"SH",name:"圣赫勒拿、阿森松和特里斯坦-达库尼亚",name_en:"Saint Helena,Ascension and Tristan da Cunha"},{code:"KN",name:"圣基茨和尼维斯",name_en:"Saint Kitts and Nevis"},{code:"LC",name:"圣卢西亚",name_en:"Saint Lucia"},{code:"MF",name:"法属圣马丁",name_en:"Saint Martin (French part)"},{code:"PM",name:"圣皮埃尔和密克隆",name_en:"Saint Pierre and Miquelon"},{code:"VC",name:"圣文森特和格林纳丁斯",name_en:"Saint Vincent and the Grenadines"},{code:"WS",name:"萨摩亚",name_en:"Samoa"},{code:"SM",name:"圣马力诺",name_en:"San Marino"},{code:"ST",name:"圣多美和普林西比",name_en:"Sao Tome and Principe"},{code:"SA",name:"沙特阿拉伯",name_en:"Saudi Arabia"},{code:"SN",name:"塞内加尔",name_en:"Senegal"},{code:"RS",name:"塞尔维亚",name_en:"Serbia"},{code:"SC",name:"塞舌尔",name_en:"Seychelles"},{code:"SL",name:"塞拉利昂",name_en:"Sierra Leone"},{code:"SG",name:"新加坡",name_en:"Singapore"},{code:"SX",name:"荷属圣马丁",name_en:"Sint Maarten (Dutch part)"},{code:"SK",name:"斯洛伐克",name_en:"Slovakia"},{code:"SI",name:"斯洛文尼亚",name_en:"Slovenia"},{code:"SB",name:"所罗门群岛",name_en:"Solomon Islands"},{code:"SO",name:"索马里",name_en:"Somalia"},{code:"ZA",name:"南非",name_en:"South Africa"},{code:"GS",name:"南乔治亚和南桑威奇群岛",name_en:"South Georgia and the South Sandwich Islands"},{code:"SS",name:"南苏丹",name_en:"South Sudan"},{code:"ES",name:"西班牙",name_en:"Spain"},{code:"LK",name:"斯里兰卡",name_en:"Sri Lanka"},{code:"SD",name:"苏丹",name_en:"Sudan"},{code:"SR",name:"苏里南",name_en:"Suriname"},{code:"SJ",name:"斯瓦尔巴和扬马延",name_en:"Svalbard and Jan Mayen"},{code:"SE",name:"瑞典",name_en:"Sweden"},{code:"CH",name:"瑞士",name_en:"Switzerland"},{code:"SY",name:"叙利亚",name_en:"Syrian Arab Republic"},{code:"TJ",name:"塔吉克斯坦",name_en:"Tajikistan"},{code:"TZ",name:"坦桑尼亚",name_en:"Tanzania,United Republic of"},{code:"TH",name:"泰国",name_en:"Thailand"},{code:"TL",name:"东帝汶",name_en:"Timor-Leste"},{code:"TG",name:"多哥",name_en:"Togo"},{code:"TK",name:"托克劳",name_en:"Tokelau"},{code:"TO",name:"汤加",name_en:"Tonga"},{code:"TT",name:"特立尼达和多巴哥",name_en:"Trinidad and Tobago"},{code:"TN",name:"突尼斯",name_en:"Tunisia"},{code:"TR",name:"土耳其",name_en:"Turkey"},{code:"TM",name:"土库曼斯坦",name_en:"Turkmenistan"},{code:"TC",name:"特克斯和凯科斯群岛",name_en:"Turks and Caicos Islands"},{code:"TV",name:"图瓦卢",name_en:"Tuvalu"},{code:"UG",name:"乌干达",name_en:"Uganda"},{code:"UA",name:"乌克兰",name_en:"Ukraine"},{code:"AE",name:"阿联酋",name_en:"United Arab Emirates"},{code:"GB",name:"英国",name_en:"United Kingdom of Great Britain and Northern Ireland"},{code:"US",name:"美国",name_en:"United States of America"},{code:"UM",name:"美国本土外小岛屿",name_en:"United States Minor Outlying Islands"},{code:"UY",name:"乌拉圭",name_en:"Uruguay"},{code:"UZ",name:"乌兹别克斯坦",name_en:"Uzbekistan"},{code:"VU",name:"瓦努阿图",name_en:"Vanuatu"},{code:"VE",name:"委内瑞拉",name_en:"Venezuela (Bolivarian Republic of)"},{code:"VN",name:"越南",name_en:"Viet Nam"},{code:"VG",name:"英属维尔京群岛",name_en:"Virgin Islands (British)"},{code:"VI",name:"美属维尔京群岛",name_en:"Virgin Islands (U.S.)"},{code:"WF",name:"瓦利斯和富图纳",name_en:"Wallis and Futuna"},{code:"EH",name:"西撒哈拉",name_en:"Western Sahara"},{code:"YE",name:"也门",name_en:"Yemen"},{code:"ZM",name:"赞比亚",name_en:"Zambia"},{code:"ZW",name:"津巴布韦",name_en:"Zimbabwe"}] const formatTime = (timestamp) => { @@ -1872,7 +1893,7 @@ app.$Menu.add("dashboard", new class { this._unit_number = ["", "k", "M", "G", "T", "P", "E"] } async init() { - this.switch = (new ElementSwitch("BASIC", "PRO")).event("click", (index) => { + this.switch = (new ElementSwitch("dashboard.basic", "dashboard.pro")).event("click", (index) => { this.page[2].clear() this.clear() $progress.set(33) @@ -1897,7 +1918,7 @@ app.$Menu.add("dashboard", new class { this._e_memory = app.createEcharts().style("min-height: 162px;") this._e_connection = app.createEcharts().style("min-height: 162px;") this.geo_type = "world" - this.switch_geo = (new ElementSwitch("世界", "中国")).style("border: 1px solid var(--border-color);").event("click", (index) => { + this.switch_geo = (new ElementSwitch("dashboard.geo.world", "dashboard.geo.china")).style("border: 1px solid var(--border-color);").event("click", (index) => { if (index == 0) this.geo_type = "world" else this.geo_type = "china" this.drawGEO() @@ -1926,7 +1947,15 @@ app.$Menu.add("dashboard", new class { ), app.createElement("div").append( app.createElement("p").class("title").setI18N("dashboard.status"), - app.createElement("p").class("value").setText("-") + app.createElement("p").append( + app.createElement("span").class("value").setText("-"), + app.createElement("span").append( + app.createElement("span").class("value").setText(" | "), + app.createElement("span").class("value").setText(""), + app.createElement("span").class("value").setText(" "), + app.createElement("span").setText("") + ), + ) ) ).minWidth(896).child(2) ), @@ -2664,7 +2693,17 @@ app.$Menu.add("dashboard", new class { this.pro[0].getChildren()[1].getChildren()[0].getChildren()[0].getChildren()[1].t18n({ peer: Math.max(...Object.values(visits)) }) } setStatus() { - this.page[0].getChildren()[0].getChildren()[1].getChildren()[1].setText(this.status.progress ? this.status.progress.desc : this.status.key) + this.page[0].getChildren()[0].getChildren()[1].getChildren()[1].getChildren()[0].setI18N(this.status.key) + this.page[0].getChildren()[0].getChildren()[1].getChildren()[1].getChildren()[1].style(`display: ${this.status.progress ? 'inline' : 'none'}`) + if (this.status.progress) { + var value_formatter = this.status.progress.desc == "files.downloading" ? (n) => this._format_bytes(n) : (n) => n + this.page[0].getChildren()[0].getChildren()[1].getChildren()[1].getChildren()[1].getChildren()[1].setI18N(this.status.progress.desc) + this.page[0].getChildren()[0].getChildren()[1].getChildren()[1].getChildren()[1].getChildren()[3].setI18N("tqdm", { + value: value_formatter(this.status.progress.value), + total: value_formatter(this.status.progress.total), + item: value_formatter(this.status.progress.speed), + }) + } } _format_time(n, sub = false) { if (n == null) return "-" diff --git a/core/dashboard.py b/core/dashboard.py index b28d6d1..c99a14e 100644 --- a/core/dashboard.py +++ b/core/dashboard.py @@ -194,6 +194,8 @@ async def set_status_by_tqdm(text: str, pbar: tqdm): if task_tqdm: task_tqdm.block() cur_tqdm.show.block() + cur_tqdm.speed = 0 + cur_tqdm.last_value = 0 task_tqdm = Timer.repeat(_calc_tqdm_speed, delay=0, interval=0.5) cur_tqdm.show = Timer.repeat(_set_status, kwargs={ "blocked": True diff --git a/core/stats.py b/core/stats.py index 31de5a2..d9fb983 100644 --- a/core/stats.py +++ b/core/stats.py @@ -238,7 +238,7 @@ def read_storage(): def write_storage(): - global storages, globalStats + global storages, globalStats, last_hour f = DataOutputStream() f.writeVarInt(last_hour) f.writeVarInt(len(storages)) @@ -573,34 +573,9 @@ def daily_global(): def init(): start = time.monotonic() logger.tinfo("stats.info.init") - db.execute( - """ - CREATE TABLE IF NOT EXISTS access ( - hour unsigned bigint NOT NULL, - storage TEXT NOT NULL, - hit unsigned bigint NOT NULL DEFAULT 0, - bytes unsigned bigint NOT NULL DEFAULT 0, - cache_hit unsigned bigint NOT NULL DEFAULT 0, - cache_bytes unsigned bigint NOT NULL DEFAULT 0, - last_hit unsigned bigint NOT NULL DEFAULT 0, - last_bytes unsigned bigint NOT NULL DEFAULT 0, - failed unsigned bigint NOT NULL DEFAULT 0 - );""" - ) - db.execute( - """ - CREATE TABLE IF NOT EXISTS g_access_ip ( - day unsigned bigint NOT NULL, - ip TEXT NOT NULL, - hit unsigned bigint not null default 0 - );""" - ) - db.execute( - """ - CREATE TABLE IF NOT EXISTS g_access_ua ( - day unsigned bigint NOT NULL - );""" - ) + db.execute("CREATE TABLE IF NOT EXISTS access (hour unsigned bigint NOT NULL, storage TEXT NOT NULL, hit unsigned bigint NOT NULL DEFAULT 0, bytes unsigned bigint NOT NULL DEFAULT 0, cache_hit unsigned bigint NOT NULL DEFAULT 0, cache_bytes unsigned bigint NOT NULL DEFAULT 0, last_hit unsigned bigint NOT NULL DEFAULT 0, last_bytes unsigned bigint NOT NULL DEFAULT 0, failed unsigned bigint NOT NULL DEFAULT 0);") + db.execute("CREATE TABLE IF NOT EXISTS g_access_ip (day unsigned bigint NOT NULL, ip TEXT NOT NULL, hit unsigned bigint not null default 0);") + db.execute("CREATE TABLE IF NOT EXISTS g_access_ua (day unsigned bigint NOT NULL);") db.commit() for ua in UserAgent: From 7366e298a14f6aeddf14e94c82e14a49bdd9ebcf Mon Sep 17 00:00:00 2001 From: tianxiu2b2t Date: Thu, 18 Apr 2024 23:19:17 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BC=9A=E5=87=BA=E7=8E=B0=E6=98=8E=E5=A4=A9?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/stats.py b/core/stats.py index d9fb983..bf62661 100644 --- a/core/stats.py +++ b/core/stats.py @@ -206,7 +206,7 @@ def read_storage(): with open("./cache/storage.bin", "rb") as r: f = FileDataInputStream(r) last_hour = f.readVarInt() - last_day = last_hour // 24 + last_day = (last_hour - last_hour % 24) // 24 - 1 for _ in range(f.readVarInt()): storage = StorageStats(f.readString()) ( From b516fd6a8bf88edc4cab347ae4b4fbddad3f6e2f Mon Sep 17 00:00:00 2001 From: SilianZ Date: Fri, 19 Apr 2024 11:27:11 +0800 Subject: [PATCH 7/7] =?UTF-8?q?:globe=5Fwith=5Fmeridians:=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=20i18n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/cluster.py | 4 ++-- core/stats.py | 10 ++-------- i18n/zh_cn.json | 6 ++++-- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/core/cluster.py b/core/cluster.py index 593cf74..2e12b3e 100644 --- a/core/cluster.py +++ b/core/cluster.py @@ -183,14 +183,14 @@ async def _download_temporarily_file(self, hash: str): "User-Agent": USER_AGENT } ) as session: - logger.debug(f"正在下载 {hash}") + logger.tdebug("cluster.debug.download_temp.downloading", hash=hash) content: io.BytesIO = io.BytesIO() async with session.get(f"/openbmclapi/download/{hash}") as resp: while data := await resp.content.read(IO_BUFFER): if not data: break content.write(data) - logger.debug(f"下载完成 {hash}") + logger.tdebug("cluster.debug.download_temp.downloaded", hash=hash) await self._mount_file(BMCLAPIFile( path = f"/download/{hash}", hash = hash, diff --git a/core/stats.py b/core/stats.py index bf62661..eb72763 100644 --- a/core/stats.py +++ b/core/stats.py @@ -87,7 +87,6 @@ def from_binary(data: bytes): input = DataInputStream(zstd.decompress(data)) ip_length = input.readVarInt() ua_length = input.readVarInt() - logger.debug(f"数据读取IP [{unit.format_number(ip_length)}] UA [{unit.format_number(ua_length)}]") cache_ip = {input.readString(): input.readVarInt() for _ in range(ip_length)} cache_ua = {UserAgent.get_ua(input.readString()): input.readVarInt() for _ in range(ua_length)} return GlobalStats(GlobalStats.convert_dict_to_defaultdict(cache_ua, int), GlobalStats.convert_dict_to_defaultdict(cache_ip, int)) @@ -364,12 +363,7 @@ def _write_database(first: bool = False): ) ) ) - if first: - logger.debug(f"本地数据同步到数据库 [{unit.format_number(len(cmds))}]") - start = time.monotonic() executemany(*cmds) - if first: - logger.debug(f"执行SQL语句耗时 {time.monotonic() - start:.2f}") cur_day = get_day(0) cur_hour = get_hour(0) if cur_hour != hour: @@ -572,7 +566,7 @@ def daily_global(): def init(): start = time.monotonic() - logger.tinfo("stats.info.init") + logger.tinfo("stats.info.initializing") db.execute("CREATE TABLE IF NOT EXISTS access (hour unsigned bigint NOT NULL, storage TEXT NOT NULL, hit unsigned bigint NOT NULL DEFAULT 0, bytes unsigned bigint NOT NULL DEFAULT 0, cache_hit unsigned bigint NOT NULL DEFAULT 0, cache_bytes unsigned bigint NOT NULL DEFAULT 0, last_hit unsigned bigint NOT NULL DEFAULT 0, last_bytes unsigned bigint NOT NULL DEFAULT 0, failed unsigned bigint NOT NULL DEFAULT 0);") db.execute("CREATE TABLE IF NOT EXISTS g_access_ip (day unsigned bigint NOT NULL, ip TEXT NOT NULL, hit unsigned bigint not null default 0);") db.execute("CREATE TABLE IF NOT EXISTS g_access_ua (day unsigned bigint NOT NULL);") @@ -582,7 +576,7 @@ def init(): addColumns("g_access_ua", f"`{ua.value}`", " unsigned bigint NOT NULL DEFAULT 0") read_storage() _write_database(True) - logger.tinfo("stats.info.initization", time = f"{(time.monotonic() - start):.2f}") + logger.tsuccess("stats.info.initialization", time = f"{(time.monotonic() - start):.2f}") Timer.delay(write_database, delay=time.time() % 1) diff --git a/i18n/zh_cn.json b/i18n/zh_cn.json index 695a0f0..0590049 100644 --- a/i18n/zh_cn.json +++ b/i18n/zh_cn.json @@ -1,6 +1,6 @@ { - "stats.info.init": "正在初始化 [统计] 模块中...", - "stats.info.initization": "初始化 [统计] 模块成功,耗时:$time 秒。", + "stats.info.initializing": "正在初始化 [统计] 模块中...", + "stats.info.initialization": "初始化 [统计] 模块成功,耗时:$time 秒。", "cert.error.failed": "无法加载证书:$failure。", "cert.success.loaded_cert": "成功从本地文件中加载证书!", "web.info.serving_router": "正在 $router 上服务路由。", @@ -17,6 +17,8 @@ "cluster.info.get_files.modified_time": "文件最后修改时间:$time。", "cluster.error.mount_files.failed_to_copy": "在尝试下载文件时出错:无法复制文件:$hash ($file) => $hash ($target)。", "cluster.tqdm.desc.download": "下载文件中", + "cluster.debug.download_temp.downloading": "正在下载文件:$hash。", + "cluster.debug.download_temp.downloaded": "成功下载文件:$hash。", "cluster.info.download.finished": "成功下载所有文件。", "cluster.info.check_files.check_type": "当前文件检查模式:$type。", "cluster.warn.check_files.skipped": "当前并无可用文件,已跳过文件检查。",