mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-21 19:23:05 +00:00
Improve parsing to datetime and add error handling (#1203)
* Improve parsing to datetime and add error handling * Fix utils.millisecondToHumanstr for days and negatives * Update tests for millisecondToHumanstr
This commit is contained in:
parent
a7d29a3638
commit
35008908fc
2 changed files with 29 additions and 17 deletions
|
@ -11,13 +11,13 @@ import unicodedata
|
|||
import warnings
|
||||
import zipfile
|
||||
from collections import deque
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from getpass import getpass
|
||||
from threading import Event, Thread
|
||||
from urllib.parse import quote
|
||||
from requests.status_codes import _codes as codes
|
||||
|
||||
import requests
|
||||
from requests.status_codes import _codes as codes
|
||||
|
||||
from plexapi.exceptions import BadRequest, NotFound, Unauthorized
|
||||
|
||||
|
@ -313,33 +313,39 @@ def toDatetime(value, format=None):
|
|||
value (str): value to return as a datetime
|
||||
format (str): Format to pass strftime (optional; if value is a str).
|
||||
"""
|
||||
if value and value is not None:
|
||||
if value is not None:
|
||||
if format:
|
||||
try:
|
||||
value = datetime.strptime(value, format)
|
||||
return datetime.strptime(value, format)
|
||||
except ValueError:
|
||||
log.info('Failed to parse %s to datetime, defaulting to None', value)
|
||||
log.info('Failed to parse "%s" to datetime as format "%s", defaulting to None', value, format)
|
||||
return None
|
||||
else:
|
||||
# https://bugs.python.org/issue30684
|
||||
# And platform support for before epoch seems to be flaky.
|
||||
# Also limit to max 32-bit integer
|
||||
value = min(max(int(value), 86400), 2**31 - 1)
|
||||
value = datetime.fromtimestamp(int(value))
|
||||
try:
|
||||
return datetime.utcfromtimestamp(0) + timedelta(seconds=int(value))
|
||||
except ValueError:
|
||||
log.info('Failed to parse "%s" to datetime as timestamp, defaulting to None', value)
|
||||
return None
|
||||
except OverflowError:
|
||||
log.info('Failed to parse "%s" to datetime as timestamp (out-of-bounds), defaulting to None', value)
|
||||
return None
|
||||
return value
|
||||
|
||||
|
||||
def millisecondToHumanstr(milliseconds):
|
||||
""" Returns human readable time duration from milliseconds.
|
||||
HH:MM:SS:MMMM
|
||||
""" Returns human readable time duration [D day[s], ]HH:MM:SS.UUU from milliseconds.
|
||||
|
||||
Parameters:
|
||||
milliseconds (str,int): time duration in milliseconds.
|
||||
milliseconds (str, int): time duration in milliseconds.
|
||||
"""
|
||||
milliseconds = int(milliseconds)
|
||||
r = datetime.utcfromtimestamp(milliseconds / 1000)
|
||||
f = r.strftime("%H:%M:%S.%f")
|
||||
return f[:-2]
|
||||
if milliseconds < 0:
|
||||
return '-' + millisecondToHumanstr(abs(milliseconds))
|
||||
secs, ms = divmod(milliseconds, 1000)
|
||||
mins, secs = divmod(secs, 60)
|
||||
hours, mins = divmod(mins, 60)
|
||||
days, hours = divmod(hours, 24)
|
||||
return ('' if days == 0 else f'{days} day{"s" if days > 1 else ""}, ') + f'{hours:02d}:{mins:02d}:{secs:02d}.{ms:03d}'
|
||||
|
||||
|
||||
def toList(value, itemcast=None, delim=','):
|
||||
|
|
|
@ -90,7 +90,13 @@ def test_utils_download(plex, episode):
|
|||
|
||||
def test_millisecondToHumanstr():
|
||||
res = utils.millisecondToHumanstr(1000)
|
||||
assert res == "00:00:01.0000"
|
||||
assert res == "00:00:01.000"
|
||||
res = utils.millisecondToHumanstr(-1000)
|
||||
assert res == "-00:00:01.000"
|
||||
res = utils.millisecondToHumanstr(123456789)
|
||||
assert res == "1 day, 10:17:36.789"
|
||||
res = utils.millisecondToHumanstr(-123456789)
|
||||
assert res == "-1 day, 10:17:36.789"
|
||||
|
||||
|
||||
def test_toJson(movie):
|
||||
|
|
Loading…
Reference in a new issue