From 6010e3a6fa8249f842def27ccc2a62e4a2c5d394 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Wed, 22 Dec 2021 17:05:53 +0100 Subject: [PATCH] Add splashscreen to select providers --- ChannelProvider/SVT/__init__.py | 5 +- ChannelProvider/YouTube/__init__.py | 12 +-- ChannelProvider/__init__.py | 27 +++++- main.py | 122 +++++++++++++++++++--------- 4 files changed, 121 insertions(+), 45 deletions(-) diff --git a/ChannelProvider/SVT/__init__.py b/ChannelProvider/SVT/__init__.py index d8f6e96..6277bab 100644 --- a/ChannelProvider/SVT/__init__.py +++ b/ChannelProvider/SVT/__init__.py @@ -20,7 +20,10 @@ class SVT(ChannelProvider.ChannelProvider): m_cachefile = '/tmp/svt_cache' def __init__(self) -> None: - super().__init__('SVT', 'http://www.svtplay.se/rss.xml') + rss_url = 'http://www.svtplay.se/rss.xml' + logo_url = 'https://upload.wikimedia.org/wikipedia/commons/' + logo_url += 'thumb/4/4b/Logotyp_SVT_Play.png/480px-Logotyp_SVT_Play.png' + super().__init__('SVT', rss_url, logo_url) if os.path.exists(self.m_cachefile): with open(self.m_cachefile, 'rb') as cachehandle: diff --git a/ChannelProvider/YouTube/__init__.py b/ChannelProvider/YouTube/__init__.py index d789768..fb43e65 100644 --- a/ChannelProvider/YouTube/__init__.py +++ b/ChannelProvider/YouTube/__init__.py @@ -18,10 +18,11 @@ class YouTube(ChannelProvider): m_cachefile = '/tmp/yt_cache' def __init__(self, channel_id) -> None: - super().__init__( - channel_id, - 'https://www.youtube.com/feeds/videos.xml?channel_id={}'.format( - channel_id)) + rss_url = 'https://www.youtube.com/feeds/videos.xml?channel_id={}'.format( + channel_id) + logo_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb' + logo_url += '/3/3f/Logo_of_YouTube_(2005-2011).svg/480px-Logo_of_YouTube_(2005-2011).svg.png' + super().__init__(channel_id, rss_url, logo_url) self.m_items: Union[list[Item], None] = None if os.path.exists(self.m_cachefile): @@ -39,7 +40,8 @@ class YouTube(ChannelProvider): feed = feedparser.parse(self.get_feed()) ydl_opts = { - 'format': 'worst', + 'format': + 'worstvideo[ext=mp4]+worstaudio[ext=m4a]/worstvideo+worstaudio', 'container': 'webm_dash', } entries = feed['entries'] diff --git a/ChannelProvider/__init__.py b/ChannelProvider/__init__.py index bd6413a..14454f5 100644 --- a/ChannelProvider/__init__.py +++ b/ChannelProvider/__init__.py @@ -2,14 +2,39 @@ from typing import Union +import requests +import wx +import io + from Items import Item +default_logo = "https://upload.wikimedia.org/wikipedia/commons/" +default_logo += "thumb/f/fd/Cartoon_Hand_Playing_Multiple_Online_Videos.svg/" +default_logo += "480px-Cartoon_Hand_Playing_Multiple_Online_Videos.svg.png" + class ChannelProvider: - def __init__(self, provider_name: str, feed: str) -> None: + def __init__(self, + provider_name: str, + feed: str, + logo_url: str = default_logo) -> None: self.m_provider_name = provider_name self.m_feed = feed self.m_items: Union[list[Item], None] = None + res = requests.get(logo_url) + content = res.content + content_bytes = io.BytesIO(content) + self.m_logo = wx.Image(content_bytes, + type=wx.BITMAP_TYPE_ANY, + index=-1) + + def get_logo_as_bitmap(self) -> wx.Bitmap: + """ + [TODO:description] + + :rtype wx.Image: [TODO:description] + """ + return wx.Bitmap(self.m_logo) def get_feed(self) -> str: return self.m_feed diff --git a/main.py b/main.py index 2b6024e..40ce9bb 100644 --- a/main.py +++ b/main.py @@ -14,7 +14,6 @@ ChannelProvider = NewType('ChannelProvider', ChannelProvider) class Cast(wx.Frame): - def __init__(self, *args, **kw): """__init__. :param args: @@ -22,7 +21,7 @@ class Cast(wx.Frame): """ super().__init__(*args, **kw) self.m_selected_chromecast = None - self.SetSizeHints(480,480,maxW=480) + self.SetSizeHints(480, 480, maxW=480) self.m_index = 0 self.m_chromecast_thr = threading.Thread(target=self.get_chromecasts, args=(), @@ -34,49 +33,90 @@ class Cast(wx.Frame): self.m_control = None self.m_panel.SetupScrolling() self.m_panel.SetSizer(self.m_sizer) - self.m_channels: list[ChannelProvider] = [YouTube.YouTube('UCu6mSoMNzHQiBIOCkHUa2Aw')]#,SVT.SVT()] - self.show_list(None) + self.m_providers: list[ChannelProvider] = [ + YouTube.YouTube('UCu6mSoMNzHQiBIOCkHUa2Aw'), + SVT.SVT() + ] + self.m_selected_channel = None + self.show_splash(None) + + def get_chromecasts(self) -> None: + """ + [TODO:description] - def get_chromecasts(self): + :rtype None: [TODO:description] + """ self.m_chromecasts, self.m_browser = pychromecast.get_chromecasts() - def show_list(self, _): + def show_splash(self, _) -> None: + self.m_sizer.Clear(delete_windows=True) + self.m_sizer = wx.BoxSizer(wx.VERTICAL) + channel_index = 0 + for provider in self.m_providers: + bitmap = provider.get_logo_as_bitmap() + btn = wx.BitmapButton(self.m_panel, + id=channel_index, + bitmap=bitmap) + btn.Bind(wx.EVT_BUTTON, + lambda event, index=channel_index: self.show_list( + event, index)) + self.m_sizer.Add(btn) + channel_index += 1 + + self.m_panel.SetSizer(self.m_sizer) + self.m_sizer.Fit(self) + self.m_panel.Layout() + + def show_list(self, _, index=0) -> None: + """ + Shows a list of videos + + :param _ [TODO:type]: [TODO:description] + :rtype None: [TODO:description] + """ self.m_sizer.Clear(delete_windows=True) self.m_sizer = wx.BoxSizer(wx.VERTICAL) - for channel in self.m_channels: - if channel.wait(): - with wx.BusyInfo("Please wait, working..."): - index = 0 - while channel.wait(): - time.sleep(1) - wx.GetApp().Yield() - - - for item in channel.get_items(): - title = wx.StaticText(self.m_panel, -1) - title.SetLabelMarkup("{}".format(item['title'])) - description = wx.StaticText(self.m_panel, -1, - item['description']) - - description.Wrap(478) - bitmap = item['thumbnail'] - btn = wx.BitmapButton(self.m_panel, - id=self.m_index, - bitmap=bitmap) - btn.Bind(wx.EVT_BUTTON, - lambda event, link=item['link']: self.show_player( - event, link)) - self.m_sizer.Add(title) - self.m_sizer.Add(btn) - self.m_sizer.Add(description) - self.m_sizer.AddSpacer(10) - self.m_index = self.m_index + 1 + channel = self.m_providers[index] + if channel.wait(): + with wx.BusyInfo("Please wait, working..."): + index = 0 + while channel.wait(): + time.sleep(1) + wx.GetApp().Yield() + + backbtn = wx.Button(self.m_panel, -1, label="Go back", size=(480, 40)) + backbtn.Bind(wx.EVT_BUTTON, lambda event: self.show_splash(event)) + self.m_sizer.Add(backbtn, wx.ALIGN_CENTER_VERTICAL) + self.m_sizer.AddSpacer(10) + for item in channel.get_items(): + title = wx.StaticText(self.m_panel, -1) + title.SetLabelMarkup("{}".format( + item['title'])) + description = wx.StaticText(self.m_panel, -1, item['description']) + + description.Wrap(478) + bitmap = item['thumbnail'] + btn = wx.BitmapButton(self.m_panel, id=self.m_index, bitmap=bitmap) + btn.Bind(wx.EVT_BUTTON, + lambda event, link=item['link'], provider_index=index: + self.show_player(event, link, provider_index)) + self.m_sizer.Add(title) + self.m_sizer.Add(btn) + self.m_sizer.Add(description) + self.m_sizer.AddSpacer(10) + self.m_index = self.m_index + 1 self.m_panel.SetSizer(self.m_sizer) self.m_sizer.Fit(self) self.m_panel.Layout() - def show_player(self, _, uri): + def show_player(self, _, uri, provider_index: int): + """ + Show the video player + + :param _ event: unused + :param uri str: the link to the video stream + """ self.m_sizer.Clear(delete_windows=True) self.m_sizer = wx.GridBagSizer() self.m_control = wx.media.MediaCtrl( @@ -89,7 +129,9 @@ class Cast(wx.Frame): pause_button = wx.Button(self.m_panel, -1, "Pause") back_button = wx.Button(self.m_panel, -1, "Back") - back_button.Bind(wx.EVT_BUTTON, self.show_list) + back_button.Bind( + wx.EVT_BUTTON, + lambda event, index=provider_index: self.show_list(event, index)) self.m_sizer.Add(self.m_control, (0, 0)) self.m_sizer.SetItemSpan(0, (0, 6)) @@ -97,7 +139,8 @@ class Cast(wx.Frame): self.m_sizer.Add(pause_button, (1, 2)) self.m_sizer.Add(back_button, (1, 3)) - if not self.m_chromecast_thr.is_alive() and not self.m_selected_chromecast: + if not self.m_chromecast_thr.is_alive( + ) and not self.m_selected_chromecast: chromecast_button = wx.Button(self.m_panel, -1, "Cast") chromecast_button.Bind( wx.EVT_BUTTON, @@ -127,7 +170,10 @@ class Cast(wx.Frame): for cast in self.m_chromecasts: friendly_name = cast.cast_info.friendly_name - btn = wx.Button(self.m_panel, id=-1, label=friendly_name, size=(480,40)) + btn = wx.Button(self.m_panel, + id=-1, + label=friendly_name, + size=(480, 40)) btn.Bind(wx.EVT_BUTTON, lambda event, chromecast=cast, muri=uri: self. set_chromecast(event, chromecast, muri))