GNServer 0.0.0.0.1__py3-none-any.whl → 0.0.0.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- GNServer/__init__.py +31 -2
- GNServer/_app.py +92 -9
- {gnserver-0.0.0.0.1.dist-info → gnserver-0.0.0.0.3.dist-info}/METADATA +2 -1
- gnserver-0.0.0.0.3.dist-info/RECORD +7 -0
- gnserver-0.0.0.0.1.dist-info/RECORD +0 -7
- {gnserver-0.0.0.0.1.dist-info → gnserver-0.0.0.0.3.dist-info}/WHEEL +0 -0
- {gnserver-0.0.0.0.1.dist-info → gnserver-0.0.0.0.3.dist-info}/licenses/LICENSE +0 -0
- {gnserver-0.0.0.0.1.dist-info → gnserver-0.0.0.0.3.dist-info}/top_level.txt +0 -0
GNServer/__init__.py
CHANGED
@@ -1,7 +1,36 @@
|
|
1
|
-
|
1
|
+
"""
|
2
|
+
Copyright (C) 2024 KeyisB. All rights reserved.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person
|
5
|
+
obtaining a copy of this software and associated documentation
|
6
|
+
files (the "Software"), to use the Software exclusively for
|
7
|
+
projects related to the GN or GW systems, including personal,
|
8
|
+
educational, and commercial purposes, subject to the following
|
9
|
+
conditions:
|
10
|
+
|
11
|
+
1. Copying, modification, merging, publishing, distribution,
|
12
|
+
sublicensing, and/or selling copies of the Software are
|
13
|
+
strictly prohibited.
|
14
|
+
2. The licensee may use the Software only in its original,
|
15
|
+
unmodified form.
|
16
|
+
3. All copies or substantial portions of the Software must
|
17
|
+
remain unaltered and include this copyright notice and these terms of use.
|
18
|
+
4. Use of the Software for projects not related to GN or
|
19
|
+
GW systems is strictly prohibited.
|
20
|
+
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
22
|
+
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
23
|
+
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
24
|
+
A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. IN NO EVENT
|
25
|
+
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
26
|
+
CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION
|
27
|
+
OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR
|
28
|
+
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
29
|
+
DEALINGS IN THE SOFTWARE.
|
30
|
+
"""
|
2
31
|
|
3
32
|
from ._app import App
|
4
|
-
|
33
|
+
from KeyisBClient.gn import GNRequest, GNResponse
|
5
34
|
|
6
35
|
|
7
36
|
|
GNServer/_app.py
CHANGED
@@ -20,8 +20,9 @@ from typing import Any, AsyncGenerator, Union, get_origin, get_args
|
|
20
20
|
from urllib.parse import parse_qs
|
21
21
|
|
22
22
|
from KeyisBClient import gn
|
23
|
-
|
23
|
+
import aiofiles
|
24
24
|
import sys
|
25
|
+
import os
|
25
26
|
|
26
27
|
try:
|
27
28
|
if not sys.platform.startswith("win"):
|
@@ -43,6 +44,64 @@ console = logging.StreamHandler()
|
|
43
44
|
console.setLevel(logging.INFO)
|
44
45
|
console.setFormatter(logging.Formatter("[GNServer] %(name)s: %(levelname)s: %(message)s"))
|
45
46
|
|
47
|
+
def guess_type(filename: str) -> str:
|
48
|
+
"""
|
49
|
+
Возвращает актуальный MIME-тип по расширению файла.
|
50
|
+
Только современные и часто используемые типы.
|
51
|
+
"""
|
52
|
+
ext = filename.lower().rsplit('.', 1)[-1] if '.' in filename else ''
|
53
|
+
|
54
|
+
mime_map = {
|
55
|
+
# 🔹 Текст и данные
|
56
|
+
"txt": "text/plain",
|
57
|
+
"html": "text/html",
|
58
|
+
"css": "text/css",
|
59
|
+
"csv": "text/csv",
|
60
|
+
"xml": "application/xml",
|
61
|
+
"json": "application/json",
|
62
|
+
"js": "application/javascript",
|
63
|
+
|
64
|
+
# 🔹 Изображения (актуальные для веба)
|
65
|
+
"jpg": "image/jpeg",
|
66
|
+
"jpeg": "image/jpeg",
|
67
|
+
"png": "image/png",
|
68
|
+
"gif": "image/gif",
|
69
|
+
"webp": "image/webp",
|
70
|
+
"svg": "image/svg+xml",
|
71
|
+
"avif": "image/avif",
|
72
|
+
|
73
|
+
# 🔹 Видео (современные форматы)
|
74
|
+
"mp4": "video/mp4",
|
75
|
+
"webm": "video/webm",
|
76
|
+
|
77
|
+
# 🔹 Аудио (современные форматы)
|
78
|
+
"mp3": "audio/mpeg",
|
79
|
+
"ogg": "audio/ogg",
|
80
|
+
"oga": "audio/ogg",
|
81
|
+
"m4a": "audio/mp4",
|
82
|
+
"flac": "audio/flac",
|
83
|
+
|
84
|
+
# 🔹 Архивы
|
85
|
+
"zip": "application/zip",
|
86
|
+
"gz": "application/gzip",
|
87
|
+
"tar": "application/x-tar",
|
88
|
+
"7z": "application/x-7z-compressed",
|
89
|
+
"rar": "application/vnd.rar",
|
90
|
+
|
91
|
+
# 🔹 Документы (актуальные офисные)
|
92
|
+
"pdf": "application/pdf",
|
93
|
+
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
94
|
+
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
95
|
+
"pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
96
|
+
|
97
|
+
# 🔹 Шрифты
|
98
|
+
"woff": "font/woff",
|
99
|
+
"woff2": "font/woff2",
|
100
|
+
"ttf": "font/ttf",
|
101
|
+
"otf": "font/otf",
|
102
|
+
}
|
103
|
+
|
104
|
+
return mime_map.get(ext, "application/octet-stream")
|
46
105
|
|
47
106
|
|
48
107
|
@dataclass
|
@@ -214,8 +273,32 @@ class App:
|
|
214
273
|
)
|
215
274
|
|
216
275
|
if allowed:
|
217
|
-
return gn.GNResponse("gn:
|
218
|
-
return gn.GNResponse("gn:
|
276
|
+
return gn.GNResponse("gn:backend:405", {'error': 'Method Not Allowed'})
|
277
|
+
return gn.GNResponse("gn:backend:404", {'error': 'Not Found'})
|
278
|
+
|
279
|
+
|
280
|
+
def static(self, path: str, dir_path: str):
|
281
|
+
@self.get(f"/{path}/{{_path:path}}")
|
282
|
+
async def r_static(_path: str):
|
283
|
+
file_path = os.path.join(dir_path, _path)
|
284
|
+
if not os.path.isfile(file_path):
|
285
|
+
return gn.GNResponse('gn:backend:404')
|
286
|
+
|
287
|
+
mime_type = guess_type(file_path)
|
288
|
+
async with aiofiles.open(file_path, "rb") as f:
|
289
|
+
data = f.read()
|
290
|
+
|
291
|
+
return gn.GNResponse('ok', {'files': [{'mime-type': mime_type, 'data': data}]})
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
|
300
|
+
|
301
|
+
|
219
302
|
|
220
303
|
|
221
304
|
class _ServerProto(QuicConnectionProtocol):
|
@@ -337,7 +420,7 @@ class App:
|
|
337
420
|
except Exception as e:
|
338
421
|
logger.error('GNServer: error\n' + traceback.format_exc())
|
339
422
|
|
340
|
-
response = gn.GNResponse('gn:
|
423
|
+
response = gn.GNResponse('gn:backend:500:Internal Server Error')
|
341
424
|
self._quic.send_stream_data(request.stream_id, response.serialize(3), end_stream=True)
|
342
425
|
self.transmit()
|
343
426
|
|
@@ -360,13 +443,13 @@ class App:
|
|
360
443
|
if ext_file_.startswith('/') or ext_file_.startswith('./'):
|
361
444
|
try:
|
362
445
|
async with await anyio.open_file(ext_file_, mode="rb") as file:
|
363
|
-
|
446
|
+
data = await file.read()
|
447
|
+
|
448
|
+
payload.pop(ext_file)
|
449
|
+
payload['files'] = [{'mime-type': guess_type(ext_file), 'data': data}]
|
364
450
|
except Exception as e:
|
365
|
-
payload[
|
451
|
+
payload[ext_file] = f'GNServer error: {e}'
|
366
452
|
logger.debug(f'error resolving extra response -> {traceback.format_exc()}')
|
367
|
-
|
368
|
-
|
369
|
-
|
370
453
|
return response
|
371
454
|
|
372
455
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: GNServer
|
3
|
-
Version: 0.0.0.0.
|
3
|
+
Version: 0.0.0.0.3
|
4
4
|
Summary: GNServer
|
5
5
|
Home-page: https://github.com/KeyisB/libs/tree/main/GNServer
|
6
6
|
Author: KeyisB
|
@@ -14,6 +14,7 @@ License-File: LICENSE
|
|
14
14
|
Requires-Dist: aioquic
|
15
15
|
Requires-Dist: anyio
|
16
16
|
Requires-Dist: KeyisBClient
|
17
|
+
Requires-Dist: aiofiles
|
17
18
|
Requires-Dist: uvloop
|
18
19
|
Dynamic: author
|
19
20
|
Dynamic: author-email
|
@@ -0,0 +1,7 @@
|
|
1
|
+
GNServer/__init__.py,sha256=T6kT6WoJpmIXashMSHfuafb9DSePUIzw192h27j9a4M,1364
|
2
|
+
GNServer/_app.py,sha256=dCV8vs3eWna4QbF2WpNYsDROZTIf1LJIZrYXUyxEomg,17116
|
3
|
+
gnserver-0.0.0.0.3.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
|
4
|
+
gnserver-0.0.0.0.3.dist-info/METADATA,sha256=F2nrEBBzvO2H173MvRZVZ-zC4J_e1LFyzqdAM5d6LGc,804
|
5
|
+
gnserver-0.0.0.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
6
|
+
gnserver-0.0.0.0.3.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
|
7
|
+
gnserver-0.0.0.0.3.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
GNServer/__init__.py,sha256=o2IMhiQljnpMpxH3o9gyenvLA7jgJkwUASwfYh4DY80,31
|
2
|
-
GNServer/_app.py,sha256=rzYMN1vnMJNAPw_xjp4EophMI1jM5-4wI1aaJL368fg,14371
|
3
|
-
gnserver-0.0.0.0.1.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
|
4
|
-
gnserver-0.0.0.0.1.dist-info/METADATA,sha256=YzjlkVBkSVbjQyptoh695OGfAfQxP80MtdhtvQZJfNE,779
|
5
|
-
gnserver-0.0.0.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
6
|
-
gnserver-0.0.0.0.1.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
|
7
|
-
gnserver-0.0.0.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|