[dt] replace 'datetime' imports

This commit is contained in:
Mike Fährmann
2025-10-16 10:59:03 +02:00
parent 21350c5084
commit 69f7cfdd0c
10 changed files with 44 additions and 53 deletions

View File

@@ -9,10 +9,9 @@
"""Extractors for https://aryion.com/""" """Extractors for https://aryion.com/"""
from .common import Extractor, Message from .common import Extractor, Message
from .. import text, util, exception from .. import text, util, dt, exception
from ..cache import cache from ..cache import cache
from email.utils import parsedate_tz from email.utils import parsedate_tz
from datetime import datetime
BASE_PATTERN = r"(?:https?://)?(?:www\.)?aryion\.com/g4" BASE_PATTERN = r"(?:https?://)?(?:www\.)?aryion\.com/g4"
@@ -156,7 +155,7 @@ class AryionExtractor(Extractor):
"artist": artist, "artist": artist,
"path" : text.split_html(extr( "path" : text.split_html(extr(
"cookiecrumb'>", '</span'))[4:-1:2], "cookiecrumb'>", '</span'))[4:-1:2],
"date" : datetime(*parsedate_tz(lmod)[:6]), "date" : dt.datetime(*parsedate_tz(lmod)[:6]),
"size" : text.parse_int(clen), "size" : text.parse_int(clen),
"views" : text.parse_int(extr("Views</b>:", "<").replace(",", "")), "views" : text.parse_int(extr("Views</b>:", "<").replace(",", "")),
"width" : text.parse_int(extr("Resolution</b>:", "x")), "width" : text.parse_int(extr("Resolution</b>:", "x")),

View File

@@ -19,7 +19,6 @@ import getpass
import logging import logging
import requests import requests
import threading import threading
from datetime import datetime
from xml.etree import ElementTree from xml.etree import ElementTree
from requests.adapters import HTTPAdapter from requests.adapters import HTTPAdapter
from .message import Message from .message import Message
@@ -313,7 +312,7 @@ class Extractor():
seconds = float(seconds) seconds = float(seconds)
until = now + seconds until = now + seconds
elif until: elif until:
if isinstance(until, datetime): if isinstance(until, dt.datetime):
# convert to UTC timestamp # convert to UTC timestamp
until = dt.to_ts(until) until = dt.to_ts(until)
else: else:
@@ -327,7 +326,7 @@ class Extractor():
return return
if reason: if reason:
t = datetime.fromtimestamp(until).time() t = dt.datetime.fromtimestamp(until).time()
isotime = f"{t.hour:02}:{t.minute:02}:{t.second:02}" isotime = f"{t.hour:02}:{t.minute:02}:{t.second:02}"
self.log.info("Waiting until %s (%s)", isotime, reason) self.log.info("Waiting until %s (%s)", isotime, reason)
time.sleep(seconds) time.sleep(seconds)
@@ -652,7 +651,7 @@ class Extractor():
self.log.warning( self.log.warning(
"cookies: %s/%s expired at %s", "cookies: %s/%s expired at %s",
cookie.domain.lstrip("."), cookie.name, cookie.domain.lstrip("."), cookie.name,
datetime.fromtimestamp(cookie.expires)) dt.datetime.fromtimestamp(cookie.expires))
continue continue
elif diff <= 86400: elif diff <= 86400:
@@ -694,7 +693,7 @@ class Extractor():
ts = self.config(key, default) ts = self.config(key, default)
if isinstance(ts, str): if isinstance(ts, str):
try: try:
ts = int(datetime.strptime(ts, fmt).timestamp()) ts = int(dt.parse(ts, fmt).timestamp())
except ValueError as exc: except ValueError as exc:
self.log.warning("Unable to parse '%s': %s", key, exc) self.log.warning("Unable to parse '%s': %s", key, exc)
ts = default ts = default

View File

@@ -9,8 +9,7 @@
"""Extractors for https://danbooru.donmai.us/ and other Danbooru instances""" """Extractors for https://danbooru.donmai.us/ and other Danbooru instances"""
from .common import BaseExtractor, Message from .common import BaseExtractor, Message
from .. import text, util from .. import text, util, dt
import datetime
class DanbooruExtractor(BaseExtractor): class DanbooruExtractor(BaseExtractor):
@@ -69,8 +68,7 @@ class DanbooruExtractor(BaseExtractor):
continue continue
text.nameext_from_url(url, post) text.nameext_from_url(url, post)
post["date"] = text.parse_datetime( post["date"] = dt.parse_iso(post["created_at"])
post["created_at"], "%Y-%m-%dT%H:%M:%S.%f%z")
post["tags"] = ( post["tags"] = (
post["tag_string"].split(" ") post["tag_string"].split(" ")
@@ -357,11 +355,11 @@ class DanbooruPopularExtractor(DanbooruExtractor):
def metadata(self): def metadata(self):
self.params = params = text.parse_query(self.groups[-1]) self.params = params = text.parse_query(self.groups[-1])
scale = params.get("scale", "day") scale = params.get("scale", "day")
date = params.get("date") or datetime.date.today().isoformat() date = params.get("date") or dt.date.today().isoformat()
if scale == "week": if scale == "week":
date = datetime.date.fromisoformat(date) date = dt.date.fromisoformat(date)
date = (date - datetime.timedelta(days=date.weekday())).isoformat() date = (date - dt.timedelta(days=date.weekday())).isoformat()
elif scale == "month": elif scale == "month":
date = date[:-3] date = date[:-3]

View File

@@ -9,9 +9,8 @@
"""Extractors for Moebooru based sites""" """Extractors for Moebooru based sites"""
from .booru import BooruExtractor from .booru import BooruExtractor
from .. import text, util from .. import text, util, dt
import collections import collections
import datetime
class MoebooruExtractor(BooruExtractor): class MoebooruExtractor(BooruExtractor):
@@ -21,7 +20,7 @@ class MoebooruExtractor(BooruExtractor):
page_start = 1 page_start = 1
def _prepare(self, post): def _prepare(self, post):
post["date"] = text.parse_timestamp(post["created_at"]) post["date"] = dt.parse_ts(post["created_at"])
def _html(self, post): def _html(self, post):
url = f"{self.root}/post/show/{post['id']}" url = f"{self.root}/post/show/{post['id']}"
@@ -164,14 +163,14 @@ class MoebooruPopularExtractor(MoebooruExtractor):
date = (f"{params['year']:>04}-{params.get('month', '01'):>02}-" date = (f"{params['year']:>04}-{params.get('month', '01'):>02}-"
f"{params.get('day', '01'):>02}") f"{params.get('day', '01'):>02}")
else: else:
date = datetime.date.today().isoformat() date = dt.date.today().isoformat()
scale = self.scale scale = self.scale
if scale.startswith("by_"): if scale.startswith("by_"):
scale = scale[3:] scale = scale[3:]
if scale == "week": if scale == "week":
date = datetime.date.fromisoformat(date) date = dt.date.fromisoformat(date)
date = (date - datetime.timedelta(days=date.weekday())).isoformat() date = (date - dt.timedelta(days=date.weekday())).isoformat()
elif scale == "month": elif scale == "month":
date = date[:-3] date = date[:-3]

View File

@@ -9,8 +9,7 @@
"""Extractors for https://blog.naver.com/""" """Extractors for https://blog.naver.com/"""
from .common import GalleryExtractor, Extractor, Message from .common import GalleryExtractor, Extractor, Message
from .. import text, util from .. import text, util, dt
import datetime
import time import time
@@ -67,11 +66,11 @@ class NaverBlogPostExtractor(NaverBlogBase, GalleryExtractor):
return data return data
def _parse_datetime(self, date_string): def _parse_datetime(self, dt_string):
if "" in date_string: if "" in dt_string:
ts = time.gmtime() ts = time.gmtime()
return datetime.datetime(ts.tm_year, ts.tm_mon, ts.tm_mday) return dt.datetime(ts.tm_year, ts.tm_mon, ts.tm_mday)
return text.parse_datetime(date_string, "%Y. %m. %d. %H:%M") return dt.parse(dt_string, "%Y. %m. %d. %H:%M")
def images(self, page): def images(self, page):
files = [] files = []

View File

@@ -9,8 +9,7 @@
"""Extractors for https://www.plurk.com/""" """Extractors for https://www.plurk.com/"""
from .common import Extractor, Message from .common import Extractor, Message
from .. import text, util, exception from .. import text, util, dt, exception
import datetime
class PlurkExtractor(Extractor): class PlurkExtractor(Extractor):
@@ -88,12 +87,10 @@ class PlurkTimelineExtractor(PlurkExtractor):
while plurks: while plurks:
yield from plurks yield from plurks
offset = datetime.datetime.strptime( offset = dt.parse(plurks[-1]["posted"], "%a, %d %b %Y %H:%M:%S %Z")
plurks[-1]["posted"], "%a, %d %b %Y %H:%M:%S %Z")
data["offset"] = offset.strftime("%Y-%m-%dT%H:%M:%S.000Z") data["offset"] = offset.strftime("%Y-%m-%dT%H:%M:%S.000Z")
response = self.request( plurks = self.request_json(
url, method="POST", headers=headers, data=data) url, method="POST", headers=headers, data=data)["plurks"]
plurks = response.json()["plurks"]
class PlurkPostExtractor(PlurkExtractor): class PlurkPostExtractor(PlurkExtractor):

View File

@@ -9,8 +9,7 @@
"""Extractors for https://www.sex.com/""" """Extractors for https://www.sex.com/"""
from .common import Extractor, Message from .common import Extractor, Message
from .. import text from .. import text, dt
from datetime import datetime
BASE_PATTERN = r"(?:https?://)?(?:www\.)?sex\.com(?:/[a-z]{2})?" BASE_PATTERN = r"(?:https?://)?(?:www\.)?sex\.com(?:/[a-z]{2})?"
@@ -34,10 +33,10 @@ class SexcomExtractor(Extractor):
url = pin["url"] url = pin["url"]
parts = url.rsplit("/", 4) parts = url.rsplit("/", 4)
try: try:
pin["date_url"] = dt = datetime( pin["date_url"] = d = dt.datetime(
int(parts[1]), int(parts[2]), int(parts[3])) int(parts[1]), int(parts[2]), int(parts[3]))
if "date" not in pin: if "date" not in pin:
pin["date"] = dt pin["date"] = d
except Exception: except Exception:
pass pass
pin["tags"] = [t[1:] for t in pin["tags"]] pin["tags"] = [t[1:] for t in pin["tags"]]
@@ -136,7 +135,7 @@ class SexcomExtractor(Extractor):
text.nameext_from_url(data["url"], data) text.nameext_from_url(data["url"], data)
data["uploader"] = extr('itemprop="author">', '<') data["uploader"] = extr('itemprop="author">', '<')
data["date"] = text.parse_datetime(extr('datetime="', '"')) data["date"] = dt.parse_iso(extr('datetime="', '"'))
data["tags"] = text.split_html(extr('class="tags"> Tags', '</div>')) data["tags"] = text.split_html(extr('class="tags"> Tags', '</div>'))
data["comments"] = text.parse_int(extr('Comments (', ')')) data["comments"] = text.parse_int(extr('Comments (', ')'))
@@ -314,7 +313,7 @@ class SexcomSearchExtractor(SexcomExtractor):
parts = path.rsplit("/", 4) parts = path.rsplit("/", 4)
try: try:
pin["date_url"] = pin["date"] = datetime( pin["date_url"] = pin["date"] = dt.datetime(
int(parts[1]), int(parts[2]), int(parts[3])) int(parts[1]), int(parts[2]), int(parts[3]))
except Exception: except Exception:
pass pass

View File

@@ -9,8 +9,7 @@
"""Extractors for https://www.tumblr.com/""" """Extractors for https://www.tumblr.com/"""
from .common import Extractor, Message from .common import Extractor, Message
from .. import text, util, oauth, exception from .. import text, util, dt, oauth, exception
from datetime import datetime, date, timedelta
BASE_PATTERN = ( BASE_PATTERN = (
@@ -313,7 +312,7 @@ class TumblrDayExtractor(TumblrExtractor):
def posts(self): def posts(self):
year, month, day = self.groups[3].split("/") year, month, day = self.groups[3].split("/")
ordinal = date(int(year), int(month), int(day)).toordinal() ordinal = dt.date(int(year), int(month), int(day)).toordinal()
# 719163 == date(1970, 1, 1).toordinal() # 719163 == date(1970, 1, 1).toordinal()
self.date_min = (ordinal - 719163) * 86400 self.date_min = (ordinal - 719163) * 86400
@@ -514,7 +513,7 @@ class TumblrAPI(oauth.OAuth1API):
self.extractor.wait(seconds=reset) self.extractor.wait(seconds=reset)
continue continue
t = (datetime.now() + timedelta(0, float(reset))).time() t = (dt.now() + dt.timedelta(0, float(reset))).time()
raise exception.AbortExtraction( raise exception.AbortExtraction(
f"Aborting - Rate limit will reset at " f"Aborting - Rate limit will reset at "
f"{t.hour:02}:{t.minute:02}:{t.second:02}") f"{t.hour:02}:{t.minute:02}:{t.second:02}")

View File

@@ -13,7 +13,6 @@ import sys
import time import time
import string import string
import _string import _string
import datetime
import operator import operator
from . import text, util, dt from . import text, util, dt
@@ -484,13 +483,13 @@ def _parse_offset(format_spec, default):
if not offset or offset == "local": if not offset or offset == "local":
def off(dt_utc): def off(dt_utc):
local = time.localtime(dt.to_ts(dt_utc)) local = time.localtime(dt.to_ts(dt_utc))
return fmt(dt_utc + datetime.timedelta(0, local.tm_gmtoff)) return fmt(dt_utc + dt.timedelta(0, local.tm_gmtoff))
else: else:
hours, _, minutes = offset.partition(":") hours, _, minutes = offset.partition(":")
offset = 3600 * int(hours) offset = 3600 * int(hours)
if minutes: if minutes:
offset += 60 * (int(minutes) if offset > 0 else -int(minutes)) offset += 60 * (int(minutes) if offset > 0 else -int(minutes))
offset = datetime.timedelta(0, offset) offset = dt.timedelta(0, offset)
def off(obj): def off(obj):
return fmt(obj + offset) return fmt(obj + offset)
@@ -557,7 +556,7 @@ _FORMATTERS = {
_GLOBALS = { _GLOBALS = {
"_env": lambda: os.environ, "_env": lambda: os.environ,
"_lit": lambda: _literal, "_lit": lambda: _literal,
"_now": datetime.datetime.now, "_now": dt.datetime.now,
"_nul": lambda: util.NONE, "_nul": lambda: util.NONE,
} }
_CONVERSIONS = { _CONVERSIONS = {

View File

@@ -122,11 +122,10 @@ class TestDatetime(unittest.TestCase):
self.assertEqual(f(value, "%Y"), dt.NONE) self.assertEqual(f(value, "%Y"), dt.NONE)
def test_parse_iso(self, f=dt.parse_iso): def test_parse_iso(self, f=dt.parse_iso):
null = dt.from_ts(0) self.assertEqual(
f("1970-01-01T00:00:00+00:00"),
self.assertEqual(f("1970-01-01T00:00:00+00:00"), null) dt.from_ts(0),
self.assertEqual(f("1970-01-01T00:00:00+0000") , null) )
self.assertEqual( self.assertEqual(
f("2019-05-07T21:25:02+09:00"), f("2019-05-07T21:25:02+09:00"),
datetime.datetime(2019, 5, 7, 12, 25, 2), datetime.datetime(2019, 5, 7, 12, 25, 2),
@@ -152,6 +151,10 @@ class TestDatetime(unittest.TestCase):
self.assertEqual(f(value), dt.NONE) self.assertEqual(f(value), dt.NONE)
def test_parse_compat(self, f=dt.parse_compat): def test_parse_compat(self, f=dt.parse_compat):
self.assertEqual(
f("1970-01-01T00:00:00+0000", "%Y-%m-%dT%H:%M:%S%z"),
dt.EPOCH,
)
self.assertEqual( self.assertEqual(
f("2019-05-07T21:25:02.753+0900", "%Y-%m-%dT%H:%M:%S.%f%z"), f("2019-05-07T21:25:02.753+0900", "%Y-%m-%dT%H:%M:%S.%f%z"),
datetime.datetime(2019, 5, 7, 12, 25, 2), datetime.datetime(2019, 5, 7, 12, 25, 2),