Use sqlite for storage

This commit is contained in:
Micke Nordin 2022-01-07 18:16:13 +01:00
parent ed4ddf1d01
commit f6628730d6
Signed by untrusted user who does not match committer: micke
GPG key ID: 0DA0A7A5708FE257
3 changed files with 117 additions and 57 deletions

View file

@ -1,15 +1,40 @@
#!/usr/bin/env python3
import io
from os import path
from posixpath import relpath
import json
import sqlite3
from os import environ, makedirs, path
from typing import Callable, Union
from urllib.parse import urlparse
import requests
import wx
from typing import Union, Callable
SIZE = wx.Size(100,68)
SIZE = wx.Size(100, 68)
MYPATH = path.dirname(path.abspath(__file__))
SCREEN_WIDTH = 720 /2
SCREEN_WIDTH = int(720 / 2)
BASEPATH = path.join(str(environ.get("HOME")), '.config/cast')
DB_FILE_NAME = 'cast.db'
SUB_TABLE = 'subscriptions'
def add_subscription(channel_id: str,
name: str,
basepath: str = BASEPATH,
filename: str = DB_FILE_NAME) -> None:
fullpath = path.join(basepath, filename)
if not path.isdir(basepath):
makedirs(basepath)
con = sqlite3.connect(fullpath)
cur = con.cursor()
create_query: str = '''CREATE TABLE IF NOT EXISTS {}
(channel_id TEXT PRIMARY KEY, channel_name TEXT)'''.format(SUB_TABLE)
cur.execute(create_query)
con.commit()
upsert_query: str = '''INSERT INTO {} (channel_id, channel_name)
VALUES('{}',"{}") ON CONFLICT(channel_id) DO NOTHING'''.format(SUB_TABLE, channel_id, name)
cur.execute(upsert_query)
con.commit()
def get_default_logo(providerid: str = 'default') -> wx.Bitmap:
if providerid == 'SVT':
@ -19,32 +44,65 @@ def get_default_logo(providerid: str = 'default') -> wx.Bitmap:
else:
return wx.Bitmap('{}/assets/Default.png'.format(MYPATH))
def make_sized_button(parent_pnl: wx.Panel, bitmap_or_str: Union[wx.Bitmap,str], text: str, callback: Callable) -> wx.BoxSizer:
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
if type(bitmap_or_str) == type(str):
if bitmap_or_str.startswith('http'): # type: ignore
bitmap = make_bitmap_from_url(bitmap_or_str) # type: ignore
else:
bitmap = wx.Bitmap(bitmap_or_str, wx.BITMAP_TYPE_ANY)
def get_subscriptions(basepath: str = BASEPATH,
filename: str = DB_FILE_NAME) -> list[tuple[str, str]]:
subscriptions = list()
fullpath = path.join(basepath, filename)
con = sqlite3.connect(fullpath)
cur = con.cursor()
select_query = '''SELECT * FROM {}'''.format(SUB_TABLE)
cur.execute(select_query)
for result in cur.fetchall():
print(result)
subscriptions.append(result)
return subscriptions
def import_from_newpipe(filename) -> None:
if path.isfile(filename):
with open(filename, 'r') as subs:
sub_data = json.loads(subs.read())
for channel in sub_data['subscriptions']:
if channel['service_id'] == 0:
channel_id = urlparse(channel['url']).path.split('/').pop()
add_subscription(channel_id, channel['name'])
def make_sized_button(parent_pnl: wx.Panel, bitmap_or_str: Union[wx.Bitmap,
str],
text: str, callback: Callable) -> wx.BoxSizer:
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
if type(bitmap_or_str) == type(str):
if bitmap_or_str.startswith('http'): # type: ignore
bitmap = make_bitmap_from_url(bitmap_or_str) # type: ignore
else:
bitmap = bitmap_or_str
btn_style = wx.BORDER_NONE | wx.BU_AUTODRAW | wx.BU_EXACTFIT | wx.BU_NOTEXT
btn_logo = wx.BitmapButton(parent_pnl, wx.ID_ANY, bitmap , style=btn_style)
btn_logo.SetMinSize(SIZE)
btn_logo.SetToolTip(text)
btn_sizer.Add(btn_logo, 0, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.TOP, 1)
bitmap = wx.Bitmap(bitmap_or_str, wx.BITMAP_TYPE_ANY)
else:
bitmap = bitmap_or_str
btn_style = wx.BORDER_NONE | wx.BU_AUTODRAW | wx.BU_EXACTFIT | wx.BU_NOTEXT
btn_logo = wx.BitmapButton(parent_pnl, wx.ID_ANY, bitmap, style=btn_style)
btn_logo.SetMinSize(SIZE)
btn_logo.SetToolTip(text)
btn_sizer.Add(btn_logo, 0, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.TOP, 1)
btn_text = wx.Button(parent_pnl, wx.ID_ANY, text, style=wx.BORDER_NONE | wx.BU_AUTODRAW)
btn_text.SetMinSize(wx.Size(SCREEN_WIDTH - SIZE.GetWidth(),SIZE.GetHeight()))
btn_text.SetToolTip(text)
btn_sizer.Add(btn_text, 0, wx.BOTTOM | wx.RIGHT | wx.TOP | wx.EXPAND, 1)
parent_pnl.Bind(wx.EVT_BUTTON, callback, btn_logo)
parent_pnl.Bind(wx.EVT_BUTTON, callback, btn_text)
btn_text = wx.Button(parent_pnl,
wx.ID_ANY,
text,
style=wx.BORDER_NONE | wx.BU_AUTODRAW)
btn_text.SetMinSize(
wx.Size(SCREEN_WIDTH - SIZE.GetWidth(), SIZE.GetHeight()))
btn_text.SetToolTip(text)
btn_sizer.Add(btn_text, 0, wx.BOTTOM | wx.RIGHT | wx.TOP | wx.EXPAND, 1)
parent_pnl.Bind(wx.EVT_BUTTON, callback, btn_logo)
parent_pnl.Bind(wx.EVT_BUTTON, callback, btn_text)
return btn_sizer
return btn_sizer
def make_bitmap_from_url(logo_url: str, size: wx.Size = SIZE ) -> wx.Bitmap:
def make_bitmap_from_url(logo_url: str, size: wx.Size = SIZE) -> wx.Bitmap:
res = requests.get(logo_url)
content = res.content
content_bytes = io.BytesIO(content)
@ -52,53 +110,58 @@ def make_bitmap_from_url(logo_url: str, size: wx.Size = SIZE ) -> wx.Bitmap:
scale_factor = image.GetWidth() / SCREEN_WIDTH
size.SetWidth(SCREEN_WIDTH)
height = image.GetHeight()
size.SetHeight(height/scale_factor)
image.Rescale(size.GetWidth(), size.GetHeight() )
size.SetHeight(height / scale_factor)
image.Rescale(size.GetWidth(), size.GetHeight())
return wx.Bitmap(image)
def make_bitmap_from_file(path, size: wx.Size = SIZE) -> wx.Bitmap:
image = wx.Image(path, type=wx.BITMAP_TYPE_ANY, index=-1)
# scale_factor = image.GetWidth() / SCREEN_WIDTH
# size.SetWidth(SCREEN_WIDTH)
# height = image.GetHeight()
# size.SetHeight(height/scale_factor)
# image.Rescale(size.GetWidth(), size.GetHeight() )
# scale_factor = image.GetWidth() / SCREEN_WIDTH
# size.SetWidth(SCREEN_WIDTH)
# height = image.GetHeight()
# size.SetHeight(height/scale_factor)
# image.Rescale(size.GetWidth(), size.GetHeight() )
return wx.Bitmap(image)
def resolve_svt_channel(svt_id: str) -> dict:
channels = {
"ch-barnkanalen": {
"name":
"Barnkanalen",
"thumbnail": make_bitmap_from_file('{}/assets/Barnkanalen.png'.format(MYPATH))
"thumbnail":
make_bitmap_from_file('{}/assets/Barnkanalen.png'.format(MYPATH))
},
"ch-svt1": {
"name":
"SVT 1",
"thumbnail": make_bitmap_from_file('{}/assets/SVT1.png'.format(MYPATH))
"name": "SVT 1",
"thumbnail":
make_bitmap_from_file('{}/assets/SVT1.png'.format(MYPATH))
},
"ch-svt2": {
"name":
"SVT 2",
"thumbnail": make_bitmap_from_file('{}/assets/SVT2.png'.format(MYPATH))
"name": "SVT 2",
"thumbnail":
make_bitmap_from_file('{}/assets/SVT2.png'.format(MYPATH))
},
"ch-svt24": {
"name":
"SVT 24",
"thumbnail": make_bitmap_from_file('{}/assets/SVT24.png'.format(MYPATH))
"thumbnail":
make_bitmap_from_file('{}/assets/SVT24.png'.format(MYPATH))
},
"ch-kunskapskanalen": {
"name":
"Kunskapskanalen",
"thumbnail": make_bitmap_from_file('{}/assets/Kunskapskanalen.png'.format(MYPATH))
"thumbnail":
make_bitmap_from_file(
'{}/assets/Kunskapskanalen.png'.format(MYPATH))
},
"feed": {
"name": "Senaste program",
"thumbnail": make_bitmap_from_file('{}/assets/SVT.png'.format(MYPATH))
"thumbnail":
make_bitmap_from_file('{}/assets/SVT.png'.format(MYPATH))
},
}
return channels[svt_id]

View file

@ -13,10 +13,10 @@ import wx.media
from Channel import SVT, YouTube
from ChannelProvider import ChannelProvider
from Utils import make_sized_button
from Utils import get_subscriptions, import_from_newpipe, make_sized_button
WIDTH = 720 / 2
HEIGHT = 1440 / 2
WIDTH = int(720 / 2)
HEIGHT = int(1440 / 2)
BTN_HEIGHT = 40
SPACER_HEIGHT = 10
SCROLL_RATE = 5
@ -91,15 +91,11 @@ class Cast(wx.Frame):
subfile = 'yt_subs.json'
if os.path.isfile(subfile):
with open(subfile, 'r') as subs:
janson = json.loads(subs.read())
for channel in janson['subscriptions']:
if channel['service_id'] == 0:
channel_id = urlparse(
channel['url']).path.split('/').pop()
youtube.append_channel(
YouTube.YouTube(channel_id, channel['name']))
import_from_newpipe(subfile)
subscriptions = get_subscriptions()
for channel in subscriptions:
print(channel)
youtube.append_channel(YouTube.YouTube(channel[0], channel[1]))
providers.append(youtube)
@ -217,7 +213,7 @@ class Cast(wx.Frame):
inner_sizer = wx.GridBagSizer()
self.m_control = wx.media.MediaCtrl(
self.m_panel,
size=(WIDTH, HEIGHT / 2),
size=(WIDTH, int(HEIGHT / 2)),
style=wx.SIMPLE_BORDER,
szBackend=wx.media.MEDIABACKEND_GSTREAMER,
)

1
src/yt_subs.json Normal file

File diff suppressed because one or more lines are too long