GNServer 0.0.0.0.1__tar.gz → 0.0.0.0.3__tar.gz

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.
@@ -0,0 +1,39 @@
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
+ """
31
+
32
+ from ._app import App
33
+ from KeyisBClient.gn import GNRequest, GNResponse
34
+
35
+
36
+
37
+
38
+
39
+
@@ -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:origin:405", {'error': 'Method Not Allowed'})
218
- return gn.GNResponse("gn:origin:404", {'error': 'Not Found'})
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:origin:500:Internal Server Error')
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
- payload[ext_file] = await file.read()
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['html'] = f'GNServer error: {e}'
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.1
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
@@ -1,4 +1,5 @@
1
1
  aioquic
2
2
  anyio
3
3
  KeyisBClient
4
+ aiofiles
4
5
  uvloop
@@ -3,6 +3,7 @@
3
3
  "aioquic",
4
4
  "anyio",
5
5
  "KeyisBClient",
6
+ "aiofiles",
6
7
  "uvloop"
7
8
  ]
8
9
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GNServer
3
- Version: 0.0.0.0.1
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
@@ -5,7 +5,7 @@ filesName = 'GNServer'
5
5
 
6
6
  setup(
7
7
  name=name,
8
- version='0.0.0.0.1',
8
+ version='0.0.0.0.3',
9
9
  author="KeyisB",
10
10
  author_email="keyisb.pip@gmail.com",
11
11
  description=name,
@@ -21,5 +21,5 @@ setup(
21
21
  ],
22
22
  python_requires='>=3.12',
23
23
  license="MMB License v1.0",
24
- install_requires = ['aioquic', 'anyio', 'KeyisBClient', 'uvloop'],
24
+ install_requires = ['aioquic', 'anyio', 'KeyisBClient', 'aiofiles', 'uvloop'],
25
25
  )
@@ -1,10 +0,0 @@
1
-
2
-
3
- from ._app import App
4
-
5
-
6
-
7
-
8
-
9
-
10
-
File without changes
File without changes
File without changes