Compare commits
3 commits
297daaa51b
...
991fe3df30
Author | SHA1 | Date | |
---|---|---|---|
991fe3df30 | |||
ca5062cced | |||
1f7140131f |
8 changed files with 80 additions and 18 deletions
|
@ -1,5 +1,5 @@
|
||||||
[bumpversion]
|
[bumpversion]
|
||||||
current_version = 0.3.1
|
current_version = 0.3.2
|
||||||
commit = True
|
commit = True
|
||||||
tag = True
|
tag = True
|
||||||
|
|
||||||
|
|
|
@ -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 = [
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
__version__ = "0.3.1"
|
__version__ = "0.3.2"
|
||||||
|
|
||||||
|
|
||||||
def template_context(request):
|
def template_context(request):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue