Skip to content

Commit 2fbc427

Browse files
committed
🎨 fix the f**king typo and grammar
- 修复所有 typo - 修复所有语法错误 - 重构 logger 和 config 逻辑
1 parent b7733a0 commit 2fbc427

File tree

14 files changed

+809
-293
lines changed

14 files changed

+809
-293
lines changed

README.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,30 +79,29 @@
7979

8080
```sh
8181
docker run -d \
82-
-v ${/data/python-openbmclapi}:/python-openbmclapi/bmclapi \
83-
-e cluster_id=${cluster_id} \
84-
-e cluster_secret=${cluster_secret} \
85-
-e public_port=${port} \
86-
-v /data/openbmclapi:/opt/openbmclapi/cache \
87-
-p ${port}:80 \
82+
-v ${/data/python-openbmclapi}:/bmclapi \
83+
-e cluster.id=${cluster.id} \
84+
-e cluster.secret=${cluster.secret} \
85+
-e web.public_port=${web.public_port} \
86+
-p ${web.public_port}:80 \
8887
--restart always \
8988
--name python-openbmclapi \
9089
silianz/python-openbmclapi
9190
```
9291

9392
**参数说明:**
9493

95-
`port` - 对外开放的端口。
94+
`web.public_port` - 对外开放的端口。
9695

97-
`cluster_id` - 即 `CLUSTER_ID`
96+
`cluster.id` - 即 `CLUSTER_ID`
9897

99-
`cluster_secret` - 即 `CLUSTER_SECRET`
98+
`cluster.secret` - 即 `CLUSTER_SECRET`
10099

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

103102
## 配置文件
104103

105-
```yaml
104+
```yml
106105
# 是否不使用 BMCLAPI 分发的证书, 同 CLUSTER_BYOC
107106
byoc: false
108107
# OpenBMCLAPI 的 CLUSTER_ID

core/__init__.py

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,41 +18,56 @@ class Protocol(Enum):
1818
HTTP = "HTTP"
1919
Unknown = "Unknown"
2020
DETECT = "Detect"
21+
2122
@staticmethod
2223
def get(data: bytes):
23-
if b'HTTP/1.1' in data:
24+
if b"HTTP/1.1" in data:
2425
return Protocol.HTTP
2526
if check_port_key == data:
2627
return Protocol.DETECT
2728
return Protocol.Unknown
29+
30+
2831
@dataclass
2932
class ProxyClient:
30-
proxy: 'Proxy'
33+
proxy: "Proxy"
3134
origin: Client
3235
target: Client
33-
before: bytes = b''
36+
before: bytes = b""
3437
closed: bool = False
38+
3539
def start(self):
3640
self._task_origin = Timer.delay(self.process_origin, (), 0)
37-
self._task_target = Timer.delay(self.process_target, (), 0)
41+
self._task_target = Timer.delay(self.process_target, (), 0)
42+
3843
async def process_origin(self):
3944
try:
4045
self.target.write(self.before)
41-
while (buffer := await self.origin.read(IO_BUFFER, timeout=TIMEOUT)) and not self.origin.is_closed() and not self.origin.is_closed():
46+
while (
47+
(buffer := await self.origin.read(IO_BUFFER, timeout=TIMEOUT))
48+
and not self.origin.is_closed()
49+
and not self.origin.is_closed()
50+
):
4251
self.target.write(buffer)
43-
self.before = b''
52+
self.before = b""
4453
await self.target.writer.drain()
4554
except:
4655
...
4756
self.close()
57+
4858
async def process_target(self):
4959
try:
50-
while (buffer := await self.target.read(IO_BUFFER, timeout=TIMEOUT)) and not self.target.is_closed() and not self.target.is_closed():
60+
while (
61+
(buffer := await self.target.read(IO_BUFFER, timeout=TIMEOUT))
62+
and not self.target.is_closed()
63+
and not self.target.is_closed()
64+
):
5165
self.origin.write(buffer)
5266
await self.origin.writer.drain()
5367
except:
5468
...
5569
self.close()
70+
5671
def close(self):
5772
if not self.closed:
5873
if not self.origin.is_closed():
@@ -61,47 +76,63 @@ def close(self):
6176
self.target.close()
6277
self.closed = True
6378
self.proxy.disconnect(self)
79+
80+
6481
class Proxy:
6582
def __init__(self) -> None:
6683
self._tables: list[ProxyClient] = []
84+
6785
async def connect(self, origin: Client, target: Client, before: bytes):
6886
client = ProxyClient(self, origin, target, before)
6987
self._tables.append(client)
7088
client.start()
89+
7190
def disconnect(self, client: ProxyClient):
7291
if client not in self._tables:
7392
return
7493
self._tables.remove(client)
7594

95+
7696
ssl_server: Optional[asyncio.Server] = None
7797
server: Optional[asyncio.Server] = None
7898
proxy: Proxy = Proxy()
7999
restart = False
80100
check_port_key = os.urandom(8)
81-
PORT: int = Config.get("web.port")
82-
TIMEOUT: int = Config.get("advanced.timeout")
101+
PORT: int = Config.get("web.port")
102+
TIMEOUT: int = Config.get("advanced.timeout")
83103
SSL_PORT: int = Config.get("web.ssl_port")
84104
PROTOCOL_HEADER_BYTES = Config.get("advanced.header_bytes")
85105
IO_BUFFER: int = Config.get("advanced.io_buffer")
86106

107+
87108
async def _handle_ssl(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
88109
return await _handle_process(Client(reader, writer), True)
89110

111+
90112
async def _handle(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
91113
return await _handle_process(Client(reader, writer))
92114

115+
93116
async def _handle_process(client: Client, ssl: bool = False):
94117
global ssl_server
95118
proxying = False
96119
try:
97-
while (header := await client.read(PROTOCOL_HEADER_BYTES, timeout=30)) and not client.is_closed():
120+
while (
121+
header := await client.read(PROTOCOL_HEADER_BYTES, timeout=30)
122+
) and not client.is_closed():
98123
protocol = Protocol.get(header)
99124
if protocol == Protocol.DETECT:
100125
client.write(check_port_key)
101126
await client.writer.drain()
102127
break
103128
if protocol == Protocol.Unknown and not ssl and ssl_server:
104-
target = Client(*(await asyncio.open_connection("127.0.0.1", ssl_server.sockets[0].getsockname()[1])))
129+
target = Client(
130+
*(
131+
await asyncio.open_connection(
132+
"127.0.0.1", ssl_server.sockets[0].getsockname()[1]
133+
)
134+
)
135+
)
105136
proxying = True
106137
await proxy.connect(client, target, header)
107138
break
@@ -117,40 +148,64 @@ async def _handle_process(client: Client, ssl: bool = False):
117148
logger.debug(traceback.format_exc())
118149
if not proxying and not client.is_closed():
119150
client.close()
151+
152+
120153
async def check_ports():
121154
global ssl_server, server, client_side_ssl, restart, check_port_key
122155
while 1:
123156
ports: list[tuple[asyncio.Server, ssl.SSLContext | None]] = []
124-
for service in ((server, None), (ssl_server, client_side_ssl if get_loads() != 0 else None)):
157+
for service in (
158+
(server, None),
159+
(ssl_server, client_side_ssl if get_loads() != 0 else None),
160+
):
125161
if not service[0]:
126162
continue
127163
ports.append((service[0], service[1]))
128164
closed = False
129165
for port in ports:
130166
try:
131-
client = Client(*(await asyncio.open_connection('127.0.0.1', port[0].sockets[0].getsockname()[1], ssl=port[1])))
167+
client = Client(
168+
*(
169+
await asyncio.open_connection(
170+
"127.0.0.1",
171+
port[0].sockets[0].getsockname()[1],
172+
ssl=port[1],
173+
)
174+
)
175+
)
132176
client.write(check_port_key)
133177
await client.writer.drain()
134178
key = await client.read(len(check_port_key), 5)
135179
except:
136-
logger.warn(f"Port {port[0].sockets[0].getsockname()[1]} is shutdown now! Now restarting the port!")
180+
logger.warn(
181+
f"Port {port[0].sockets[0].getsockname()[1]} has been closed! Reopening..."
182+
)
137183
logger.error(traceback.format_exc())
138184
closed = True
139185
if closed:
140186
restart = True
141187
for port in ports:
142188
port[0].close()
143189
await asyncio.sleep(5)
190+
191+
144192
async def main():
145193
global ssl_server, server, server_side_ssl, restart
146194
await web.init()
147195
Timer.delay(check_ports, (), 5)
148196
while 1:
149197
try:
150198
server = await asyncio.start_server(_handle, port=PORT)
151-
ssl_server = await asyncio.start_server(_handle_ssl, port=0 if SSL_PORT == PORT else SSL_PORT, ssl=server_side_ssl if get_loads() != 0 else None)
152-
logger.info(f"Listening server on {PORT}")
153-
logger.info(f"Listening server on {ssl_server.sockets[0].getsockname()[1]} Loaded certificates: {get_loads()}")
199+
ssl_server = await asyncio.start_server(
200+
_handle_ssl,
201+
port=0 if SSL_PORT == PORT else SSL_PORT,
202+
ssl=server_side_ssl if get_loads() != 0 else None,
203+
)
204+
logger.info(f"Listening server on port {PORT}.")
205+
logger.info(
206+
f"Listening server on {ssl_server.sockets[0].getsockname()[1]}."
207+
)
208+
logger.info(f"Loaded {get_loads()} certificates!")
154209
async with server, ssl_server:
155210
await asyncio.gather(server.serve_forever(), ssl_server.serve_forever())
156211
except asyncio.CancelledError:
@@ -159,8 +214,8 @@ async def main():
159214
server.close()
160215
restart = False
161216
else:
162-
logger.info("Shutdown web service")
163-
await web.close()
217+
logger.info("Shutting down web service...")
218+
web.close()
164219
break
165220
except:
166221
if server:
@@ -170,4 +225,4 @@ async def main():
170225

171226

172227
def init():
173-
asyncio.run(main())
228+
asyncio.run(main())

core/api.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,20 @@ class BMCLAPIFile:
1818
path: str
1919
hash: str
2020
size: int
21-
def __hash__(self):
21+
22+
def __hash__(self):
2223
return int.from_bytes(bytes.fromhex(self.hash))
23-
24-
def __eq__(self, other):
25-
if isinstance(other, BMCLAPIFile):
26-
return self.hash == other.hash and self.size == other.size and self.path == other.path
24+
25+
def __eq__(self, other):
26+
if isinstance(other, BMCLAPIFile):
27+
return (
28+
self.hash == other.hash
29+
and self.size == other.size
30+
and self.path == other.path
31+
)
2732
return False
2833

34+
2935
@dataclass
3036
class File:
3137
path: Path | str
@@ -34,53 +40,67 @@ class File:
3440
last_hit: float = 0
3541
last_access: float = 0
3642
data: Optional[io.BytesIO] = None
43+
3744
def is_url(self):
3845
if not isinstance(self.path, str):
3946
return False
4047
return self.path.startswith("http://") or self.path.startswith("https://")
48+
4149
def get_path(self) -> str | Path:
4250
return self.path
51+
4352
def get_data(self):
4453
if not self.data:
4554
return io.BytesIO()
4655
return io.BytesIO(zlib.decompress(self.data.getbuffer()))
56+
4757
def set_data(self, data: io.BytesIO | memoryview | bytes):
4858
if not isinstance(data, io.BytesIO):
4959
data = io.BytesIO(data)
5060
self.data = io.BytesIO(zlib.compress(data.getbuffer()))
5161

62+
5263
class Storage(metaclass=abc.ABCMeta):
5364
@abc.abstractmethod
5465
async def get(self, file: str) -> File:
5566
"""
56-
return
57-
type: Path, str
58-
Path: Local File
59-
str: url
67+
return
68+
type: Path, str
69+
Path: Local File
70+
str: url
6071
"""
6172
raise NotImplementedError
73+
6274
@abc.abstractmethod
6375
async def exists(self, hash: str) -> bool:
6476
raise NotImplementedError
77+
6578
@abc.abstractmethod
6679
async def get_size(self, hash: str) -> int:
6780
raise NotImplementedError
81+
6882
@abc.abstractmethod
6983
async def write(self, hash: str, io: io.BytesIO) -> int:
7084
raise NotImplementedError
85+
7186
@abc.abstractmethod
72-
async def check_missing_files(self, pbar: tqdm, files: list[BMCLAPIFile]) -> list[BMCLAPIFile]:
87+
async def check_missing_files(
88+
self, pbar: tqdm, files: list[BMCLAPIFile]
89+
) -> list[BMCLAPIFile]:
7390
raise NotImplementedError
91+
7492
@abc.abstractmethod
7593
async def get_files(self, dir: str) -> list[str]:
7694
raise NotImplementedError
95+
7796
@abc.abstractmethod
7897
async def get_files_size(self, dir: str) -> int:
7998
raise NotImplementedError
99+
80100
@abc.abstractmethod
81101
async def removes(self, hashs: list[str]) -> int:
82102
raise NotImplementedError
83-
103+
84104

85105
def get_hash(org):
86106
if len(org) == 32:
@@ -97,4 +117,4 @@ async def get_file_hash(org: str, path: Path):
97117
break
98118
hash.update(data)
99119
await asyncio.sleep(0.001)
100-
return hash.hexdigest() == org
120+
return hash.hexdigest() == org

0 commit comments

Comments
 (0)