Skip to content

Commit

Permalink
🎨 重构部分代码
Browse files Browse the repository at this point in the history
- 新增使用 `loguru` 编写的 logger
- 新增使用 `tqdm` 编写的进度条
- 重构 `config.py`
- 修正了多处工地英语
- 将 `print` 改为 `logger`
- 更新 README 以适应新的 config 文件
- 修改 `requirements.txt`
- 修改 Dashboard 的部分样式
- 更新 config.*.example
- 更新配置文件语言至 YAML
- 更新 `Dockerfile` 以适配新的版本
- 更新 `.gitignore`
  • Loading branch information
SilianZ committed Mar 9, 2024
1 parent 4f3620d commit b29d35a
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 95 deletions.
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<<<<<<< HEAD
container/.ssl/
container/bmclapi/
container/cache/
container/config/
container/__pycache__/
.vscode/
.lh/
=======
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"]
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,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 +69,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 +81,9 @@

`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` - `cache` 文件夹挂载的路径
`/data/python-openbmclapi` - `bmclapi` 文件夹(即缓存 `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: ''
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 @@ -260,10 +261,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
32 changes: 20 additions & 12 deletions container/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import utils
import stats
import web
from logger import logger
from tqdm import tqdm
import time

PY_VERSION = "1.0.0"
VERSION = "1.9.7"
Expand Down Expand Up @@ -59,7 +62,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 @@ -119,12 +122,14 @@ 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 = Path(str(self.dir) + f"/{file.hash[:2]}/{file.hash}")
if not filepath.exists() or filepath.stat().st_size != file.size:
Expand All @@ -133,15 +138,15 @@ async def check_file(self):
await asyncio.sleep(0)
b = utils.calc_more_bytes(byte, filesize)
byte += file.size
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 @@ -153,14 +158,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)
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 @@ -182,11 +190,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 @@ -203,9 +211,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 @@ -231,7 +239,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
82 changes: 29 additions & 53 deletions container/config.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,38 @@
from pathlib import Path
import yaml

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):
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)
def load(self):
with open(self.file, 'r', encoding="utf-8") as f:
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, None)
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("./config/config.yaml")

CLUSTER_ID = Config.get("cluster_id", "")
CLUSTER_SECRET = Config.get("cluster_secret", "")
MAX_DOWNLOAD = Config.get("download_threads", 64)
PORT = Config.get("web_port", 8800)
PUBLICPORT = Config.get("web_publicport", 8800)
PUBLICHOST = Config.get("web_host", "")
BYOC = Config.get("byoc", False)
TIMEOUT = 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
11 changes: 6 additions & 5 deletions container/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import config
import filetype
import urllib.parse as urlparse
from logger import logger


class Route:
Expand Down Expand Up @@ -195,7 +196,7 @@ async def handle(self, request: 'Request', client: Client):
}))(request, client)
def mount(self, router: Router):
self._routes.append(router)
print(f"Serve router at: {router.prefix}")
logger.info(f"Serve router at: {router.prefix}")
def mount_resource(self, resource: Resource):
self._resources.append(resource)

Expand Down Expand Up @@ -491,7 +492,7 @@ async def handle(data, client: Client):
request: Request = Request(data, client)
await app.handle(request, client)
await request.skip()
print(request.get_request_time(), "|", request.method.ljust(6), request.get_status_code(), "|", request.get_ip().ljust(16), "|", request.url, request.get_user_agent())
logger.info(request.method.ljust(6), request.get_status_code(), "|", request.get_ip().ljust(16), "|", request.url, request.get_user_agent())
except TimeoutError:
...
except:
Expand Down Expand Up @@ -542,15 +543,15 @@ async def main():
load_cert()
import cluster
await cluster.init()
while 1:
while True:
try:
server = await asyncio.start_server(_handle, host='0.0.0.0', port=config.PORT, ssl=cert)
print(f"Server listen on {config.PORT}{' with ssl' if cert else ''}!")
logger.info(f"Server listening on {config.PORT}{' with ssl' if cert else ''}!")
await server.serve_forever()
except:
if server:
server.close()
traceback.print_exc()
logger.error(traceback.format_exc())

@app.get("/favicon.ico")
async def _():
Expand Down
1 change: 1 addition & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Optional
import sys
import time
from container.logger import logger
from watchdog.observers import Observer
from watchdog.events import FileSystemEvent, FileSystemEventHandler
encoding = sys.getdefaultencoding()
Expand Down
Binary file modified requirements.txt
Binary file not shown.

0 comments on commit b29d35a

Please sign in to comment.