add alternatives for deprecated utc datetime functions

This commit is contained in:
Mike Fährmann
2024-09-19 20:09:03 +02:00
parent a051e1c955
commit 2c7a0c3ca8
7 changed files with 68 additions and 19 deletions

View File

@@ -9,9 +9,9 @@
"""Extractors for https://8chan.moe/""" """Extractors for https://8chan.moe/"""
from .common import Extractor, Message from .common import Extractor, Message
from .. import text from .. import text, util
from ..cache import memcache from ..cache import memcache
from datetime import datetime, timedelta from datetime import timedelta
import itertools import itertools
BASE_PATTERN = r"(?:https?://)?8chan\.(moe|se|cc)" BASE_PATTERN = r"(?:https?://)?8chan\.(moe|se|cc)"
@@ -34,14 +34,14 @@ class _8chanExtractor(Extractor):
def cookies_prepare(self): def cookies_prepare(self):
# fetch captcha cookies # fetch captcha cookies
# (necessary to download without getting interrupted) # (necessary to download without getting interrupted)
now = datetime.utcnow() now = util.datetime_utcnow()
url = self.root + "/captcha.js" url = self.root + "/captcha.js"
params = {"d": now.strftime("%a %b %d %Y %H:%M:%S GMT+0000 (UTC)")} params = {"d": now.strftime("%a %b %d %Y %H:%M:%S GMT+0000 (UTC)")}
self.request(url, params=params).content self.request(url, params=params).content
# adjust cookies # adjust cookies
# - remove 'expires' timestamp # - remove 'expires' timestamp
# - move 'captchaexpiration' value forward by 1 month) # - move 'captchaexpiration' value forward by 1 month
domain = self.root.rpartition("/")[2] domain = self.root.rpartition("/")[2]
for cookie in self.cookies: for cookie in self.cookies:
if cookie.domain.endswith(domain): if cookie.domain.endswith(domain):

View File

@@ -448,7 +448,8 @@ class PixivRankingExtractor(PixivExtractor):
self.log.warning("invalid date '%s'", date) self.log.warning("invalid date '%s'", date)
date = None date = None
if not date: if not date:
date = (datetime.utcnow() - timedelta(days=1)).strftime("%Y-%m-%d") now = util.datetime_utcnow()
date = (now - timedelta(days=1)).strftime("%Y-%m-%d")
self.date = date self.date = date
return {"ranking": { return {"ranking": {
@@ -887,7 +888,7 @@ class PixivAppAPI():
"get_secure_url": "1", "get_secure_url": "1",
} }
time = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S+00:00") time = util.datetime_utcnow().strftime("%Y-%m-%dT%H:%M:%S+00:00")
headers = { headers = {
"X-Client-Time": time, "X-Client-Time": time,
"X-Client-Hash": hashlib.md5( "X-Client-Hash": hashlib.md5(

View File

@@ -9,7 +9,9 @@
"""Collection of functions that work on strings/text""" """Collection of functions that work on strings/text"""
import re import re
import sys
import html import html
import time
import datetime import datetime
import urllib.parse import urllib.parse
@@ -247,12 +249,23 @@ def parse_query(qs):
return result return result
def parse_timestamp(ts, default=None): if sys.hexversion < 0x30c0000:
"""Create a datetime object from a unix timestamp""" # Python <= 3.11
try: def parse_timestamp(ts, default=None):
return datetime.datetime.utcfromtimestamp(int(ts)) """Create a datetime object from a Unix timestamp"""
except Exception: try:
return default return datetime.datetime.utcfromtimestamp(int(ts))
except Exception:
return default
else:
# Python >= 3.12
def parse_timestamp(ts, default=None):
"""Create a datetime object from a Unix timestamp"""
try:
Y, m, d, H, M, S, _, _, _ = time.gmtime(int(ts))
return datetime.datetime(Y, m, d, H, M, S)
except Exception:
return default
def parse_datetime(date_string, format="%Y-%m-%dT%H:%M:%S%z", utcoffset=0): def parse_datetime(date_string, format="%Y-%m-%dT%H:%M:%S%z", utcoffset=0):

View File

@@ -218,18 +218,34 @@ def to_string(value):
def datetime_to_timestamp(dt): def datetime_to_timestamp(dt):
"""Convert naive UTC datetime to timestamp""" """Convert naive UTC datetime to Unix timestamp"""
return (dt - EPOCH) / SECOND return (dt - EPOCH) / SECOND
def datetime_to_timestamp_string(dt): def datetime_to_timestamp_string(dt):
"""Convert naive UTC datetime to timestamp string""" """Convert naive UTC datetime to Unix timestamp string"""
try: try:
return str((dt - EPOCH) // SECOND) return str((dt - EPOCH) // SECOND)
except Exception: except Exception:
return "" return ""
if sys.hexversion < 0x30c0000:
# Python <= 3.11
datetime_utcfromtimestamp = datetime.datetime.utcfromtimestamp
datetime_utcnow = datetime.datetime.utcnow
datetime_from_timestamp = datetime_utcfromtimestamp
else:
# Python >= 3.12
def datetime_from_timestamp(ts=None):
"""Convert Unix timestamp to naive UTC datetime"""
Y, m, d, H, M, S, _, _, _ = time.gmtime(ts)
return datetime.datetime(Y, m, d, H, M, S)
datetime_utcfromtimestamp = datetime_from_timestamp
datetime_utcnow = datetime_from_timestamp
def json_default(obj): def json_default(obj):
if isinstance(obj, CustomNone): if isinstance(obj, CustomNone):
return None return None

View File

@@ -243,9 +243,12 @@ class TestExtractorWait(unittest.TestCase):
def test_wait_until_datetime(self): def test_wait_until_datetime(self):
extr = extractor.find("generic:https://example.org/") extr = extractor.find("generic:https://example.org/")
until = datetime.utcnow() + timedelta(seconds=5) until = util.datetime_utcnow() + timedelta(seconds=5)
until_local = datetime.now() + timedelta(seconds=5) until_local = datetime.now() + timedelta(seconds=5)
if not until.microsecond:
until = until.replace(microsecond=until_local.microsecond)
with patch("time.sleep") as sleep, patch.object(extr, "log") as log: with patch("time.sleep") as sleep, patch.object(extr, "log") as log:
extr.wait(until=until) extr.wait(until=until)

View File

@@ -14,7 +14,7 @@ import unittest
import datetime import datetime
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from gallery_dl import text # noqa E402 from gallery_dl import text, util # noqa E402
INVALID = ((), [], {}, None, 1, 2.3) INVALID = ((), [], {}, None, 1, 2.3)
@@ -414,8 +414,8 @@ class TestText(unittest.TestCase):
self.assertEqual(f(value), {}) self.assertEqual(f(value), {})
def test_parse_timestamp(self, f=text.parse_timestamp): def test_parse_timestamp(self, f=text.parse_timestamp):
null = datetime.datetime.utcfromtimestamp(0) null = util.datetime_utcfromtimestamp(0)
value = datetime.datetime.utcfromtimestamp(1555816235) value = util.datetime_utcfromtimestamp(1555816235)
self.assertEqual(f(0) , null) self.assertEqual(f(0) , null)
self.assertEqual(f("0") , null) self.assertEqual(f("0") , null)
@@ -427,7 +427,7 @@ class TestText(unittest.TestCase):
self.assertEqual(f(value, "foo"), "foo") self.assertEqual(f(value, "foo"), "foo")
def test_parse_datetime(self, f=text.parse_datetime): def test_parse_datetime(self, f=text.parse_datetime):
null = datetime.datetime.utcfromtimestamp(0) null = util.datetime_utcfromtimestamp(0)
self.assertEqual(f("1970-01-01T00:00:00+00:00"), null) self.assertEqual(f("1970-01-01T00:00:00+00:00"), null)
self.assertEqual(f("1970-01-01T00:00:00+0000") , null) self.assertEqual(f("1970-01-01T00:00:00+0000") , null)

View File

@@ -738,6 +738,22 @@ def hash(value):
self.assertEqual(f(datetime.datetime(2010, 1, 1)), "1262304000") self.assertEqual(f(datetime.datetime(2010, 1, 1)), "1262304000")
self.assertEqual(f(None), "") self.assertEqual(f(None), "")
def test_datetime_from_timestamp(
self, f=util.datetime_from_timestamp):
self.assertEqual(f(0.0), util.EPOCH)
self.assertEqual(f(1262304000.0), datetime.datetime(2010, 1, 1))
self.assertEqual(f(1262304000.128000).replace(microsecond=0),
datetime.datetime(2010, 1, 1, 0, 0, 0))
def test_datetime_utcfromtimestamp(
self, f=util.datetime_utcfromtimestamp):
self.assertEqual(f(0.0), util.EPOCH)
self.assertEqual(f(1262304000.0), datetime.datetime(2010, 1, 1))
def test_datetime_utcnow(
self, f=util.datetime_utcnow):
self.assertIsInstance(f(), datetime.datetime)
def test_universal_none(self): def test_universal_none(self):
obj = util.NONE obj = util.NONE