GNServer 0.0.0.0.7__tar.gz → 0.0.0.0.8__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.
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/GNServer/_app.py +58 -33
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/GNServer.egg-info/PKG-INFO +1 -1
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/GNServer.egg-info/SOURCES.txt +0 -1
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/PKG-INFO +1 -1
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/setup.py +1 -1
- gnserver-0.0.0.0.7/GNServer/GNServer/models.py +0 -25
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/GNServer/__init__.py +0 -0
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/GNServer.egg-info/dependency_links.txt +0 -0
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/GNServer.egg-info/requires.txt +0 -0
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/GNServer.egg-info/top_level.txt +0 -0
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/LICENSE +0 -0
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/GNServer/mmbConfig.json +0 -0
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/LICENSE +0 -0
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/MANIFEST.in +0 -0
- {gnserver-0.0.0.0.7 → gnserver-0.0.0.0.8}/setup.cfg +0 -0
@@ -110,6 +110,59 @@ def guess_type(filename: str) -> str:
|
|
110
110
|
return mime_map.get(ext, "application/octet-stream")
|
111
111
|
|
112
112
|
|
113
|
+
import re
|
114
|
+
from typing import List
|
115
|
+
|
116
|
+
# regex для !{var}, поддерживает вложенность через точку
|
117
|
+
TPL_VAR_RE = re.compile(r'(?<!\\)!\{([A-Za-z_][A-Za-z0-9_\.]*)\}')
|
118
|
+
|
119
|
+
# список mime, которые считаем текстовыми
|
120
|
+
TEXTUAL_MIME_PREFIXES = [
|
121
|
+
"text/", # text/html, text/css, text/plain
|
122
|
+
]
|
123
|
+
TEXTUAL_MIME_EXACT = {
|
124
|
+
"application/javascript",
|
125
|
+
"application/json",
|
126
|
+
"application/xml",
|
127
|
+
"application/xhtml+xml"
|
128
|
+
}
|
129
|
+
TEXTUAL_MIME_SUFFIXES = (
|
130
|
+
"+xml", # например application/rss+xml
|
131
|
+
"+json", # application/ld+json
|
132
|
+
)
|
133
|
+
|
134
|
+
def extract_template_vars(filedata: bytes, mime: str) -> List[str]:
|
135
|
+
"""
|
136
|
+
Ищет все !{var} в тексте, если MIME относится к текстовым.
|
137
|
+
"""
|
138
|
+
mime = (mime or "").lower().strip()
|
139
|
+
|
140
|
+
# определяем, текстовый ли mime
|
141
|
+
is_textual = (
|
142
|
+
mime.startswith(tuple(TEXTUAL_MIME_PREFIXES))
|
143
|
+
or mime in TEXTUAL_MIME_EXACT
|
144
|
+
or mime.endswith(TEXTUAL_MIME_SUFFIXES)
|
145
|
+
or "javascript" in mime
|
146
|
+
or "json" in mime
|
147
|
+
or "xml" in mime
|
148
|
+
)
|
149
|
+
|
150
|
+
if not is_textual:
|
151
|
+
return []
|
152
|
+
|
153
|
+
try:
|
154
|
+
text = filedata.decode("utf-8", errors="ignore")
|
155
|
+
except Exception:
|
156
|
+
return []
|
157
|
+
|
158
|
+
return list(set(m.group(1) for m in TPL_VAR_RE.finditer(text)))
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
|
113
166
|
@dataclass
|
114
167
|
class Route:
|
115
168
|
method: str
|
@@ -290,7 +343,7 @@ class App:
|
|
290
343
|
|
291
344
|
def fastFile(self, path: str, file_path: str, cors: Optional[gn.CORSObject] = None):
|
292
345
|
@self.get(path)
|
293
|
-
async def r_static(
|
346
|
+
async def r_static():
|
294
347
|
nonlocal file_path
|
295
348
|
if file_path.endswith('/'):
|
296
349
|
file_path = file_path[:-1]
|
@@ -429,10 +482,6 @@ class App:
|
|
429
482
|
|
430
483
|
response = await self._api.dispatch(request)
|
431
484
|
|
432
|
-
|
433
|
-
response = await self.resolve_extra_response(response)
|
434
|
-
|
435
|
-
|
436
485
|
if inspect.isasyncgen(response):
|
437
486
|
async for chunk in response: # type: ignore[misc]
|
438
487
|
chunk._stream = True
|
@@ -455,7 +504,7 @@ class App:
|
|
455
504
|
except Exception as e:
|
456
505
|
logger.error('GNServer: error\n' + traceback.format_exc())
|
457
506
|
|
458
|
-
response = gn.GNResponse('gn:backend:500
|
507
|
+
response = gn.GNResponse('gn:backend:500')
|
459
508
|
self._quic.send_stream_data(request.stream_id, response.serialize(3), end_stream=True)
|
460
509
|
self.transmit()
|
461
510
|
|
@@ -463,36 +512,12 @@ class App:
|
|
463
512
|
if response._cors is None:
|
464
513
|
response._cors = self._api._cors
|
465
514
|
|
515
|
+
await response.assembly()
|
516
|
+
|
466
517
|
return response
|
467
518
|
|
468
519
|
|
469
|
-
|
470
|
-
|
471
|
-
file_types = (
|
472
|
-
'html',
|
473
|
-
'css',
|
474
|
-
'js',
|
475
|
-
'svg'
|
476
|
-
)
|
477
|
-
|
478
|
-
if isinstance(response, gn.GNResponse):
|
479
|
-
payload = response.payload
|
480
|
-
if payload is not None:
|
481
|
-
for ext_file in file_types:
|
482
|
-
ext_file_ = payload.get(ext_file)
|
483
|
-
if ext_file_ is not None:
|
484
|
-
if isinstance(ext_file_, str):
|
485
|
-
if ext_file_.startswith('/') or ext_file_.startswith('./'):
|
486
|
-
try:
|
487
|
-
async with await anyio.open_file(ext_file_, mode="rb") as file:
|
488
|
-
data = await file.read()
|
489
|
-
|
490
|
-
payload.pop(ext_file)
|
491
|
-
payload['files'] = [{'mime-type': guess_type(ext_file_.split('/')[-1]), 'data': data}]
|
492
|
-
except Exception as e:
|
493
|
-
payload[ext_file] = f'GNServer error: {e}'
|
494
|
-
logger.debug(f'error resolving extra response -> {traceback.format_exc()}')
|
495
|
-
return response
|
520
|
+
|
496
521
|
|
497
522
|
|
498
523
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|