aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--youtube/subscriptions.py31
1 files changed, 30 insertions, 1 deletions
diff --git a/youtube/subscriptions.py b/youtube/subscriptions.py
index 7d3efab..50a7942 100644
--- a/youtube/subscriptions.py
+++ b/youtube/subscriptions.py
@@ -291,6 +291,11 @@ def youtube_timestamp_to_posix(dumb_timestamp):
def posix_to_dumbed_down(posix_time):
'''Inverse of youtube_timestamp_to_posix.'''
+ # Legacy/corrupt DB rows may store time_published as a non-numeric string
+ # (e.g. an unparsed "2 days ago"). Coerce defensively so the feed renders
+ # instead of crashing with: float - str.
+ posix_time = _coerce_posix_time(posix_time)
+
delta = int(time.time() - posix_time)
# Guard against future timestamps (clock drift) without relying on
# `assert` (which is stripped under `python -O`).
@@ -312,12 +317,31 @@ def posix_to_dumbed_down(posix_time):
def exact_timestamp(posix_time):
+ posix_time = _coerce_posix_time(posix_time)
result = time.strftime('%I:%M %p %m/%d/%y', time.localtime(posix_time))
if result[0] == '0': # remove 0 infront of hour (like 01:00 PM)
return result[1:]
return result
+def _coerce_posix_time(posix_time):
+ '''Best-effort conversion of a stored time_published value to a float.
+
+ Older versions could persist an unparsed timestamp string into the
+ integer time_published column. Recover gracefully: try numeric
+ conversion, then the dumbed-down parser, and fall back to "now".'''
+ if isinstance(posix_time, (int, float)):
+ return posix_time
+ try:
+ return float(posix_time)
+ except (TypeError, ValueError):
+ pass
+ try:
+ return youtube_timestamp_to_posix(posix_time)
+ except Exception:
+ return time.time()
+
+
try:
existing_thumbnails = set(os.path.splitext(name)[0] for name in os.listdir(thumbnails_directory))
except FileNotFoundError:
@@ -575,7 +599,12 @@ def _get_upstream_videos(channel_id):
try:
video_item['time_published'] = youtube_timestamp_to_posix(video_item['time_published']) - i # subtract a few seconds off the videos so they will be in the right order
except Exception:
- print(video_item)
+ print('Failed to parse time_published:', video_item)
+ # Don't leave the unparsed string in place: it would be stored
+ # in the integer time_published column and later crash
+ # posix_to_dumbed_down (float - str). Treat as unknown instead;
+ # the fill-in passes below will approximate it.
+ video_item['time_published'] = None
else:
video_item['is_time_published_exact'] = False
video_item['time_published'] = None