[Python-modules-commits] [python-m3u8] 01/04: Import python-m3u8_0.3.1.orig.tar.gz

Ondřej Nový onovy at moszumanska.debian.org
Tue Jan 24 09:41:20 UTC 2017


This is an automated email from the git hooks/post-receive script.

onovy pushed a commit to branch master
in repository python-m3u8.

commit 81937f6cea962bdb4c5a9aa0c409fd4dc5dda6e7
Author: Ondřej Nový <onovy at debian.org>
Date:   Tue Jan 24 10:35:25 2017 +0100

    Import python-m3u8_0.3.1.orig.tar.gz
---
 m3u8/__init__.py     | 44 +++++++++++++++++++++++---------------------
 m3u8/model.py        |  2 +-
 m3u8/parser.py       |  3 +--
 setup.py             |  2 +-
 tests/playlists.py   | 44 ++++++++++++++++++++++++++++++++++++++++++++
 tests/test_model.py  | 10 +++++++++-
 tests/test_parser.py | 22 ++++++++++++++++++++++
 7 files changed, 101 insertions(+), 26 deletions(-)

diff --git a/m3u8/__init__.py b/m3u8/__init__.py
index 7393089..acd14c0 100644
--- a/m3u8/__init__.py
+++ b/m3u8/__init__.py
@@ -4,24 +4,22 @@
 # license that can be found in the LICENSE file.
 
 import sys
-PYTHON_MAJOR_VERSION = sys.version_info
-
 import os
 import posixpath
 
 try:
-    import urlparse as url_parser
-    import urllib2
-    urlopen = urllib2.urlopen
-except ImportError:
-    import urllib.parse as url_parser
-    from urllib.request import urlopen as url_opener
-    urlopen = url_opener
-
+    from urllib.request import urlopen, Request
+    from urllib.error import HTTPError
+    from urllib.parse import urlparse, urljoin
+except ImportError:  # Python 2.x
+    from urllib2 import urlopen, Request, HTTPError
+    from urlparse import urlparse, urljoin
 
 from m3u8.model import M3U8, Playlist, IFramePlaylist, Media, Segment
 from m3u8.parser import parse, is_url, ParseError
 
+PYTHON_MAJOR_VERSION = sys.version_info
+
 __all__ = ('M3U8', 'Playlist', 'IFramePlaylist', 'Media',
            'Segment', 'loads', 'load', 'parse', 'ParseError')
 
@@ -34,23 +32,25 @@ def loads(content):
     return M3U8(content)
 
 
-def load(uri, timeout=None):
+def load(uri, timeout=None, headers={}):
     '''
     Retrieves the content from a given URI and returns a M3U8 object.
     Raises ValueError if invalid content or IOError if request fails.
-    Raises socket.timeout(python 2.7+) or urllib2.URLError(python 2.6) if timeout happens when loading from uri
+    Raises socket.timeout(python 2.7+) or urllib2.URLError(python 2.6) if
+    timeout happens when loading from uri
     '''
     if is_url(uri):
-        return _load_from_uri(uri, timeout)
+        return _load_from_uri(uri, timeout, headers)
     else:
         return _load_from_file(uri)
 
 # Support for python3 inspired by https://github.com/szemtiv/m3u8/
 
 
-def _load_from_uri(uri, timeout=None):
-    resource = urlopen(uri, timeout=timeout)
-    base_uri = _parsed_url(_url_for(uri))
+def _load_from_uri(uri, timeout=None, headers={}):
+    request = Request(uri, headers=headers)
+    resource = urlopen(request, timeout=timeout)
+    base_uri = _parsed_url(_url_for(request))
     if PYTHON_MAJOR_VERSION < (3,):
         content = _read_python2x(resource)
     else:
@@ -58,15 +58,15 @@ def _load_from_uri(uri, timeout=None):
     return M3U8(content, base_uri=base_uri)
 
 
-def _url_for(uri):
-    return urlopen(uri).geturl()
+def _url_for(request):
+    return urlopen(request).geturl()
 
 
 def _parsed_url(url):
-    parsed_url = url_parser.urlparse(url)
+    parsed_url = urlparse(url)
     prefix = parsed_url.scheme + '://' + parsed_url.netloc
     base_path = posixpath.normpath(parsed_url.path + '/..')
-    return url_parser.urljoin(prefix, base_path)
+    return urljoin(prefix, base_path)
 
 
 def _read_python2x(resource):
@@ -74,7 +74,9 @@ def _read_python2x(resource):
 
 
 def _read_python3x(resource):
-    return resource.read().decode(resource.headers.get_content_charset(failobj="utf-8"))
+    return resource.read().decode(
+        resource.headers.get_content_charset(failobj="utf-8")
+    )
 
 
 def _load_from_file(uri):
diff --git a/m3u8/model.py b/m3u8/model.py
index 591faa7..f39dd68 100644
--- a/m3u8/model.py
+++ b/m3u8/model.py
@@ -412,7 +412,7 @@ class Key(BasePathMixin):
 
     '''
 
-    def __init__(self, method, uri, base_uri, iv=None, keyformat=None, keyformatversions=None):
+    def __init__(self, method, base_uri, uri=None, iv=None, keyformat=None, keyformatversions=None):
         self.method = method
         self.uri = uri
         self.iv = iv
diff --git a/m3u8/parser.py b/m3u8/parser.py
index 21e6207..1e472da 100644
--- a/m3u8/parser.py
+++ b/m3u8/parser.py
@@ -218,13 +218,12 @@ def _parse_attribute_list(prefix, line, atribute_parser):
 
     return attributes
 
-
 def _parse_stream_inf(line, data, state):
     data['is_variant'] = True
     data['media_sequence'] = None
     atribute_parser = remove_quotes_parser('codecs', 'audio', 'video', 'subtitles')
     atribute_parser["program_id"] = int
-    atribute_parser["bandwidth"] = int
+    atribute_parser["bandwidth"] = lambda x: int(float(x))
     atribute_parser["average_bandwidth"] = int
     state['stream_info'] = _parse_attribute_list(protocol.ext_x_stream_inf, line, atribute_parser)
 
diff --git a/setup.py b/setup.py
index 8c727c2..c450f0f 100644
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@ setup(
     name="m3u8",
     author='Globo.com',
     author_email='videos3 at corp.globo.com',
-    version="0.3.0",
+    version="0.3.1",
     license='MIT',
     zip_safe=False,
     include_package_data=True,
diff --git a/tests/playlists.py b/tests/playlists.py
index bad5da0..fe405a1 100755
--- a/tests/playlists.py
+++ b/tests/playlists.py
@@ -82,6 +82,18 @@ http://example.com/hi.m3u8
 http://example.com/audio-only.m3u8
 '''
 
+VARIANT_PLAYLIST_WITH_BANDWIDTH_FLOAT = '''
+#EXTM3U
+#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1280000.0
+http://example.com/low.m3u8
+#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000.4
+http://example.com/mid.m3u8
+#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000.6
+http://example.com/hi.m3u8
+#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS="mp4a.40.5,avc1.42801e"
+http://example.com/audio-only.m3u8
+'''
+
 VARIANT_PLAYLIST_WITH_IFRAME_PLAYLISTS = '''
 #EXTM3U
 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=624x352,CODECS="avc1.4d001f, mp4a.40.5"
@@ -342,6 +354,38 @@ PLAYLIST_WITH_MULTIPLE_KEYS_UNENCRYPTED_AND_ENCRYPTED_NONE = '''
 
 '''
 
+PLAYLIST_WITH_MULTIPLE_KEYS_UNENCRYPTED_AND_ENCRYPTED_NONE_AND_NO_URI_ATTR = '''
+#EXTM3U
+#EXT-X-MEDIA-SEQUENCE:82400
+#EXT-X-ALLOW-CACHE:NO
+#EXT-X-VERSION:2
+#EXT-X-TARGETDURATION:8
+#EXTINF:8,
+../../../../hls/streamNum82400.ts
+#EXTINF:8,
+../../../../hls/streamNum82401.ts
+#EXT-X-KEY:METHOD=AES-128,URI="/hls-key/key.bin",IV=0X10ef8f758ca555115584bb5b3c687f52
+#EXTINF:8,
+../../../../hls/streamNum82400.ts
+#EXTINF:8,
+../../../../hls/streamNum82401.ts
+#EXTINF:8,
+../../../../hls/streamNum82402.ts
+#EXTINF:8,
+../../../../hls/streamNum82403.ts
+#EXT-X-KEY:METHOD=NONE
+#EXTINF:8,
+../../../../hls/streamNum82404.ts
+#EXTINF:8,
+../../../../hls/streamNum82405.ts
+#EXT-X-KEY:METHOD=AES-128,URI="/hls-key/key2.bin",IV=0Xcafe8f758ca555115584bb5b3c687f52
+#EXTINF:8,
+../../../../hls/streamNum82404.ts
+#EXTINF:8,
+../../../../hls/streamNum82405.ts
+
+'''
+
 
 SIMPLE_PLAYLIST_WITH_TITLE = '''
 #EXTM3U
diff --git a/tests/test_model.py b/tests/test_model.py
index 02d0f1d..5672291 100755
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -507,6 +507,14 @@ def test_should_dump_complex_unencrypted_encrypted_keys():
 
     assert expected == obj.dumps().strip()
 
+def test_should_dump_complex_unencrypted_encrypted_keys_no_uri_attr():
+    obj = m3u8.M3U8(playlists.PLAYLIST_WITH_MULTIPLE_KEYS_UNENCRYPTED_AND_ENCRYPTED_NONE_AND_NO_URI_ATTR)
+    expected = playlists.PLAYLIST_WITH_MULTIPLE_KEYS_UNENCRYPTED_AND_ENCRYPTED_NONE_AND_NO_URI_ATTR \
+        .strip()
+
+    assert expected == obj.dumps().strip()
+
+
 
 def test_length_segments_by_key():
     obj = m3u8.M3U8(playlists.PLAYLIST_WITH_MULTIPLE_KEYS_UNENCRYPTED_AND_ENCRYPTED)
@@ -536,7 +544,7 @@ def test_replace_segment_key():
     obj = m3u8.M3U8(playlists.PLAYLIST_WITH_MULTIPLE_KEYS_UNENCRYPTED_AND_ENCRYPTED)
 
     # Replace unencrypted segments with new key
-    new_key = Key("AES-128", "/hls-key/key0.bin", None, iv="0Xcafe8f758ca555115584bb5b3c687f52")
+    new_key = Key("AES-128", None, "/hls-key/key0.bin", iv="0Xcafe8f758ca555115584bb5b3c687f52")
     for segment in obj.segments.by_key(None):
         segment.key = new_key
 
diff --git a/tests/test_parser.py b/tests/test_parser.py
index b5355bb..3e0df79 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -77,6 +77,16 @@ def test_should_add_non_key_for_multiple_keys_unencrypted_and_encrypted():
     assert "AES-128" == last_segment_key['method']
     assert "0Xcafe8f758ca555115584bb5b3c687f52" == last_segment_key['iv']
 
+def test_should_handle_key_method_none_and_no_uri_attr():
+    data = m3u8.parse(playlists.PLAYLIST_WITH_MULTIPLE_KEYS_UNENCRYPTED_AND_ENCRYPTED_NONE_AND_NO_URI_ATTR)
+    assert 'key' not in data['segments'][0]
+    assert 'key' not in data['segments'][1]
+    third_segment_key = data['segments'][2]['key']
+    assert "/hls-key/key.bin" == third_segment_key['uri']
+    assert "AES-128" == third_segment_key['method']
+    assert "0X10ef8f758ca555115584bb5b3c687f52" == third_segment_key['iv']
+    assert "NONE" == data['segments'][6]['key']['method']  
+
 def test_should_parse_title_from_playlist():
     data = m3u8.parse(playlists.SIMPLE_PLAYLIST_WITH_TITLE)
     assert 1 == len(data['segments'])
@@ -113,6 +123,18 @@ def test_should_parse_variant_playlist_with_average_bandwidth():
     assert 65000 == playlists_list[3]['stream_info']['bandwidth']
     assert 63005 == playlists_list[3]['stream_info']['average_bandwidth']
 
+# This is actually not according to specification but as for example Twitch.tv
+# is producing master playlists that have bandwidth as floats (issue 72)
+# this tests that this situation does not break the parser and will just
+# truncate to a decimal-integer according to specification
+def test_should_parse_variant_playlist_with_bandwidth_as_float():
+    data = m3u8.parse(playlists.VARIANT_PLAYLIST_WITH_BANDWIDTH_FLOAT)
+    playlists_list = list(data['playlists'])
+    assert 1280000 == playlists_list[0]['stream_info']['bandwidth']
+    assert 2560000 == playlists_list[1]['stream_info']['bandwidth']
+    assert 7680000 == playlists_list[2]['stream_info']['bandwidth']
+    assert 65000 == playlists_list[3]['stream_info']['bandwidth']
+
 def test_should_parse_variant_playlist_with_iframe_playlists():
     data = m3u8.parse(playlists.VARIANT_PLAYLIST_WITH_IFRAME_PLAYLISTS)
     iframe_playlists = list(data['iframe_playlists'])

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-m3u8.git



More information about the Python-modules-commits mailing list