Skip to content

Commit cc59344

Browse files
committed
feat: get timezone from TZ [FR]Time zone support/时区如何实现自定义呀 #37
1 parent 2a2773b commit cc59344

4 files changed

Lines changed: 40 additions & 7 deletions

File tree

asgi_webdav/constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ def http_date(self) -> str:
216216
# <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
217217
return self.arrow.format("ddd, DD MMM YYYY HH:mm:ss ZZZ")
218218

219-
def ui_display(self) -> str:
220-
return self.arrow.format(arrow.FORMAT_W3C)
219+
def ui_display(self, timezone: str) -> str:
220+
return self.arrow.replace(tzinfo=timezone).format(arrow.FORMAT_W3C)
221221

222222
def dav_creation_date(self) -> str:
223223
# format borrowed from Apache mod_webdav

asgi_webdav/helpers.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
from logging import getLogger
66
from mimetypes import guess_type as orig_guess_type
77
from pathlib import Path
8+
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
89

910
import aiofiles
1011
import xmltodict
1112
from chardet import UniversalDetector
1213

1314
from asgi_webdav.config import Config
1415
from asgi_webdav.constants import RESPONSE_DATA_BLOCK_SIZE
16+
from asgi_webdav.exception import DAVException
1517

1618
logger = getLogger(__name__)
1719

@@ -154,3 +156,14 @@ def dav_xml2dict(data: bytes) -> dict | None:
154156
return None
155157

156158
return data
159+
160+
161+
def paser_timezone_key(tz_key: str) -> str:
162+
try:
163+
zone_info = ZoneInfo(tz_key)
164+
165+
except ZoneInfoNotFoundError:
166+
# TODO: rewrite, move into config
167+
raise DAVException(f"Invalid timezone: {tz_key}")
168+
169+
return zone_info.key

asgi_webdav/web_dav.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
from copy import copy
22
from dataclasses import dataclass
33
from logging import getLogger
4+
from os import getenv
45

56
from asgi_webdav import __version__
67
from asgi_webdav.config import Config
78
from asgi_webdav.constants import DAVDepth, DAVMethod, DAVPath, DAVTime
8-
from asgi_webdav.exception import DAVExceptionProviderInitFailed
9-
from asgi_webdav.helpers import empty_data_generator, is_browser_user_agent
9+
from asgi_webdav.exception import DAVException, DAVExceptionProviderInitFailed
10+
from asgi_webdav.helpers import (
11+
empty_data_generator,
12+
is_browser_user_agent,
13+
paser_timezone_key,
14+
)
1015
from asgi_webdav.property import DAVProperty
1116
from asgi_webdav.provider.dev_provider import DAVProvider
1217
from asgi_webdav.provider.file_system import FileSystemProvider
@@ -131,6 +136,12 @@ def __init__(self, config: Config):
131136
# init hide file in dir
132137
self._hide_file_in_dir = DAVHideFileInDir(config)
133138

139+
# Please check environment variable
140+
try:
141+
self.timezone = paser_timezone_key(getenv("TZ", "UTC"))
142+
except DAVException as e:
143+
DAVException(f"Please check environment variable: TZ, {e}")
144+
134145
def match_provider(self, request: DAVRequest) -> DAVProvider | None:
135146
weight = None
136147
provider = None
@@ -385,22 +396,22 @@ async def _create_dir_browser_content(
385396
basic_data.display_name,
386397
basic_data.content_type,
387398
"-",
388-
basic_data.last_modified.ui_display(),
399+
basic_data.last_modified.ui_display(self.timezone),
389400
)
390401
else:
391402
tbody_file += _CONTENT_TBODY_FILE_TEMPLATE.format(
392403
dav_path.raw,
393404
basic_data.display_name,
394405
basic_data.content_type,
395406
f"{basic_data.content_length:,}",
396-
basic_data.last_modified.ui_display(),
407+
basic_data.last_modified.ui_display(self.timezone),
397408
)
398409

399410
content = _CONTENT_TEMPLATE.format(
400411
root_path.raw,
401412
root_path.raw,
402413
tbody_parent + tbody_dir + tbody_file,
403414
__version__,
404-
DAVTime().ui_display(),
415+
DAVTime().ui_display(self.timezone),
405416
)
406417
return content.encode("utf-8")

tests/test_helpers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
from asgi_webdav.config import get_config
66
from asgi_webdav.constants import AppEntryParameters
7+
from asgi_webdav.exception import DAVException
78
from asgi_webdav.helpers import (
89
detect_charset,
910
get_data_generator_from_content,
1011
guess_type,
1112
is_browser_user_agent,
13+
paser_timezone_key,
1214
)
1315

1416

@@ -126,3 +128,10 @@ async def test_func_get_data_generator_from_content():
126128
):
127129
data_new += data_block
128130
assert len(data_new) == 100
131+
132+
133+
def test_get_timezone_from_env():
134+
assert paser_timezone_key("Asia/Shanghai") == "Asia/Shanghai"
135+
136+
with pytest.raises(DAVException):
137+
paser_timezone_key("Invalid/TimeZone")

0 commit comments

Comments
 (0)