Compare commits

...

3 commits

Author SHA1 Message Date
991fe3df30 Bump version: 0.3.1 → 0.3.2
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-29 23:26:04 +02:00
ca5062cced add daily cache cleanup 2022-06-29 23:25:43 +02:00
1f7140131f move db folder 2022-06-29 22:46:42 +02:00
8 changed files with 80 additions and 18 deletions

View file

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 0.3.1 current_version = 0.3.2
commit = True commit = True
tag = True tag = True

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "ucast" name = "ucast"
version = "0.3.1" version = "0.3.2"
description = "YouTube to Podcast converter" description = "YouTube to Podcast converter"
authors = ["Theta-Dev <t.testboy@gmail.com>"] authors = ["Theta-Dev <t.testboy@gmail.com>"]
packages = [ packages = [

View file

@ -1,4 +1,4 @@
__version__ = "0.3.1" __version__ = "0.3.2"
def template_context(request): def template_context(request):

View file

@ -1,5 +1,7 @@
import os import os
import shutil
import tempfile import tempfile
from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from django.conf import settings from django.conf import settings
@ -73,3 +75,18 @@ class Cache:
def create_tmpdir(self, prefix="dld") -> tempfile.TemporaryDirectory: def create_tmpdir(self, prefix="dld") -> tempfile.TemporaryDirectory:
return tempfile.TemporaryDirectory(prefix=prefix + "_", dir=self.dir_cache) return tempfile.TemporaryDirectory(prefix=prefix + "_", dir=self.dir_cache)
def cleanup(self):
"""
Delete temporary directories that are older than 24h and are most likely left
over after unexpected shutdowns.
"""
for dirname in os.listdir(self.dir_cache):
if dirname == "yt_dlp":
continue
ctime = os.path.getctime(dirname)
age = datetime.now() - datetime.fromtimestamp(ctime)
if age > timedelta(days=1):
shutil.rmtree(self.dir_cache / dirname)

View file

@ -105,3 +105,8 @@ def update_channel_info(channel: Channel):
def update_channel_infos(): def update_channel_infos():
for channel in Channel.objects.filter(active=True): for channel in Channel.objects.filter(active=True):
queue.enqueue(update_channel_info, channel) queue.enqueue(update_channel_info, channel)
def clean_cache():
cache = storage.Cache()
cache.cleanup()

View file

@ -1,5 +1,5 @@
import logging import logging
from datetime import datetime from datetime import datetime, timedelta
from django.conf import settings from django.conf import settings
@ -28,8 +28,15 @@ def register_scheduled_jobs():
) )
scheduler.schedule( scheduler.schedule(
datetime.utcnow(), datetime.utcnow() + timedelta(days=1),
library.update_channel_infos, library.update_channel_infos,
id="schedule_update_channel_infos", id="schedule_update_channel_infos",
interval=24 * 3600, interval=24 * 3600,
) )
scheduler.schedule(
datetime.utcnow() + timedelta(days=1),
library.clean_cache,
id="schedule_clean_cache",
interval=24 * 3600,
)

View file

@ -1,5 +1,6 @@
import os import os
import tempfile import tempfile
from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from ucast.service import storage from ucast.service import storage
@ -54,3 +55,30 @@ def test_channel_folder():
== ucast_dir / "thumbnails" / "my_video_title_sm.webp" == ucast_dir / "thumbnails" / "my_video_title_sm.webp"
) )
assert cf.get_audio("my_video_title") == tmpdir / "my_video_title.mp3" assert cf.get_audio("my_video_title") == tmpdir / "my_video_title.mp3"
def test_clean_cache(settings, mocker):
tmpdir_o = tempfile.TemporaryDirectory()
tmpdir = Path(tmpdir_o.name)
os.mkdir(tmpdir / "yt_dlp")
os.mkdir(tmpdir / "dld_old")
os.mkdir(tmpdir / "dld_new")
def mock_ctime(path):
if path == "dld_new":
return datetime.now().timestamp()
if path == "dld_old":
return (datetime.now() - timedelta(days=1, minutes=1)).timestamp()
raise Exception("invalid path")
mocker.patch.object(os.path, "getctime", mock_ctime)
settings.CACHE_ROOT = tmpdir
cache = storage.Cache()
cache.cleanup()
assert os.path.isdir(tmpdir / "yt_dlp")
assert os.path.isdir(tmpdir / "dld_new")
assert not os.path.exists(tmpdir / "dld_old")

View file

@ -32,8 +32,11 @@ def get_env(name, default=None):
def get_env_path(name, default=None): def get_env_path(name, default=None):
raw_env = get_env(name) raw_env = get_env(name)
if not raw_env: if not raw_env:
return default folder = default
return Path(raw_env).absolute() else:
folder = Path(raw_env).absolute()
os.makedirs(folder, exist_ok=True)
return folder
def get_env_list(name): def get_env_list(name):
@ -142,7 +145,7 @@ def _get_db_config() -> dict:
if db_engine == "sqlite": if db_engine == "sqlite":
return { return {
"ENGINE": "django.db.backends.sqlite3", "ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / f"{db_name}.sqlite", "NAME": DB_DIR / f"{db_name}.sqlite",
} }
db_port = get_env("DB_PORT") db_port = get_env("DB_PORT")
@ -162,6 +165,18 @@ def _get_db_config() -> dict:
} }
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = "static/"
STATIC_ROOT = get_env_path("STATIC_ROOT", BASE_DIR / "static")
DOWNLOAD_ROOT = get_env_path("DOWNLOAD_ROOT", BASE_DIR / "data")
CACHE_ROOT = get_env_path("CACHE_ROOT", BASE_DIR / "cache")
DB_DIR = get_env_path("DB_DIR", BASE_DIR / "db")
STATICFILES_DIRS = [resources.path("ucast", "static")]
# Database # Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases # https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = { DATABASES = {
@ -202,16 +217,6 @@ USE_I18N = True
USE_TZ = True USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = "static/"
STATIC_ROOT = get_env_path("STATIC_ROOT", BASE_DIR / "static")
DOWNLOAD_ROOT = get_env_path("DOWNLOAD_ROOT", BASE_DIR / "data")
CACHE_ROOT = get_env_path("CACHE_ROOT", BASE_DIR / "cache")
STATICFILES_DIRS = [resources.path("ucast", "static")]
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field