Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run format with ruff #346

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: chartboost/ruff-action@v1

ruff_format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chartboost/ruff-action@v1
with:
args: format --check
2 changes: 1 addition & 1 deletion m3u8/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"loads",
"load",
"parse",
"ParseError"
"ParseError",
)


Expand Down
31 changes: 17 additions & 14 deletions m3u8/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class M3U8:
("allow_cache", "allow_cache"),
("playlist_type", "playlist_type"),
("discontinuity_sequence", "discontinuity_sequence"),
("is_images_only", "is_images_only")
("is_images_only", "is_images_only"),
)

def __init__(
Expand Down Expand Up @@ -232,12 +232,12 @@ def _initialize_attributes(self):
)

self.image_playlists = PlaylistList()
for img_pl in self.data.get('image_playlists', []):
for img_pl in self.data.get("image_playlists", []):
self.image_playlists.append(
ImagePlaylist(
base_uri=self.base_uri,
uri=img_pl["uri"],
image_stream_info=img_pl["image_stream_info"]
image_stream_info=img_pl["image_stream_info"],
)
)

Expand Down Expand Up @@ -1547,27 +1547,28 @@ def __init__(self, base_uri, uri, image_stream_info):
hdcp_level=None,
frame_rate=None,
pathway_id=image_stream_info.get("pathway_id"),
stable_variant_id=image_stream_info.get("stable_variant_id")
stable_variant_id=image_stream_info.get("stable_variant_id"),
)

def __str__(self):
image_stream_inf = []
if self.image_stream_info.program_id:
image_stream_inf.append("PROGRAM-ID=%d" %
self.image_stream_info.program_id)
image_stream_inf.append("PROGRAM-ID=%d" % self.image_stream_info.program_id)
if self.image_stream_info.bandwidth:
image_stream_inf.append("BANDWIDTH=%d" %
self.image_stream_info.bandwidth)
image_stream_inf.append("BANDWIDTH=%d" % self.image_stream_info.bandwidth)
if self.image_stream_info.average_bandwidth:
image_stream_inf.append("AVERAGE-BANDWIDTH=%d" %
self.image_stream_info.average_bandwidth)
image_stream_inf.append(
"AVERAGE-BANDWIDTH=%d" % self.image_stream_info.average_bandwidth
)
if self.image_stream_info.resolution:
res = (str(self.image_stream_info.resolution[0]) + "x" +
str(self.image_stream_info.resolution[1]))
res = (
str(self.image_stream_info.resolution[0])
+ "x"
+ str(self.image_stream_info.resolution[1])
)
image_stream_inf.append("RESOLUTION=" + res)
if self.image_stream_info.codecs:
image_stream_inf.append("CODECS=" +
quoted(self.image_stream_info.codecs))
image_stream_inf.append("CODECS=" + quoted(self.image_stream_info.codecs))
if self.uri:
image_stream_inf.append("URI=" + quoted(self.uri))
if self.image_stream_info.pathway_id:
Expand All @@ -1581,6 +1582,7 @@ def __str__(self):

return "#EXT-X-IMAGE-STREAM-INF:" + ",".join(image_stream_inf)


class Tiles(BasePathMixin):
"""
Image tiles from a M3U8 playlist
Expand Down Expand Up @@ -1611,6 +1613,7 @@ def dumps(self):
def __str__(self):
return self.dumps()


def find_key(keydata, keylist):
if not keydata:
return None
Expand Down
22 changes: 8 additions & 14 deletions m3u8/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

try:
from backports.datetime_fromisoformat import MonkeyPatch

MonkeyPatch.patch_fromisoformat()
except ImportError:
pass
Expand Down Expand Up @@ -226,7 +227,7 @@ def parse(content, strict=False, custom_tags_parser=None):
_parse_image_stream_inf(line, data)

elif line.startswith(protocol.ext_x_images_only):
data['is_images_only'] = True
data["is_images_only"] = True

elif line.startswith(protocol.ext_x_tiles):
_parse_tiles(line, data, state)
Expand All @@ -239,11 +240,11 @@ def parse(content, strict=False, custom_tags_parser=None):
# blank lines are legal
pass

elif (not line.startswith('#')) and (state["expect_segment"]):
elif (not line.startswith("#")) and (state["expect_segment"]):
_parse_ts_chunk(line, data, state)
state["expect_segment"] = False

elif (not line.startswith('#')) and (state["expect_playlist"]):
elif (not line.startswith("#")) and (state["expect_playlist"]):
_parse_variant_playlist(line, data, state)
state["expect_playlist"] = False

Expand Down Expand Up @@ -290,9 +291,7 @@ def _parse_ts_chunk(line, data, state):
segment["program_date_time"] = state.pop("program_date_time")
if state.get("current_program_date_time"):
segment["current_program_date_time"] = state["current_program_date_time"]
state["current_program_date_time"] += timedelta(
seconds=segment["duration"]
)
state["current_program_date_time"] += timedelta(seconds=segment["duration"])
segment["uri"] = line
segment["cue_in"] = state.pop("cue_in", False)
segment["cue_out"] = state.pop("cue_out", False)
Expand Down Expand Up @@ -391,21 +390,18 @@ def _parse_image_stream_inf(line, data):
)
image_playlist = {
"uri": image_stream_info.pop("uri"),
"image_stream_info": image_stream_info
"image_stream_info": image_stream_info,
}

data["image_playlists"].append(image_playlist)



def _parse_tiles(line, data, state):
attribute_parser = remove_quotes_parser("uri")
attribute_parser["resolution"] = str
attribute_parser["layout"] = str
attribute_parser["duration"] = float
tiles_info = _parse_attribute_list(
protocol.ext_x_tiles, line, attribute_parser
)
tiles_info = _parse_attribute_list(protocol.ext_x_tiles, line, attribute_parser)
data["tiles"].append(tiles_info)


Expand Down Expand Up @@ -578,9 +574,7 @@ def _parse_part(line, data, state):
# this should always be true according to spec
if state.get("current_program_date_time"):
part["program_date_time"] = state["current_program_date_time"]
state["current_program_date_time"] += timedelta(
seconds=part["duration"]
)
state["current_program_date_time"] += timedelta(seconds=part["duration"])

part["dateranges"] = state.pop("dateranges", None)
part["gap_tag"] = state.pop("gap", None)
Expand Down
6 changes: 3 additions & 3 deletions m3u8/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@
ext_x_daterange = "#EXT-X-DATERANGE"
ext_x_gap = "#EXT-X-GAP"
ext_x_content_steering = "#EXT-X-CONTENT-STEERING"
ext_x_image_stream_inf = '#EXT-X-IMAGE-STREAM-INF'
ext_x_images_only = '#EXT-X-IMAGES-ONLY'
ext_x_tiles = '#EXT-X-TILES'
ext_x_image_stream_inf = "#EXT-X-IMAGE-STREAM-INF"
ext_x_images_only = "#EXT-X-IMAGES-ONLY"
ext_x_tiles = "#EXT-X-TILES"
17 changes: 8 additions & 9 deletions tests/playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@
#EXT-X-MEDIA:TYPE=AUDIO,NAME="audio-aac-eng",STABLE-RENDITION-ID="a8213e27c12a158ea8660e0fe8bdcac6072ca26d984e7e8603652bc61fdceffa",URI="http://example.com/eng.m3u8"
"""

VARIANT_PLAYLIST_WITH_IMAGE_PLAYLISTS = '''
VARIANT_PLAYLIST_WITH_IMAGE_PLAYLISTS = """
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-INDEPENDENT-SEGMENTS
Expand All @@ -1246,9 +1246,9 @@
index_0_a/new_index_0_a.m3u8S
#EXT-X-IMAGE-STREAM-INF:BANDWIDTH=16460,RESOLUTION=320x180,CODECS="jpeg",URI="5x2_320x180/320x180-5x2.m3u8"
#EXT-X-IMAGE-STREAM-INF:BANDWIDTH=32920,RESOLUTION=640x360,CODECS="jpeg",URI="5x2_640x360/640x360-5x2.m3u8"
'''
"""

VOD_IMAGE_PLAYLIST = '''
VOD_IMAGE_PLAYLIST = """
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:6
Expand Down Expand Up @@ -1295,9 +1295,9 @@
#EXT-X-TILES:RESOLUTION=640x360,LAYOUT=5x2,DURATION=6.006
content-7.jpg
#EXT-X-ENDLIST
'''
"""

VOD_IMAGE_PLAYLIST2 = '''
VOD_IMAGE_PLAYLIST2 = """
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXT-X-VERSION:7
Expand Down Expand Up @@ -1331,9 +1331,9 @@
#EXT-X-TILES:RESOLUTION=640x360,LAYOUT=4x3,DURATION=2.002
credits_2_1.jpg
#EXT-X-ENDLIST
'''
"""

LIVE_IMAGE_PLAYLIST = '''
LIVE_IMAGE_PLAYLIST = """
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXT-X-VERSION:7
Expand Down Expand Up @@ -1368,8 +1368,7 @@
content-130.jpg
#EXTINF:6.006,
content-131.jpg
'''

"""


del abspath, dirname, join
9 changes: 3 additions & 6 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,9 +854,7 @@ def test_should_dump_multiple_keys():
obj = m3u8.M3U8(
playlists.PLAYLIST_WITH_ENCRYPTED_SEGMENTS_AND_IV_WITH_MULTIPLE_KEYS
)
expected = (
playlists.PLAYLIST_WITH_ENCRYPTED_SEGMENTS_AND_IV_WITH_MULTIPLE_KEYS_SORTED.strip()
)
expected = playlists.PLAYLIST_WITH_ENCRYPTED_SEGMENTS_AND_IV_WITH_MULTIPLE_KEYS_SORTED.strip()

assert expected == obj.dumps().strip()

Expand Down Expand Up @@ -885,9 +883,7 @@ 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()
)
expected = playlists.PLAYLIST_WITH_MULTIPLE_KEYS_UNENCRYPTED_AND_ENCRYPTED_NONE_AND_NO_URI_ATTR.strip()

assert expected == obj.dumps().strip()

Expand Down Expand Up @@ -1560,6 +1556,7 @@ def test_dump_should_work_for_variant_playlists_with_image_playlists():

assert expected == obj.dumps().strip()


def test_segment_media_sequence():
obj = m3u8.M3U8(playlists.SLIDING_WINDOW_PLAYLIST)
assert [s.media_sequence for s in obj.segments] == [2680, 2681, 2682]
Expand Down
72 changes: 38 additions & 34 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,53 +297,57 @@ def test_should_parse_iframe_playlist():

def test_should_parse_variant_playlist_with_image_playlists():
data = m3u8.parse(playlists.VARIANT_PLAYLIST_WITH_IMAGE_PLAYLISTS)
image_playlists = list(data['image_playlists'])
image_playlists = list(data["image_playlists"])

assert True is data['is_variant']
assert True is data["is_variant"]
assert 2 == len(image_playlists)
assert '320x180' == image_playlists[0]['image_stream_info']['resolution']
assert 'jpeg' == image_playlists[0]['image_stream_info']['codecs']
assert '5x2_320x180/320x180-5x2.m3u8' == image_playlists[0]['uri']
assert '640x360' == image_playlists[1]['image_stream_info']['resolution']
assert 'jpeg' == image_playlists[1]['image_stream_info']['codecs']
assert '5x2_640x360/640x360-5x2.m3u8' == image_playlists[1]['uri']
assert "320x180" == image_playlists[0]["image_stream_info"]["resolution"]
assert "jpeg" == image_playlists[0]["image_stream_info"]["codecs"]
assert "5x2_320x180/320x180-5x2.m3u8" == image_playlists[0]["uri"]
assert "640x360" == image_playlists[1]["image_stream_info"]["resolution"]
assert "jpeg" == image_playlists[1]["image_stream_info"]["codecs"]
assert "5x2_640x360/640x360-5x2.m3u8" == image_playlists[1]["uri"]


def test_should_parse_vod_image_playlist():
data = m3u8.parse(playlists.VOD_IMAGE_PLAYLIST)

assert True is data['is_images_only']
assert 8 == len(data['tiles'])
assert 'preroll-ad-1.jpg' == data['segments'][0]['uri']
assert '640x360' == data['tiles'][0]['resolution']
assert '5x2' == data['tiles'][0]['layout']
assert 6.006 == data['tiles'][0]['duration']
assert 'byterange' not in data['tiles'][0]
assert True is data["is_images_only"]
assert 8 == len(data["tiles"])
assert "preroll-ad-1.jpg" == data["segments"][0]["uri"]
assert "640x360" == data["tiles"][0]["resolution"]
assert "5x2" == data["tiles"][0]["layout"]
assert 6.006 == data["tiles"][0]["duration"]
assert "byterange" not in data["tiles"][0]


def test_should_parse_vod_image_playlist2():
data = m3u8.parse(playlists.VOD_IMAGE_PLAYLIST2)

assert True is data['is_images_only']
assert '640x360' == data['tiles'][0]['resolution']
assert '4x3' == data['tiles'][0]['layout']
assert 2.002 == data['tiles'][0]['duration']
assert 6 == len(data['tiles'])
assert 'promo_1.jpg' == data['segments'][0]['uri']
assert True is data["is_images_only"]
assert "640x360" == data["tiles"][0]["resolution"]
assert "4x3" == data["tiles"][0]["layout"]
assert 2.002 == data["tiles"][0]["duration"]
assert 6 == len(data["tiles"])
assert "promo_1.jpg" == data["segments"][0]["uri"]


def test_should_parse_live_image_playlist():
data = m3u8.parse(playlists.LIVE_IMAGE_PLAYLIST)

assert True is data['is_images_only']
assert 10 == len(data['segments'])
assert 'content-123.jpg' == data['segments'][0]['uri']
assert 'content-124.jpg' == data['segments'][1]['uri']
assert 'content-125.jpg' == data['segments'][2]['uri']
assert 'missing-midroll.jpg' == data['segments'][3]['uri']
assert 'missing-midroll.jpg' == data['segments'][4]['uri']
assert 'missing-midroll.jpg' == data['segments'][5]['uri']
assert 'content-128.jpg' == data['segments'][6]['uri']
assert 'content-129.jpg' == data['segments'][7]['uri']
assert 'content-130.jpg' == data['segments'][8]['uri']
assert 'content-131.jpg' == data['segments'][9]['uri']
assert True is data["is_images_only"]
assert 10 == len(data["segments"])
assert "content-123.jpg" == data["segments"][0]["uri"]
assert "content-124.jpg" == data["segments"][1]["uri"]
assert "content-125.jpg" == data["segments"][2]["uri"]
assert "missing-midroll.jpg" == data["segments"][3]["uri"]
assert "missing-midroll.jpg" == data["segments"][4]["uri"]
assert "missing-midroll.jpg" == data["segments"][5]["uri"]
assert "content-128.jpg" == data["segments"][6]["uri"]
assert "content-129.jpg" == data["segments"][7]["uri"]
assert "content-130.jpg" == data["segments"][8]["uri"]
assert "content-131.jpg" == data["segments"][9]["uri"]


def test_should_parse_playlist_using_byteranges():
data = m3u8.parse(playlists.PLAYLIST_USING_BYTERANGES)
Expand Down Expand Up @@ -673,7 +677,7 @@ def parse_iptv_attributes(line, lineno, data, state):
def test_tag_after_extinf():
parsed_playlist = m3u8.loads(playlists.IPTV_PLAYLIST_WITH_EARLY_EXTINF)
actual = parsed_playlist.segments[0].uri
expected = 'http://str00.iptv.domain/7331/mpegts?token=longtokenhere'
expected = "http://str00.iptv.domain/7331/mpegts?token=longtokenhere"
assert actual == expected


Expand Down
Loading