diff options
Diffstat (limited to 'youtube_dl/utils.py')
| -rw-r--r-- | youtube_dl/utils.py | 63 | 
1 files changed, 48 insertions, 15 deletions
| diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 3574fc615..5f1f664c8 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -1,6 +1,7 @@  #!/usr/bin/env python  # -*- coding: utf-8 -*- +import calendar  import contextlib  import ctypes  import datetime @@ -501,13 +502,13 @@ def orderedSet(iterable):              res.append(el)      return res +  def unescapeHTML(s): -    """ -    @param s a string -    """ -    assert type(s) == type(u'') +    if s is None: +        return None +    assert type(s) == compat_str -    result = re.sub(u'(?u)&(.+?);', htmlentity_transform, s) +    result = re.sub(r'(?u)&(.+?);', htmlentity_transform, s)      return result @@ -538,7 +539,6 @@ def encodeFilename(s, for_subprocess=False):          encoding = 'utf-8'      return s.encode(encoding, 'ignore') -  def decodeOption(optval):      if optval is None:          return optval @@ -761,6 +761,31 @@ class YoutubeDLHandler(compat_urllib_request.HTTPHandler):      https_response = http_response +def parse_iso8601(date_str): +    """ Return a UNIX timestamp from the given date """ + +    if date_str is None: +        return None + +    m = re.search( +        r'Z$| ?(?P<sign>\+|-)(?P<hours>[0-9]{2}):?(?P<minutes>[0-9]{2})$', +        date_str) +    if not m: +        timezone = datetime.timedelta() +    else: +        date_str = date_str[:-len(m.group(0))] +        if not m.group('sign'): +            timezone = datetime.timedelta() +        else: +            sign = 1 if m.group('sign') == '+' else -1 +            timezone = datetime.timedelta( +                hours=sign * int(m.group('hours')), +                minutes=sign * int(m.group('minutes'))) + +    dt = datetime.datetime.strptime(date_str, '%Y-%m-%dT%H:%M:%S') - timezone +    return calendar.timegm(dt.timetuple()) + +  def unified_strdate(date_str):      """Return a string with the date in the format YYYYMMDD""" @@ -1126,11 +1151,11 @@ def setproctitle(title):          libc = ctypes.cdll.LoadLibrary("libc.so.6")      except OSError:          return -    title = title -    buf = ctypes.create_string_buffer(len(title) + 1) -    buf.value = title.encode('utf-8') +    title_bytes = title.encode('utf-8') +    buf = ctypes.create_string_buffer(len(title_bytes)) +    buf.value = title_bytes      try: -        libc.prctl(15, ctypes.byref(buf), 0, 0, 0) +        libc.prctl(15, buf, 0, 0, 0)      except AttributeError:          return  # Strange libc, just skip this @@ -1151,8 +1176,12 @@ class HEADRequest(compat_urllib_request.Request):          return "HEAD" -def int_or_none(v, scale=1): -    return v if v is None else (int(v) // scale) +def int_or_none(v, scale=1, default=None): +    return default if v is None else (int(v) // scale) + + +def float_or_none(v, scale=1, default=None): +    return default if v is None else (float(v) / scale)  def parse_duration(s): @@ -1160,7 +1189,7 @@ def parse_duration(s):          return None      m = re.match( -        r'(?:(?:(?P<hours>[0-9]+)[:h])?(?P<mins>[0-9]+)[:m])?(?P<secs>[0-9]+)s?$', s) +        r'(?:(?:(?P<hours>[0-9]+)[:h])?(?P<mins>[0-9]+)[:m])?(?P<secs>[0-9]+)s?(?::[0-9]+)?$', s)      if not m:          return None      res = int(m.group('secs')) @@ -1235,8 +1264,8 @@ class PagedList(object):  def uppercase_escape(s):      return re.sub( -        r'\\U([0-9a-fA-F]{8})', -        lambda m: compat_chr(int(m.group(1), base=16)), s) +        r'\\U[0-9a-fA-F]{8}', +        lambda m: m.group(0).decode('unicode-escape'), s)  try:      struct.pack(u'!I', 0) @@ -1302,3 +1331,7 @@ US_RATINGS = {      'R': 16,      'NC': 18,  } + + +def strip_jsonp(code): +    return re.sub(r'(?s)^[a-zA-Z_]+\s*\(\s*(.*)\);\s*?\s*$', r'\1', code) | 
