[common] allow general ISO 8601 values for 'date-min' & '-max'
and parse them as UTC times instead of local time
This commit is contained in:
@@ -1503,12 +1503,19 @@ extractor.*.date-format
|
||||
Type
|
||||
``string``
|
||||
Default
|
||||
``"%Y-%m-%dT%H:%M:%S"``
|
||||
``null``
|
||||
Description
|
||||
Format string used to parse ``string`` values of
|
||||
`date-min` and `date-max`.
|
||||
|
||||
See |strptime|_ for a list of formatting directives.
|
||||
Special Values
|
||||
``null``
|
||||
| Parse `date-min` and `date-max` according to
|
||||
`ISO 8601 <https://en.wikipedia.org/wiki/ISO_8601>`__
|
||||
| See
|
||||
`datetime.fromisoformat() <https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat>`__
|
||||
for details and examples.
|
||||
Note
|
||||
Despite its name, this option does **not** control how
|
||||
``{date}`` metadata fields are formatted.
|
||||
|
||||
@@ -681,7 +681,7 @@
|
||||
"embeds" : true,
|
||||
"date-min" : 0,
|
||||
"date-max" : 253402210800,
|
||||
"date-format" : "%Y-%m-%dT%H:%M:%S",
|
||||
"date-format" : null,
|
||||
"id-min" : null,
|
||||
"id-max" : null,
|
||||
"limit" : null,
|
||||
|
||||
@@ -697,13 +697,16 @@ class Extractor():
|
||||
def get(key, default):
|
||||
ts = self.config(key, default)
|
||||
if isinstance(ts, str):
|
||||
try:
|
||||
ts = int(dt.parse(ts, fmt).timestamp())
|
||||
except ValueError as exc:
|
||||
self.log.warning("Unable to parse '%s': %s", key, exc)
|
||||
dt_obj = dt.parse_iso(ts) if fmt is None else dt.parse(ts, fmt)
|
||||
if dt_obj is dt.NONE:
|
||||
self.log.warning(
|
||||
"Unable to parse '%s': Invalid %s string '%s'",
|
||||
key, "isoformat" if fmt is None else "date", ts)
|
||||
ts = default
|
||||
else:
|
||||
ts = int(dt.to_ts(dt_obj))
|
||||
return ts
|
||||
fmt = self.config("date-format", "%Y-%m-%dT%H:%M:%S")
|
||||
fmt = self.config("date-format")
|
||||
return get("date-min", dmin), get("date-max", dmax)
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -16,7 +16,7 @@ import time
|
||||
import string
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from gallery_dl import extractor, util, dt # noqa E402
|
||||
from gallery_dl import extractor, util, dt, config # noqa E402
|
||||
from gallery_dl.extractor import mastodon # noqa E402
|
||||
from gallery_dl.extractor.common import Extractor, Message # noqa E402
|
||||
from gallery_dl.extractor.directlink import DirectlinkExtractor # noqa E402
|
||||
@@ -261,6 +261,79 @@ class TestExtractorWait(unittest.TestCase):
|
||||
return int(parts[0]) * 3600 + int(parts[1]) * 60 + int(parts[2])
|
||||
|
||||
|
||||
class TextExtractorCommonDateminmax(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
config.clear()
|
||||
|
||||
tearDown = setUp
|
||||
|
||||
def test_date_min_max_default(self):
|
||||
extr = extractor.find("generic:https://example.org/")
|
||||
|
||||
dmin, dmax = extr._get_date_min_max()
|
||||
self.assertEqual(dmin, None)
|
||||
self.assertEqual(dmax, None)
|
||||
|
||||
dmin, dmax = extr._get_date_min_max(..., -1)
|
||||
self.assertEqual(dmin, ...)
|
||||
self.assertEqual(dmax, -1)
|
||||
|
||||
def test_date_min_max_timestamp(self):
|
||||
extr = extractor.find("generic:https://example.org/")
|
||||
config.set((), "date-min", 1262304000)
|
||||
config.set((), "date-max", 1262304000.123)
|
||||
|
||||
dmin, dmax = extr._get_date_min_max()
|
||||
self.assertEqual(dmin, 1262304000)
|
||||
self.assertEqual(dmax, 1262304000.123)
|
||||
|
||||
def test_date_min_max_iso(self):
|
||||
extr = extractor.find("generic:https://example.org/")
|
||||
config.set((), "date-min", "2010-01-01")
|
||||
config.set((), "date-max", "2010-01-01T00:01:03")
|
||||
|
||||
dmin, dmax = extr._get_date_min_max()
|
||||
self.assertEqual(dmin, 1262304000)
|
||||
self.assertEqual(dmax, 1262304063)
|
||||
|
||||
def test_date_min_max_iso_invalid(self):
|
||||
extr = extractor.find("generic:https://example.org/")
|
||||
config.set((), "date-min", "2010-01-01")
|
||||
config.set((), "date-max", "2010-01")
|
||||
|
||||
with self.assertLogs() as log_info:
|
||||
dmin, dmax = extr._get_date_min_max()
|
||||
self.assertEqual(dmin, 1262304000)
|
||||
self.assertEqual(dmax, None)
|
||||
|
||||
self.assertEqual(len(log_info.output), 1)
|
||||
self.assertEqual(
|
||||
log_info.output[0],
|
||||
"WARNING:generic:Unable to parse 'date-max': "
|
||||
"Invalid isoformat string '2010-01'")
|
||||
|
||||
def test_date_min_max_fmt(self):
|
||||
extr = extractor.find("generic:https://example.org/")
|
||||
config.set((), "date-format", "%B %d %Y")
|
||||
config.set((), "date-min", "January 01 2010")
|
||||
config.set((), "date-max", "August 18 2022")
|
||||
|
||||
dmin, dmax = extr._get_date_min_max()
|
||||
self.assertEqual(dmin, 1262304000)
|
||||
self.assertEqual(dmax, 1660780800)
|
||||
|
||||
def test_date_min_max_mix(self):
|
||||
extr = extractor.find("generic:https://example.org/")
|
||||
config.set((), "date-format", "%B %d %Y")
|
||||
config.set((), "date-min", "January 01 2010")
|
||||
config.set((), "date-max", 1262304061)
|
||||
|
||||
dmin, dmax = extr._get_date_min_max()
|
||||
self.assertEqual(dmin, 1262304000)
|
||||
self.assertEqual(dmax, 1262304061)
|
||||
|
||||
|
||||
class TextExtractorOAuth(unittest.TestCase):
|
||||
|
||||
def test_oauth1(self):
|
||||
|
||||
Reference in New Issue
Block a user