From cdf248d8e40de10e3c2c52df40dd04d967ea8eb4 Mon Sep 17 00:00:00 2001 From: Giulio Bottari Date: Wed, 6 Oct 2021 22:37:32 -0300 Subject: [PATCH 1/2] Refactor _initialize_attributes() avoiding code repetition --- m3u8/model.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/m3u8/model.py b/m3u8/model.py index 19b7af0b..44a68d73 100644 --- a/m3u8/model.py +++ b/m3u8/model.py @@ -6,6 +6,7 @@ import os import errno import math +import functools from m3u8.protocol import ext_x_start, ext_x_key, ext_x_session_key, ext_x_map from m3u8.parser import parse, format_date_time @@ -186,17 +187,14 @@ def _initialize_attributes(self): ) self.segment_map = self.data.get('segment_map') - start = self.data.get('start', None) - self.start = start and Start(**start) - - server_control = self.data.get('server_control', None) - self.server_control = server_control and ServerControl(**server_control) - - part_inf = self.data.get('part_inf', None) - self.part_inf = part_inf and PartInformation(**part_inf) - - skip = self.data.get('skip', None) - self.skip = skip and Skip(**skip) + for attr, cls in (('start', Start), + ('server_control', ServerControl), + ('part_inf', PartInformation), + ('skip', Skip), + ('preload_hint', functools.partial(PreloadHint, base_uri=self.base_uri))): + # if missing set the attribute to None + val = self.data.get(attr, None) + setattr(self, attr, val and cls(**val)) self.rendition_reports = RenditionReportList([ RenditionReport(base_uri=self.base_uri, **rendition_report) for rendition_report in self.data.get('rendition_reports', []) ]) @@ -208,9 +206,6 @@ def _initialize_attributes(self): self.session_keys = [ SessionKey(base_uri=self.base_uri, **params) if params else None for params in self.data.get('session_keys', []) ] - preload_hint = self.data.get('preload_hint', None) - self.preload_hint = preload_hint and PreloadHint(base_uri=self.base_uri, **preload_hint) - def __unicode__(self): return self.dumps() From e69caf45c939e78f159d5edd43d3e91300c59678 Mon Sep 17 00:00:00 2001 From: Giulio Bottari Date: Thu, 7 Oct 2021 00:50:27 -0300 Subject: [PATCH 2/2] Refactor most loops in _initialize_attributes() --- m3u8/model.py | 75 +++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/m3u8/model.py b/m3u8/model.py index 44a68d73..a16d9030 100644 --- a/m3u8/model.py +++ b/m3u8/model.py @@ -156,55 +156,60 @@ def __init__(self, content=None, base_path=None, base_uri=None, strict=False, cu self._initialize_attributes() self.base_path = base_path - def _initialize_attributes(self): - self.keys = [ Key(base_uri=self.base_uri, **params) if params else None - for params in self.data.get('keys', []) ] - self.segments = SegmentList([ Segment(base_uri=self.base_uri, keyobject=find_key(segment.get('key', {}), self.keys), **segment) - for segment in self.data.get('segments', []) ]) - #self.keys = get_uniques([ segment.key for segment in self.segments ]) for attr, param in self.simple_attributes: setattr(self, attr, self.data.get(param)) - self.files = [] - for key in self.keys: - # Avoid None key, it could be the first one, don't repeat them - if key and key.uri not in self.files: - self.files.append(key.uri) - self.files.extend(self.segments.uri) - - self.media = MediaList([ Media(base_uri=self.base_uri, **media) - for media in self.data.get('media', []) ]) - - self.playlists = PlaylistList([ Playlist(base_uri=self.base_uri, media=self.media, **playlist) - for playlist in self.data.get('playlists', []) ]) - - self.iframe_playlists = PlaylistList() - for ifr_pl in self.data.get('iframe_playlists', []): - self.iframe_playlists.append(IFramePlaylist(base_uri=self.base_uri, - uri=ifr_pl['uri'], - iframe_stream_info=ifr_pl['iframe_stream_info']) - ) - self.segment_map = self.data.get('segment_map') - + PartialPreloadHint = functools.partial(PreloadHint, base_uri=self.base_uri) for attr, cls in (('start', Start), ('server_control', ServerControl), ('part_inf', PartInformation), ('skip', Skip), - ('preload_hint', functools.partial(PreloadHint, base_uri=self.base_uri))): + ('preload_hint', PartialPreloadHint)): # if missing set the attribute to None val = self.data.get(attr, None) setattr(self, attr, val and cls(**val)) - self.rendition_reports = RenditionReportList([ RenditionReport(base_uri=self.base_uri, **rendition_report) - for rendition_report in self.data.get('rendition_reports', []) ]) + self.segment_map = self.data.get('segment_map') + + def build_models(builder, key, filter_func=None): + param_list = self.data.get(key, []) + if filter_func: + param_list = filter(filter_func, param_list) + return (builder(params) for params in param_list) - self.session_data = SessionDataList([ SessionData(**session_data) - for session_data in self.data.get('session_data', []) - if 'data_id' in session_data ]) + build_rendention_report = lambda rendition_report: RenditionReport(base_uri=self.base_uri, **rendition_report) + self.rendition_reports = RenditionReportList(build_models(build_rendention_report, 'rendition_reports')) - self.session_keys = [ SessionKey(base_uri=self.base_uri, **params) if params else None - for params in self.data.get('session_keys', []) ] + build_session_data = lambda session_data: SessionData(**session_data) + self.session_data = SessionDataList(build_models(build_session_data, 'session_data', + filter_func=lambda session_data: 'data_id' in session_data)) + + build_iframe_playlist = lambda ifr_pl: IFramePlaylist(base_uri=self.base_uri, uri=ifr_pl['uri'], + iframe_stream_info=ifr_pl['iframe_stream_info']) + self.iframe_playlists = PlaylistList(build_models(build_iframe_playlist, 'iframe_playlists')) + + build_media = lambda media: Media(base_uri=self.base_uri, **media) + self.media = MediaList(build_models(build_media, 'media')) + + build_playlist = lambda playlist: Playlist(base_uri=self.base_uri, media=self.media, **playlist) + self.playlists = PlaylistList(build_models(build_playlist, 'playlists')) + + build_session_key = lambda params: SessionKey(base_uri=self.base_uri, **params) if params else None + self.session_keys = list(build_models(build_session_key, 'session_keys')) + + build_key = lambda params: Key(base_uri=self.base_uri, **params) if params else None + self.keys = list(build_models(build_key, 'keys')) + + build_segment = lambda segment: Segment(base_uri=self.base_uri, keyobject=find_key(segment.get('key', {}), self.keys), **segment) + self.segments = SegmentList(build_models(build_segment, 'segments')) + + self.files = [] + for key in self.keys: + # Avoid None key, it could be the first one, don't repeat them + if key and key.uri not in self.files: + self.files.append(key.uri) + self.files.extend(self.segments.uri) def __unicode__(self): return self.dumps()