Add image caching logic for show posters

This commit is contained in:
2022-09-13 22:57:43 -06:00
parent 9234da67fe
commit 6ace97ff83
+51 -11
View File
@@ -1,8 +1,9 @@
from typing import Type from typing import Type
import os import os
import shutil
import sys import sys
from urllib import parse import urllib.parse
from collections import defaultdict from collections import defaultdict
@@ -14,7 +15,6 @@ from PyQt5.QtCore import QObject, pyqtProperty, pyqtSlot
from PyQt5.QtGui import QImage from PyQt5.QtGui import QImage
from .qtmpv import MpvObject from .qtmpv import MpvObject
import requests import requests
@@ -92,13 +92,13 @@ class ProviderImageProvider(QQuickImageProvider):
def getUrl(base: str, path: str) -> dict: def getUrl(base: str, path: str) -> dict:
url: str = parse.urljoin(base, path) url: str = urllib.parse.urljoin(base, path)
r: requests.Response = requests.get(url) r: requests.Response = requests.get(url)
return r.json() return r.json()
class Provider(QObject): class Provider(QObject):
def __init__(self, url: str, parent=None): def __init__(self, url: str, data_dir: str, parent=None):
super().__init__(parent) super().__init__(parent)
self.url: str = url self.url: str = url
@@ -108,17 +108,44 @@ class Provider(QObject):
describe["icon"] describe["icon"]
) )
def default_val(): # Create dictionary of show episodes
return []
episodes: dict = getUrl(self.url, "episodes") episodes: dict = getUrl(self.url, "episodes")
_episodes: defaultdict[str, list[Episode]] = defaultdict(default_val) _episodes: defaultdict[str, list[Episode]] = defaultdict(lambda: [])
for e in episodes["episodes"]: for e in episodes["episodes"]:
_episodes[e["ShowTitle"]].append(Episode(e)) _episodes[e["ShowTitle"]].append(Episode(e))
shows: dict = getUrl(self.url, "shows") shows: dict = getUrl(self.url, "shows")
# Create image_cache directory
provider_data_dir: str = os.path.join(
data_dir, "image_cache", "providers", self._name
)
os.makedirs(provider_data_dir, exist_ok=True)
# Cache show posters
for s in shows["data"]:
# Get local cache path
poster_url: str = s["poster"]
poster_path: str = urllib.parse.urlparse(poster_url).path
poster_ext: str = os.path.splitext(poster_path)[1]
download_path: str = os.path.join(
provider_data_dir, str(s["id"]) + poster_ext
)
# Download poster
try:
with open(download_path, "xb") as f:
r = requests.get(poster_url, stream=True)
if r.status_code == 200:
r.raw.decode_content = True
shutil.copyfileobj(r.raw, f)
except FileExistsError:
pass
# Overwrite poster URL with local path
s["poster"] = download_path
self._shows: dict[int, Show] = { self._shows: dict[int, Show] = {
e["id"]: Show(e, _episodes[e["title"]]) for e in shows["data"] e["id"]: Show(e, _episodes[e["title"]]) for e in shows["data"]
} }
@@ -161,8 +188,8 @@ class Provider(QObject):
class DataSource: class DataSource:
def __init__(self, providers=[]): def __init__(self, providers: list[str], data_dir: str):
self.providers: list[Provider] = [Provider(url) for url in providers] self.providers: list[Provider] = [Provider(url, data_dir) for url in providers]
def DatabaseType(data_source) -> Type: def DatabaseType(data_source) -> Type:
@@ -204,6 +231,17 @@ def load_config() -> list[str]:
return [f'http://{b["address"]}:{b["port"]}/' for b in config["backends"]] return [f'http://{b["address"]}:{b["port"]}/' for b in config["backends"]]
def get_data_dir() -> str:
try:
data_dir: str = os.path.join(os.environ["XDG_DATA_HOME"], "ikinuki")
except:
data_dir: str = os.path.join(os.environ["HOME"], ".local", "share", "ikinuki")
os.makedirs(data_dir, exist_ok=True)
return data_dir
def main(): def main():
app = QApplication(sys.argv) app = QApplication(sys.argv)
@@ -218,7 +256,9 @@ def main():
print(f"ERROR: Could not load config file: {repr(e)}") print(f"ERROR: Could not load config file: {repr(e)}")
sys.exit(-1) sys.exit(-1)
data_source = DataSource(backends) data_dir: str = get_data_dir()
data_source = DataSource(backends, data_dir)
qmlRegisterType(DatabaseType(data_source), "Ikinuki.Client", 1, 0, "Database") qmlRegisterType(DatabaseType(data_source), "Ikinuki.Client", 1, 0, "Database")