xhtm 0.6__tar.gz → 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.
- {xhtm-0.6 → xhtm-0.8}/PKG-INFO +2 -1
- {xhtm-0.6 → xhtm-0.8}/xhtm.egg-info/PKG-INFO +2 -1
- {xhtm-0.6 → xhtm-0.8}/xhtm.egg-info/requires.txt +1 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/attribute.py +1 -1
- {xhtm-0.6 → xhtm-0.8}/xhtml/header/headers.py +52 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/locale/template.py +3 -2
- {xhtm-0.6 → xhtm-0.8}/xhtml/resource/__init__.py +28 -12
- {xhtm-0.6 → xhtm-0.8}/xhtml/template/__init__.py +4 -2
- {xhtm-0.6 → xhtm-0.8}/LICENSE +0 -0
- {xhtm-0.6 → xhtm-0.8}/README.md +0 -0
- {xhtm-0.6 → xhtm-0.8}/setup.cfg +0 -0
- {xhtm-0.6 → xhtm-0.8}/setup.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtm.egg-info/SOURCES.txt +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtm.egg-info/dependency_links.txt +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtm.egg-info/top_level.txt +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtm.egg-info/zip-safe +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/__init__.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/element/__init__.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/element/attr.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/element/css.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/element/doc.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/element/tag.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/header/__init__.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/header/accept.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/header/content.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/locale/__init__.py +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/resource/favicon.ico +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/resource/logo.svg +0 -0
- {xhtm-0.6 → xhtm-0.8}/xhtml/template/hello.html +0 -0
{xhtm-0.6 → xhtm-0.8}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: xhtm
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8
|
|
4
4
|
Summary: Rendering HTML Text
|
|
5
5
|
Home-page: https://github.com/bondbox/xhtm
|
|
6
6
|
Author: Mingzhe Zou
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
16
16
|
Requires-Python: >=3.8
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
+
Requires-Dist: xkits-lib>=0.2
|
|
19
20
|
Requires-Dist: xlc>=1.0
|
|
20
21
|
Requires-Dist: jinja2
|
|
21
22
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: xhtm
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8
|
|
4
4
|
Summary: Rendering HTML Text
|
|
5
5
|
Home-page: https://github.com/bondbox/xhtm
|
|
6
6
|
Author: Mingzhe Zou
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
16
16
|
Requires-Python: >=3.8
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
+
Requires-Dist: xkits-lib>=0.2
|
|
19
20
|
Requires-Dist: xlc>=1.0
|
|
20
21
|
Requires-Dist: jinja2
|
|
21
22
|
|
|
@@ -5,6 +5,58 @@ from typing import Dict
|
|
|
5
5
|
from typing import Iterator
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
class RequestLine():
|
|
9
|
+
"""HTTP requests
|
|
10
|
+
|
|
11
|
+
Reference:
|
|
12
|
+
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Messages#http_requests
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, request_line: str):
|
|
16
|
+
method, target, protocol = request_line.split()
|
|
17
|
+
self.__protocol: str = protocol.strip()
|
|
18
|
+
self.__method: str = method.strip()
|
|
19
|
+
self.__target: str = target.strip()
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def protocol(self) -> str:
|
|
23
|
+
return self.__protocol
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def method(self) -> str:
|
|
27
|
+
return self.__method
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def target(self) -> str:
|
|
31
|
+
return self.__target
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class StatusLine():
|
|
35
|
+
"""HTTP responses
|
|
36
|
+
|
|
37
|
+
Reference:
|
|
38
|
+
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Messages#http_responses
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, status_line: str):
|
|
42
|
+
protocol, status_code, status_text = status_line.split(maxsplit=2)
|
|
43
|
+
self.__status_code: int = int(status_code.strip())
|
|
44
|
+
self.__status_text: str = status_text.strip()
|
|
45
|
+
self.__protocol: str = protocol.strip()
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def protocol(self) -> str:
|
|
49
|
+
return self.__protocol
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def status_code(self) -> int:
|
|
53
|
+
return self.__status_code
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def status_text(self) -> str:
|
|
57
|
+
return self.__status_text
|
|
58
|
+
|
|
59
|
+
|
|
8
60
|
class Headers(Enum):
|
|
9
61
|
"""HTTP headers
|
|
10
62
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from os.path import join
|
|
4
4
|
|
|
5
|
+
from xkits_lib import TimeUnit
|
|
5
6
|
from xlc.language.message import Message
|
|
6
7
|
from xlc.language.segment import Section
|
|
7
8
|
|
|
@@ -10,9 +11,9 @@ from xhtml.template import Template
|
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class LocaleTemplate(Template):
|
|
13
|
-
def __init__(self, base: str):
|
|
14
|
+
def __init__(self, base: str, lifetime: TimeUnit = 0):
|
|
14
15
|
self.__message: Message = Message(join(base, "locale"))
|
|
15
|
-
super().__init__(base)
|
|
16
|
+
super().__init__(base=base, lifetime=lifetime)
|
|
16
17
|
|
|
17
18
|
def search(self, accept_language: str, section: str) -> Section:
|
|
18
19
|
language: AcceptLanguage = AcceptLanguage(accept_language)
|
|
@@ -9,6 +9,9 @@ from os.path import splitext
|
|
|
9
9
|
from typing import Optional
|
|
10
10
|
|
|
11
11
|
from jinja2 import Environment
|
|
12
|
+
from xkits_lib import CacheMiss
|
|
13
|
+
from xkits_lib import CachePool
|
|
14
|
+
from xkits_lib import TimeUnit
|
|
12
15
|
|
|
13
16
|
BASE_DIR = dirname(abspath(__file__))
|
|
14
17
|
|
|
@@ -19,6 +22,7 @@ class FileResource():
|
|
|
19
22
|
message = f"No such file: {path}"
|
|
20
23
|
raise FileNotFoundError(message)
|
|
21
24
|
self.__ext: str = splitext(path)[1]
|
|
25
|
+
self.__data: Optional[bytes] = None
|
|
22
26
|
self.__path: str = path
|
|
23
27
|
|
|
24
28
|
@property
|
|
@@ -29,13 +33,14 @@ class FileResource():
|
|
|
29
33
|
def path(self) -> str:
|
|
30
34
|
return self.__path
|
|
31
35
|
|
|
32
|
-
def loads(self) -> str:
|
|
33
|
-
with open(self.path, "r", encoding="utf-8") as rhdl:
|
|
34
|
-
return rhdl.read()
|
|
35
|
-
|
|
36
36
|
def loadb(self) -> bytes:
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
if self.__data is None:
|
|
38
|
+
with open(self.path, "rb") as rhdl:
|
|
39
|
+
self.__data = rhdl.read()
|
|
40
|
+
return self.__data
|
|
41
|
+
|
|
42
|
+
def loads(self, encoding: str = "utf-8") -> str:
|
|
43
|
+
return self.loadb().decode(encoding=encoding)
|
|
39
44
|
|
|
40
45
|
def render(self, **context: str) -> str:
|
|
41
46
|
"""render html template"""
|
|
@@ -45,7 +50,8 @@ class FileResource():
|
|
|
45
50
|
class Resource():
|
|
46
51
|
FAVICON: str = "favicon.ico"
|
|
47
52
|
|
|
48
|
-
def __init__(self, base: Optional[str] = None):
|
|
53
|
+
def __init__(self, base: Optional[str] = None, lifetime: TimeUnit = 0):
|
|
54
|
+
self.__cache: CachePool[str, FileResource] = CachePool(lifetime)
|
|
49
55
|
self.__base: str = base if base and isdir(base) else BASE_DIR
|
|
50
56
|
|
|
51
57
|
@property
|
|
@@ -56,13 +62,23 @@ class Resource():
|
|
|
56
62
|
def favicon(self) -> FileResource:
|
|
57
63
|
return self.seek(self.FAVICON)
|
|
58
64
|
|
|
59
|
-
def find(self, *args: str) -> Optional[
|
|
65
|
+
def find(self, *args: str) -> Optional[FileResource]:
|
|
60
66
|
def check(base: str, real: str) -> Optional[str]:
|
|
61
67
|
return path if isfile(path := join(base, real)) else check(BASE_DIR, real) if base != BASE_DIR else None # noqa:E501
|
|
62
|
-
|
|
68
|
+
|
|
69
|
+
if (real := join(*args)) in self.__cache:
|
|
70
|
+
try:
|
|
71
|
+
return self.__cache.get(real)
|
|
72
|
+
except CacheMiss:
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
resource: Optional[FileResource] = None
|
|
76
|
+
if isinstance(path := check(self.base, real), str):
|
|
77
|
+
resource = FileResource(path)
|
|
78
|
+
self.__cache.put(real, resource)
|
|
79
|
+
return resource
|
|
63
80
|
|
|
64
81
|
def seek(self, *args: str) -> FileResource:
|
|
65
|
-
|
|
66
|
-
if not isinstance(path, str):
|
|
82
|
+
if not isinstance(resource := self.find(*args), FileResource):
|
|
67
83
|
raise FileNotFoundError(f"No such file: {join(*args)}")
|
|
68
|
-
return
|
|
84
|
+
return resource
|
|
@@ -5,6 +5,8 @@ from os.path import dirname
|
|
|
5
5
|
from os.path import isdir
|
|
6
6
|
from typing import Optional
|
|
7
7
|
|
|
8
|
+
from xkits_lib import TimeUnit
|
|
9
|
+
|
|
8
10
|
from xhtml.resource import Resource
|
|
9
11
|
|
|
10
12
|
BASE_DIR = dirname(abspath(__file__))
|
|
@@ -13,5 +15,5 @@ BASE_DIR = dirname(abspath(__file__))
|
|
|
13
15
|
class Template(Resource):
|
|
14
16
|
FAVICON: str = "favicon.ico"
|
|
15
17
|
|
|
16
|
-
def __init__(self, base: Optional[str] = None):
|
|
17
|
-
super().__init__(base if base and isdir(base) else BASE_DIR)
|
|
18
|
+
def __init__(self, base: Optional[str] = None, lifetime: TimeUnit = 0):
|
|
19
|
+
super().__init__(base if base and isdir(base) else BASE_DIR, lifetime)
|
{xhtm-0.6 → xhtm-0.8}/LICENSE
RENAMED
|
File without changes
|
{xhtm-0.6 → xhtm-0.8}/README.md
RENAMED
|
File without changes
|
{xhtm-0.6 → xhtm-0.8}/setup.cfg
RENAMED
|
File without changes
|
{xhtm-0.6 → xhtm-0.8}/setup.py
RENAMED
|
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
|
|
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
|