cast/Channel/YouTube/__init__.py

98 lines
3.7 KiB
Python

import hashlib
import io
import os
import pickle
import threading
from typing import Union
import feedparser
import requests
import wx
from Channel import Channel
from Items import Item
from youtube_dl import YoutubeDL as yt
class YouTube(Channel):
m_cache: dict = dict()
m_cachefile = '/tmp/yt_cache'
def __init__(self, channel_id) -> None:
rss_url = 'https://www.youtube.com/feeds/videos.xml?channel_id={}'.format(
channel_id)
logo_url = 'https://upload.wikimedia.org/wikipedia/commons/'
logo_url += 'thumb/0/09/YouTube_full-color_icon_(2017).svg/480px-YouTube_full-color_icon_(2017).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):
with open(self.m_cachefile, 'rb') as cachehandle:
self.m_cache = pickle.load(cachehandle)
self.m_thr = threading.Thread(target=self.parse_feed,
args=(),
kwargs={})
self.m_thr.start()
def wait(self) -> bool:
return self.m_thr.is_alive()
def parse_feed(self) -> None:
feed = feedparser.parse(self.get_feed())
ydl_opts = {
'format':
'worstvideo[ext=mp4]+worstaudio[ext=m4a]/worstvideo+worstaudio',
'container': 'webm_dash',
}
entries = feed['entries']
self.m_items: list[Item] = list()
for entry in entries:
key = hashlib.sha256(entry['link'].encode('utf-8')).hexdigest()
if key in self.m_cache.keys():
thumbnail_link = self.m_cache[key]['thumbnail_link']
content = self.m_cache[key]['content']
resolved_link = self.m_cache[key]['resolved_link']
description = self.m_cache[key]['description']
published_parsed = self.m_cache[key]['published_parsed']
title = self.m_cache[key]['title']
else:
title = str(entry['title'])
thumbnail_link = str(entry['media_thumbnail'][0]['url'])
description = str(entry['description'])
link = ''
with yt(ydl_opts) as ydl:
video = yt(ydl_opts).extract_info(entry['link'],
download=False)
for form in video['formats']:
if form['height']:
if form['height'] < 480 and form[
'acodec'] != 'none':
link = form['url']
resolved_link = link
published_parsed = entry['published_parsed']
res = requests.get(thumbnail_link)
content = res.content
if not resolved_link:
continue
content_bytes = io.BytesIO(content)
self.m_cache[key] = {'thumbnail_link': thumbnail_link}
self.m_cache[key]['content'] = content
self.m_cache[key]['resolved_link'] = resolved_link
self.m_cache[key]['description'] = description
self.m_cache[key]['published_parsed'] = published_parsed
self.m_cache[key]['title'] = title
image = wx.Image(content_bytes, type=wx.BITMAP_TYPE_ANY, index=-1)
thumbnail = wx.Bitmap(image)
item = Item(description, resolved_link, self.m_provider_name,
published_parsed, thumbnail, title)
self.m_items.append(item)
# write to cache file
with open(self.m_cachefile, 'wb') as cachehandle:
pickle.dump(self.m_cache, cachehandle)