From fb97ed4ee4ff2ce7106c96832cff00c1efffdf3c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 4 Jun 2016 11:15:59 +0530 Subject: [PATCH] Dont use dateutil to parse dates known to be in the ISO 8601 format dateutils parse() method is unstable, with behavior changes in minor releases that break parsing of ISO 8601 dates --- src/calibre/ebooks/metadata/book/json_codec.py | 4 ++-- src/calibre/utils/config.py | 4 ++-- src/calibre/web/feeds/recipes/collection.py | 14 +++++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/calibre/ebooks/metadata/book/json_codec.py b/src/calibre/ebooks/metadata/book/json_codec.py index 0af304f6a1..4b292925f3 100644 --- a/src/calibre/ebooks/metadata/book/json_codec.py +++ b/src/calibre/ebooks/metadata/book/json_codec.py @@ -16,10 +16,10 @@ from calibre import isbytestring # Translate datetimes to and from strings. The string form is the datetime in # UTC. The returned date is also UTC def string_to_datetime(src): - from calibre.utils.date import parse_date + from calibre.utils.iso8601 import parse_iso8601 if src != "None": try: - return parse_date(src) + return parse_iso8601(src) except Exception: pass return None diff --git a/src/calibre/utils/config.py b/src/calibre/utils/config.py index 5e9d715bc1..7e628dc4a2 100644 --- a/src/calibre/utils/config.py +++ b/src/calibre/utils/config.py @@ -377,8 +377,8 @@ def from_json(obj): if obj['__class__'] == 'bytearray': return bytearray(base64.standard_b64decode(obj['__value__'])) if obj['__class__'] == 'datetime.datetime': - from calibre.utils.date import parse_date - return parse_date(obj['__value__'], assume_utc=True) + from calibre.utils.iso8601 import parse_iso8601 + return parse_iso8601(obj['__value__'], assume_utc=True) return obj class JSONConfig(XMLConfig): diff --git a/src/calibre/web/feeds/recipes/collection.py b/src/calibre/web/feeds/recipes/collection.py index 003196bac9..856e7eb3a7 100644 --- a/src/calibre/web/feeds/recipes/collection.py +++ b/src/calibre/web/feeds/recipes/collection.py @@ -14,8 +14,8 @@ from lxml import etree from lxml.builder import ElementMaker from calibre import force_unicode -from calibre.utils.date import parse_date, now as nowf, utcnow, local_tz, \ - isoformat, fromordinal +from calibre.utils.iso8601 import parse_iso8601 +from calibre.utils.date import now as nowf, utcnow, local_tz, isoformat, fromordinal, UNDEFINED_DATE from calibre.utils.recycle_bin import delete_file NS = 'http://calibre-ebook.com/recipe_collection' @@ -292,8 +292,8 @@ class SchedulerConfig(object): ld = x.get('last_downloaded', None) if ld and last_downloaded is None: try: - last_downloaded = parse_date(ld) - except: + last_downloaded = parse_iso8601(ld) + except Exception: pass self.root.remove(x) break @@ -397,7 +397,11 @@ class SchedulerConfig(object): days = list(map(int, [x.strip() for x in parts[0].split(',')])) sch = [days, int(parts[1]), int(parts[2])] - return typ, sch, parse_date(recipe.get('last_downloaded')) + try: + ld = parse_iso8601(recipe.get('last_downloaded')) + except Exception: + ld = UNDEFINED_DATE + return typ, sch, ld def recipe_needs_to_be_downloaded(self, recipe): try: