Skip to content

Commit

Permalink
Merge pull request #7 from TTB-Network/dev/config
Browse files Browse the repository at this point in the history
🎨 重构部分代码
  • Loading branch information
SilianZ authored Mar 9, 2024
2 parents 7387ec4 + 21c7682 commit 97122d2
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 101 deletions.
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<<<<<<< HEAD
container/.ssl/
container/bmclapi/
container/cache/
container/config/
container/__pycache__/
.vscode/
.lh/
test/
=======
config/config.properties
__pycache__
.venv
>>>>>>> 1821e9a699e53437109088d3d8cf4bb4a1bf9a50
logs
config/config.yaml
bmclapi
bmclapi_dashboard
cache
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ WORKDIR /python-openbmclapi
ADD . .

RUN pip install -r requirements.txt --no-deps
VOLUME /python-openbmclapi/cache
ENV web_port=8080
VOLUME /python-openbmclapi/bmclapi
ENV web_port=8800
EXPOSE $web_port
CMD ["python", "./container/main.py"]
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

🎉 __*新增功能!*__基于 Echart 的 OpenBMCLAPI 仪表盘(Dashboard)。

🎉 __*新增功能!*__基于 loguru 的**日志器**


</div>

# 简介
Expand Down Expand Up @@ -53,7 +56,7 @@
python ./container/main.py
```

4. 在 `config.properties` 中,填写你的 `cluster.id`(即 `CLUSTER_ID`)和 `cluster.secret`(即 `CLUSTER_SECRET`)。
4. 在 `config.yaml` 中,填写你的 `cluster_id`(即 `CLUSTER_ID`)和 `cluster_secret`(即 `CLUSTER_SECRET`)。

5. 重新启动程序。

Expand All @@ -69,8 +72,8 @@

```sh
docker run -d \
-v ${/data/python-openbmclapi}:/python-openbmclapi/container/cache \
-v ${/path/to/your/config}:/python-openbmclapi/config/config.properties \
-v ${/data/python-openbmclapi}:/python-openbmclapi/bmclapi \
-v ${/path/to/your/config}:/python-openbmclapi/config/config.yaml \
-p ${web.port}:${web.port} \
--restart always \
--name python-openbmclapi \
Expand All @@ -81,9 +84,23 @@

`web.port` - 对外开放的端口。

`/path/to/your/config` - 配置文件(你需要从此仓库中下载 `config/config.properties.example` 并重命名为 `config.properties` 来进行配置)的存放路径。
`/path/to/your/config` - 配置文件(你需要从此仓库中下载 `config/config.yaml.example` 并重命名为 `config.yaml` 来进行配置)的存放路径。

`/data/python-openbmclapi` - `bmclapi` 文件夹(即缓存 `cache` 文件夹)挂载的路径。

# 配置文件

```yaml
byoc: ''
cluster_id: ''
cluster_secret: ''
download_threads: 64
timeout: 30
web_host: ''
web_port: 8800
web_publicport: 8800
`/data/python-openbmclapi` - `cache` 文件夹挂载的路径。
```

# 鸣谢

Expand Down
8 changes: 0 additions & 8 deletions config/config.properties.example

This file was deleted.

8 changes: 8 additions & 0 deletions config/config.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
byoc: false
cluster_id: ''
cluster_secret: ''
download_threads: 64
timeout: 30
web_host: ''
web_port: 8800
web_publicport: 8800
2 changes: 1 addition & 1 deletion container/bmclapi_dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8"/>
<title>OPENBMCLAPI - TTB Network</title>
<title>Python OpenBMCLAPI Dashboard</title>
</head>
<body>
</body>
Expand Down
6 changes: 2 additions & 4 deletions container/bmclapi_dashboard/static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const calc_more_bytes = (...values) => {
".container .vcmp-status-bar:hover":"color: #8dcffc;",
".container .vcmp-status-online":"width: 12px;height: 12px;border-radius: 50%;background-color: #0FC6C2;margin: 8px;",
".container .vcmp-status-offline":"width: 12px;height: 12px;border-radius: 50%;background-color: rgba(0, 0, 0, 0.5);margin: 8px;margin-right: 0;",
"h1, h2, h3":"font-family: Microsoft Yahei UI"
}
set_styles(default_styles)
Extendi18nSets("zh_cn", {
Expand Down Expand Up @@ -266,10 +267,7 @@ const calc_more_bytes = (...values) => {
ExtendFlex().append(
ExtendFlex().css("domain", "extend-flex-auto").append(
ExtendElement("span").append(
ExtendElement("h2").text("Python OpenBMCLAPI Dashboard").valueOf(),
ExtendElement("span").text("Built by ").append(
ExtendElement("a").text("TTB Network").setAttr("href", "https://github.com/TTB-Network/python-openbmclapi/").valueOf()
).id("dashboard-geo").valueOf()
ExtendElement("h3").text("Python OpenBMCLAPI Dashboard").valueOf(),
).valueOf(),
).valueOf(),
).css("header-bar").valueOf(),
Expand Down
35 changes: 19 additions & 16 deletions container/cluster.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio
from dataclasses import dataclass
import glob
import hashlib
import hmac
import io
Expand All @@ -18,6 +17,8 @@
import utils
import stats
import web
from logger import logger
from tqdm import tqdm

PY_VERSION = "1.0.0"
VERSION = "1.9.7"
Expand Down Expand Up @@ -60,7 +61,7 @@ async def fetchToken(self):
Timer.delay(self.fetchToken, delay=float(content['ttl']) / 1000.0 - 600)

except aiohttp.ClientError as e:
print(f"Error fetching token: {e}")
logger.error(f"Error fetching token: {e}.")
async def getToken(self) -> str:
if not self.token:
await self.fetchToken()
Expand Down Expand Up @@ -120,29 +121,30 @@ async def download(self, session: aiohttp.ClientSession):
self.download_bytes.add(-size)
await self.files.put(file)
async def check_file(self):
print("Requesting files...")
logger.info("Requesting filelist...")
filelist = await self.get_file_list()
filesize = sum((file.size for file in filelist))
total = len(filelist)
byte = 0
miss = []
pbar = tqdm(total=total, unit=' file(s)', unit_scale=True)
pbar.set_description("Checking files")
for i, file in enumerate(filelist):
filepath = str(self.dir) + f"/{file.hash[:2]}/{file.hash}"
if not os.path.exists(filepath) or os.path.getsize(filepath) != file.size:
miss.append(file)
...
await asyncio.sleep(0)
byte += file.size
b = utils.calc_more_bytes(byte, filesize)
print(f"<<<flush>>>Check file {i}/{total} ({b[0]}/{b[1]})")
pbar.update(1)
if not miss:
print(f"<<<flush>>>Checked all files!")
logger.info("Checked all files!")
await self.start_service()
return
filelist = miss
filesize = sum((file.size for file in filelist))
total = len(filelist)
print(f"<<<flush>>>Missing files: {total}({utils.calc_bytes(filesize)})")
logger.info(f"Missing files: {total}({utils.calc_bytes(filesize)}).")
for file in filelist:
await self.files.put(file)
self.download_bytes = utils.Progress(5, filesize)
Expand All @@ -154,16 +156,17 @@ async def check_file(self):
"User-Agent": UA,
"Authorization": f"Bearer {await token.getToken()}"
}), )))
pbar = tqdm(total=total, unit=' file(s)', unit_scale=True)
pre = 0
while any([not timer.called for timer in timers]):
b = utils.calc_more_bytes(self.download_bytes.get_cur(), filesize)
bits = self.download_bytes.get_cur_speeds() or [0]
minbit = min(bits)
bit = utils.calc_more_bit(minbit, bits[-1], max(bits))
eta = self.download_bytes.get_eta()
print(f"<<<flush>>>Downloading files... {self.download_files.get_cur()}/{total} {b[0]}/{b[1]}, eta: {utils.format_time(eta if eta != -1 else None)}, total: {utils.format_time(self.download_bytes.get_total())}, Min: {bit[0]}, Cur: {bit[2]}, Max: {bit[1]}, Files: {self.download_files.get_cur_speed()}/s")
pbar.set_description(f"Downloading files | Curent speed: {bit[2]}")
await asyncio.sleep(1)
for timer in timers:
del timer
pbar.update(self.download_files.get_cur() - pre)
pre = self.download_files.get_cur()
await self.start_service()
async def start_service(self):
tokens = await token.getToken()
Expand All @@ -185,11 +188,11 @@ async def enable(self):
if not web.get_ssl() and not (Path(".ssl/cert.pem").exists() and Path(".ssl/key.pem").exists()):
await self.emit("request-cert")
self.cur_counter = stats.Counters()
print("Connected Main Server.")
logger.info("Connected to the Main Server.")
async def message(self, type, data):
if type == "request-cert":
cert = data[1]
print("Requested cert!")
logger.info("Requested cert!")
cert_file = Path(".ssl/cert.pem")
key_file = Path(".ssl/key.pem")
for file in (cert_file, key_file):
Expand All @@ -206,9 +209,9 @@ async def message(self, type, data):
self.keepalive.block()
self.keepalive = Timer.delay(self.keepaliveTimer, (), 5)
if len(data) == 2 and data[1] == True:
print("Checked! Can service")
logger.info("Checked! Starting the service")
return
print("Error:" + data[0]['message'])
logger.error("Error:" + data[0]['message'])
Timer.delay(self.enable)
elif type == "keep-alive":
COUNTER.hit -= self.cur_counter.hit
Expand All @@ -234,7 +237,7 @@ async def get_file_list(self):
"cache": ""
}) as req:
req.raise_for_status()
print("Requested files")
logger.info("Requested filelist.")

parser = avro_io.DatumReader(schema.parse(
'''
Expand Down
81 changes: 29 additions & 52 deletions container/config.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,39 @@
from pathlib import Path
import yaml
from typing import Union

class CFG:
def __init__(self, path: str) -> None:
self.file = Path(path)
self.cfg = {}
if self.file.exists():
self.load()

class Property:
def __init__(self, config: str, exists_ok: bool = True) -> None:
self.file = Path(config)
self.properties = {}
if self.file.exists():
self.parse_file()
self.exists_ok = exists_ok

def parse_file(self):
def load(self):
with open(self.file, "r", encoding="utf-8") as f:
for line in f.readlines():
line = line.strip()
if not line or line.startswith('#'):
continue
key, value = line.split('=', 1)
value = value.strip('"')
self.properties[key] = value
def set(self, key, value):
self.properties[key] = str(value)
self.cfg = yaml.load(f.read(), Loader=yaml.FullLoader)

def get(self, key, default=None):
val = self.properties.get(key, None)
if not self.exists_ok and val is None:
self.set(key, default or "")
self.save()
return val or str(default)
def getBoolean(self, key, def_: bool = False):
val = self.get(key, def_)
return val.lower() in ("true", "1", "t", "yes", "y")
def getInteger(self, key, def_: int = 0):
val = self.get(key, def_)
return int(val) if val.isnumeric() else def_
def __getitem__(self, key):
return self.properties.get(key)
def __setitem__(self, key, value):
self.set(key, value)

def save(self):
sorted_dict = sorted(self.properties.items())
self.file.parent.mkdir(exist_ok=True, parents=True)
with open(self.file, 'w', encoding="utf-8") as file:
for key, value in sorted_dict:
if "\n" in value:
value = f'"{value}"'
file.write(f"{key}={value}\n")
def get(self, key, default_):
value = self.cfg.get(key, default_)
if value is None:
self.write(key, default_)
return value

Config: Property = Property("./config/config.properties", False)
def write(self, key, value):
self.cfg[key] = value
with open(self.file, "w", encoding="utf-8") as f:
yaml.dump(data=self.cfg, stream=f, allow_unicode=True)

CLUSTER_ID = Config.get("cluster.id", None) or ""
CLUSTER_SECRET = Config.get("cluster.secret", None) or ""
MAX_DOWNLOAD = Config.getInteger("download.threads", 64)
PORT = Config.getInteger("web.port", 8800)
PUBLICPORT = Config.getInteger("web.publicport", 8800)
PUBLICHOST = Config.get("web.host", "")
BYOC = False
TIMEOUT = 30
Config: CFG = CFG("./config/config.yaml")

CLUSTER_ID: str = Config.get("cluster_id", "")
CLUSTER_SECRET: str = Config.get("cluster_secret", "")
MAX_DOWNLOAD: int = Config.get("download_threads", 64)
PORT: int = Config.get("web_port", 8800)
PUBLICPORT: int = Config.get("web_publicport", 8800)
PUBLICHOST: int = Config.get("web_host", "")
BYOC: bool = Config.get("byoc", False)
TIMEOUT: int = Config.get("timeout", 30)
MIN_RATE_TIMESTAMP = 1000
MIN_RATE = 500
REQUEST_BUFFER = 1024 * 8
Expand Down
4 changes: 4 additions & 0 deletions container/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from loguru import logger
from pathlib import Path

logger.add(Path("./logs/{time}.log"), rotation="3 hours")
5 changes: 3 additions & 2 deletions container/timer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import inspect
import time
import traceback
from logger import logger


class Task:
Expand Down Expand Up @@ -44,15 +45,15 @@ def block(self):
self.blocked = True
async def callback_error(self):
if not self.error:
print(traceback.format_exc())
logger.debug(traceback.format_exc())
return
try:
if inspect.iscoroutinefunction(self.error):
await self.error()
else:
self.error()
except:
print(traceback.format_exc())
logger.debug(traceback.format_exc())
class TimerManager:
def delay(self, target, args = (), delay: float = 0, callback = None):
task = Task(target=target, args=args, delay=delay, back=callback)
Expand Down
Loading

0 comments on commit 97122d2

Please sign in to comment.