refactor: use single logger namespace

This commit is contained in:
arabcoders 2026-05-28 19:07:11 +03:00
parent 39ed3d0361
commit 1267dbaf6b
85 changed files with 195 additions and 160 deletions

4
API.md
View file

@ -2318,7 +2318,7 @@ Binary image data with appropriate headers
"datetime": "2026-05-18T12:00:00.000+00:00",
"level": "error",
"levelno": 40,
"logger": "downloads.queue",
"logger": "ytptube",
"message": "Failed to download 'Example Video'.",
"exception": {
"type": "ValueError",
@ -2379,7 +2379,7 @@ Binary image data with appropriate headers
"datetime": "2026-05-18T12:00:00.000+00:00",
"level": "error",
"levelno": 40,
"logger": "downloads.queue",
"logger": "ytptube",
"message": "Failed to download 'Example Video'.",
"exception": {
"type": "ValueError",

View file

@ -1,18 +1,18 @@
from __future__ import annotations
import json
import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any, cast
from app.features.conditions.models import ConditionModel
from app.features.core.migration import Migration as FeatureMigration
from app.library.config import Config
from app.library.log import get_logger
if TYPE_CHECKING:
from app.features.conditions.repository import ConditionsRepository
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class Migration(FeatureMigration):

View file

@ -1,6 +1,5 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
from app.features.conditions.migration import Migration
@ -18,8 +17,9 @@ from sqlalchemy import delete, func, or_, select
from app.features.conditions.models import ConditionModel
from app.features.core.deps import get_session
from app.library.log import get_logger
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class ConditionsRepository(metaclass=Singleton):

View file

@ -1,5 +1,4 @@
import asyncio
import logging
from collections import OrderedDict
from typing import Any
@ -15,10 +14,11 @@ from app.library.cache import Cache
from app.library.config import Config
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.router import route
from app.library.Utils import validate_url
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
def _model(model: Any) -> Condition:

View file

@ -1,4 +1,3 @@
import logging
from collections.abc import Iterable
from numbers import Number
@ -8,9 +7,10 @@ from app.features.conditions.models import ConditionModel
from app.features.conditions.repository import ConditionsRepository
from app.features.ytdlp.mini_filter import match_str
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.Singleton import Singleton
LOG: logging.Logger = logging.getLogger("feature.conditions")
LOG = get_logger()
def _ignored_identifiers(ignore_conditions: Iterable[str | Number] | None) -> tuple[set[str], bool]:

View file

@ -1,15 +1,16 @@
from __future__ import annotations
import abc
import logging
import time
from pathlib import Path
from typing import TYPE_CHECKING
from app.library.log import get_logger
if TYPE_CHECKING:
from app.library.config import Config
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class Migration(abc.ABC):

View file

@ -1,18 +1,18 @@
from __future__ import annotations
import json
import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any, cast
from app.features.core.migration import Migration as FeatureMigration
from app.features.dl_fields.schemas import DLField
from app.library.config import Config
from app.library.log import get_logger
if TYPE_CHECKING:
from app.features.dl_fields.repository import DLFieldsRepository
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class Migration(FeatureMigration):

View file

@ -1,6 +1,5 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
from sqlalchemy import delete, func, or_, select
@ -8,6 +7,7 @@ from sqlalchemy import delete, func, or_, select
from app.features.core.deps import get_session
from app.features.dl_fields.migration import Migration
from app.features.dl_fields.models import DLFieldModel
from app.library.log import get_logger
from app.library.Singleton import Singleton
if TYPE_CHECKING:
@ -18,7 +18,7 @@ if TYPE_CHECKING:
from sqlalchemy.sql.elements import ColumnElement
from sqlalchemy.sql.selectable import Select
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class DLFieldsRepository(metaclass=Singleton):

View file

@ -1,4 +1,3 @@
import logging
from typing import Any
from aiohttp import web
@ -11,9 +10,10 @@ from app.features.dl_fields.schemas import DLField, DLFieldList, DLFieldPatch
from app.features.dl_fields.service import DLFields
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.router import route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
def _model(model: Any) -> DLField:

View file

@ -1,18 +1,18 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
from app.features.dl_fields.models import DLFieldModel
from app.features.dl_fields.repository import DLFieldsRepository
from app.features.dl_fields.schemas import DLField
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.Singleton import Singleton
if TYPE_CHECKING:
from aiohttp import web
LOG: logging.Logger = logging.getLogger("feature.dl_fields")
LOG = get_logger()
class DLFields(metaclass=Singleton):

View file

@ -1,7 +1,6 @@
from __future__ import annotations
import json
import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any, cast
@ -9,11 +8,12 @@ from app.features.core.migration import Migration as FeatureMigration
from app.features.notifications.schemas import NotificationEvents
from app.features.presets.service import Presets
from app.library.config import Config
from app.library.log import get_logger
if TYPE_CHECKING:
from app.features.notifications.repository import NotificationsRepository
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class Migration(FeatureMigration):

View file

@ -1,6 +1,5 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
from sqlalchemy import func, or_, select
@ -8,6 +7,7 @@ from sqlalchemy import func, or_, select
from app.features.core.deps import get_session
from app.features.notifications.migration import Migration
from app.features.notifications.models import NotificationModel
from app.library.log import get_logger
from app.library.Singleton import Singleton
if TYPE_CHECKING:
@ -18,7 +18,7 @@ if TYPE_CHECKING:
from sqlalchemy.sql.elements import ColumnElement
from sqlalchemy.sql.selectable import Select
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class NotificationsRepository(metaclass=Singleton):

View file

@ -1,4 +1,3 @@
import logging
from typing import Any
from aiohttp import web
@ -11,9 +10,10 @@ from app.features.notifications.schemas import Notification, NotificationEvents,
from app.features.notifications.service import Notifications
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.router import route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
def _model(model: Any) -> Notification:

View file

@ -1,7 +1,6 @@
from __future__ import annotations
import asyncio
import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any
@ -22,6 +21,7 @@ from app.library.encoder import Encoder
from app.library.Events import Event, EventBus, Events
from app.library.httpx_client import async_client
from app.library.ItemDTO import Item, ItemDTO
from app.library.log import get_logger
from app.library.Singleton import Singleton
if TYPE_CHECKING:
@ -30,7 +30,7 @@ if TYPE_CHECKING:
import httpx
from aiohttp import web
LOG: logging.Logger = logging.getLogger("feature.notifications")
LOG = get_logger()
class Notifications(metaclass=Singleton):

View file

@ -1,7 +1,6 @@
from __future__ import annotations
import json
import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any
@ -9,11 +8,12 @@ from app.features.core.migration import Migration as FeatureMigration
from app.features.presets.schemas import Preset
from app.features.presets.utils import preset_name
from app.library.config import Config
from app.library.log import get_logger
if TYPE_CHECKING:
from app.features.presets.repository import PresetsRepository
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class Migration(FeatureMigration):

View file

@ -1,6 +1,5 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
from sqlalchemy import func, or_, select
@ -12,6 +11,7 @@ from app.features.presets.models import PresetModel
from app.features.presets.utils import preset_name, seed_defaults
from app.library.config import Config
from app.library.Events import Event, EventBus, Events
from app.library.log import get_logger
from app.library.Services import Services
from app.library.Singleton import Singleton
@ -27,7 +27,7 @@ if TYPE_CHECKING:
SessionFactory = Callable[[], AbstractAsyncContextManager[AsyncSession]]
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class PresetsRepository(metaclass=Singleton):

View file

@ -1,10 +1,11 @@
import logging
import re
from datetime import UTC, datetime
from app.library.log import get_logger
NAME_WHITESPACE_PATTERN = re.compile(r"\s+")
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
async def seed_defaults(repo) -> None:

View file

@ -5,7 +5,6 @@ Python wrapper for ffprobe command line tool. ffprobe must exist in the path.
import asyncio
import functools
import json
import logging
import operator
import os
import subprocess # qa: ignore
@ -14,9 +13,10 @@ from pathlib import Path
import anyio
from app.features.streaming.types import FFProbeError
from app.library.log import get_logger
from app.library.Utils import timed_lru_cache
LOG: logging.Logger = logging.getLogger("streaming.ffprobe")
LOG = get_logger()
class FFStream:

View file

@ -1,5 +1,4 @@
import asyncio
import logging
import os
import subprocess # type: ignore
import sys
@ -19,6 +18,7 @@ from app.features.streaming.library.segment_encoders import (
select_encoder,
)
from app.library.config import SUPPORTED_CODECS, Config
from app.library.log import get_logger
if TYPE_CHECKING:
from asyncio.subprocess import Process
@ -26,7 +26,7 @@ if TYPE_CHECKING:
from .ffprobe import FFProbeResult
from .segment_encoders import EncoderBuilder
LOG: logging.Logger = logging.getLogger("player.segments")
LOG = get_logger()
class Segments:

View file

@ -1,6 +1,5 @@
from __future__ import annotations
import logging
from dataclasses import dataclass
from pathlib import Path
@ -9,9 +8,10 @@ import pysubs2
from pysubs2.formats.substation import SubstationFormat
from pysubs2.time import ms_to_times
from app.library.log import get_logger
from app.library.Utils import ALLOWED_SUBS_EXTENSIONS, get_file_sidecar
LOG: logging.Logger = logging.getLogger("player.subtitle")
LOG = get_logger()
SOURCE_FORMATS: tuple[str, ...] = ("vtt", "srt", "ass")
DELIVERY_FORMATS: dict[str, str] = {

View file

@ -1,7 +1,6 @@
from __future__ import annotations
import asyncio
import logging
import os
import subprocess
from pathlib import Path
@ -9,9 +8,10 @@ from pathlib import Path
from app.features.streaming.library.ffprobe import ffprobe
from app.library.cache import Cache
from app.library.config import Config
from app.library.log import get_logger
from app.library.Utils import FILES_TYPE, get_file_sidecar
LOG: logging.Logger = logging.getLogger("player.thumbnail")
LOG = get_logger()
IMAGE_TYPES: tuple[str, ...] = (".jpg", ".jpeg", ".png", ".webp")
FOLDER_IMAGE_ORDER: tuple[str, ...] = ("thumbnail", "poster", "artwork", "cover", "fanart")

View file

@ -1,4 +1,3 @@
import logging
import time
from datetime import UTC, datetime
from pathlib import Path
@ -12,10 +11,11 @@ from app.features.streaming.library.segments import Segments
from app.features.streaming.library.subtitle import Subtitle, get_subtitle_tracks
from app.features.streaming.types import StreamingError
from app.library.config import Config
from app.library.log import get_logger
from app.library.router import route
from app.library.Utils import get_file
LOG: logging.Logger = logging.getLogger("streaming")
LOG = get_logger()
@route("GET", "api/player/playlist/{file:.*}.m3u8", "playlist_create")

View file

@ -255,7 +255,7 @@ async def test_stream_gpu_fallback(
# Encourage GPU preference
seg.vcodec = "" # empty -> try GPUs first
resp = _FakeResp()
with caplog.at_level(logging.WARNING, logger="player.segments"):
with caplog.at_level(logging.WARNING, logger="ytptube"):
await seg.stream(tmp_path / "file.mp4", resp)
# Ensure fallback path streamed data

View file

@ -6,7 +6,6 @@ import asyncio
import fnmatch
import hashlib
import json
import logging
import re
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any
@ -26,6 +25,7 @@ from app.features.ytdlp.utils import get_archive_id
from app.library.cache import Cache
from app.library.config import Config
from app.library.httpx_client import Globals, build_request_headers, get_async_client, resolve_curl_transport
from app.library.log import get_logger
from ._base_handler import BaseHandler
@ -34,7 +34,7 @@ if TYPE_CHECKING:
from parsel.selector import SelectorList
LOG: logging.Logger = logging.getLogger("handlers.generic")
LOG = get_logger()
CACHE: Cache = Cache()

View file

@ -1,5 +1,4 @@
import hashlib
import logging
import re
from typing import TYPE_CHECKING, Any
from xml.etree.ElementTree import Element
@ -10,13 +9,14 @@ from app.features.tasks.definitions.results import HandleTask, TaskFailure, Task
from app.features.ytdlp.extractor import fetch_info
from app.features.ytdlp.utils import get_archive_id
from app.library.cache import Cache
from app.library.log import get_logger
from ._base_handler import BaseHandler
if TYPE_CHECKING:
from xml.etree.ElementTree import Element
LOG: logging.Logger = logging.getLogger("handlers.rss")
LOG = get_logger()
CACHE: Cache = Cache()

View file

@ -1,14 +1,14 @@
import logging
import re
import httpx
from app.features.tasks.definitions.results import HandleTask, TaskFailure, TaskItem, TaskResult
from app.features.ytdlp.utils import get_archive_id
from app.library.log import get_logger
from ._base_handler import BaseHandler
LOG: logging.Logger = logging.getLogger("handlers.tver")
LOG = get_logger()
class TverHandler(BaseHandler):

View file

@ -1,4 +1,3 @@
import logging
import re
from typing import TYPE_CHECKING
from xml.etree.ElementTree import Element
@ -7,13 +6,14 @@ import httpx
from app.features.tasks.definitions.results import HandleTask, TaskFailure, TaskItem, TaskResult
from app.features.ytdlp.utils import get_archive_id
from app.library.log import get_logger
from ._base_handler import BaseHandler
if TYPE_CHECKING:
from xml.etree.ElementTree import Element
LOG: logging.Logger = logging.getLogger("handlers.twitch")
LOG = get_logger()
class TwitchHandler(BaseHandler):

View file

@ -1,4 +1,3 @@
import logging
import re
from typing import TYPE_CHECKING, Any
from xml.etree.ElementTree import Element
@ -7,13 +6,14 @@ import httpx
from app.features.tasks.definitions.results import HandleTask, TaskFailure, TaskItem, TaskResult
from app.features.ytdlp.utils import get_archive_id
from app.library.log import get_logger
from ._base_handler import BaseHandler
if TYPE_CHECKING:
from xml.etree.ElementTree import Element
LOG: logging.Logger = logging.getLogger("handlers.youtube")
LOG = get_logger()
class YoutubeHandler(BaseHandler):

View file

@ -1,17 +1,17 @@
from __future__ import annotations
import json
import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any
from app.features.core.migration import Migration as FeatureMigration
from app.library.config import Config
from app.library.log import get_logger
if TYPE_CHECKING:
from app.features.tasks.definitions.repository import TaskDefinitionsRepository
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class Migration(FeatureMigration):

View file

@ -1,6 +1,5 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
from sqlalchemy import func, or_, select
@ -10,6 +9,7 @@ from app.features.core.schemas import CEFeature, ConfigEvent
from app.features.tasks.definitions.migration import Migration
from app.features.tasks.definitions.models import TaskDefinitionModel
from app.library.Events import Event, EventBus, Events
from app.library.log import get_logger
from app.library.Services import Services
from app.library.Singleton import Singleton
@ -21,7 +21,7 @@ if TYPE_CHECKING:
from sqlalchemy.sql.elements import ColumnElement
from sqlalchemy.sql.selectable import Select
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class TaskDefinitionsRepository(metaclass=Singleton):

View file

@ -1,4 +1,3 @@
import logging
from typing import Any
from aiohttp import web
@ -16,9 +15,10 @@ from app.features.tasks.definitions.schemas import (
from app.features.tasks.definitions.utils import model_to_schema, schema_to_payload
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.router import route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
@route("GET", "api/tasks/definitions/", "task_definitions")

View file

@ -3,7 +3,6 @@ from __future__ import annotations
import asyncio
import importlib
import inspect
import logging
import pkgutil
import random
from datetime import UTC, datetime
@ -15,6 +14,7 @@ from app.features.ytdlp.utils import archive_read
from app.library.downloads.queue_manager import DownloadQueue
from app.library.Events import EventBus, Events
from app.library.ItemDTO import Item, ItemDTO
from app.library.log import get_logger
from app.library.Services import Services
if TYPE_CHECKING:
@ -22,7 +22,7 @@ if TYPE_CHECKING:
from app.library.config import Config
from app.library.Scheduler import Scheduler
LOG: logging.Logger = logging.getLogger("definitions.service")
LOG = get_logger()
class TaskHandle:

View file

@ -1,18 +1,18 @@
from __future__ import annotations
import json
import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any
from app.features.core.migration import Migration as FeatureMigration
from app.features.tasks.schemas import Task
from app.library.config import Config
from app.library.log import get_logger
if TYPE_CHECKING:
from app.features.tasks.repository import TasksRepository
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class Migration(FeatureMigration):

View file

@ -1,12 +1,12 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
from sqlalchemy import func, or_, select
from app.features.core.deps import get_session
from app.features.tasks.models import TaskModel
from app.library.log import get_logger
from app.library.Singleton import Singleton
if TYPE_CHECKING:
@ -17,7 +17,7 @@ if TYPE_CHECKING:
from sqlalchemy.sql.elements import ColumnElement
from sqlalchemy.sql.selectable import Select
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
class TasksRepository(metaclass=Singleton):

View file

@ -1,5 +1,4 @@
import asyncio
import logging
from typing import TYPE_CHECKING, Any
from aiohttp import web
@ -18,6 +17,7 @@ from app.library.ag_utils import ag
from app.library.config import Config
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.router import route
from app.library.Utils import get_channel_images, get_file, validate_url
@ -25,7 +25,7 @@ if TYPE_CHECKING:
from pathlib import Path
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
TIMER_SLOTS_PER_HOUR: int = 12

View file

@ -1,12 +1,12 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from app.features.core.schemas import CEAction, CEFeature, ConfigEvent
from app.features.tasks.models import TaskModel
from app.features.tasks.utils import cron_time
from app.library.Events import Event, EventBus, Events
from app.library.log import get_logger
from app.library.Scheduler import Scheduler
from app.library.Services import Services
from app.library.Singleton import Singleton
@ -14,7 +14,7 @@ from app.library.Singleton import Singleton
if TYPE_CHECKING:
from aiohttp import web
LOG: logging.Logger = logging.getLogger("tasks.service")
LOG = get_logger()
class Tasks(metaclass=Singleton):

View file

@ -1,6 +1,6 @@
import logging
from app.library.log import get_logger
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
def cron_time(timer: str) -> str:

View file

@ -1,12 +1,12 @@
import logging
import os
import threading
import time
from pathlib import Path
from app.library.log import get_logger
from app.library.Singleton import ThreadSafe
LOG: logging.Logger = logging.getLogger("Archiver")
LOG = get_logger()
class _Entry:

View file

@ -12,10 +12,11 @@ from aiohttp import web
from app.features.ytdlp.utils import _DATA, LogWrapper, get_archive_id
from app.features.ytdlp.ytdlp import YTDLP
from app.library.log import get_logger
from app.library.Services import Services
from app.library.Singleton import Singleton
LOG: logging.Logger = logging.getLogger("downloads.extractor")
LOG = get_logger()
LIVE_REEXTRACT_STATUSES: set[str] = {"is_live", "post_live"}
REEXTRACT_INFO_KEY = "_ytptube_reextract"

View file

@ -1,9 +1,10 @@
import logging
import subprocess
import sys
from typing import Any
LOG: logging.Logger = logging.getLogger("ytdlp.utils")
from app.library.log import get_logger
LOG = get_logger()
def patch_metadataparser() -> None:

View file

@ -18,10 +18,11 @@ from app.library.cache import Cache
from app.library.config import Config
from app.library.encoder import Encoder
from app.library.ItemDTO import Item
from app.library.log import get_logger
from app.library.router import route
from app.library.Utils import validate_url
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
def _get_preset_archive(preset: str) -> str | None:

View file

@ -11,9 +11,10 @@ from typing import Any
from app.features.ytdlp.patches import apply_ytdlp_patches
from app.features.ytdlp.ytdlp import YTDLP
from app.library.log import get_logger
from app.library.Utils import merge_dict, timed_lru_cache
LOG: logging.Logger = logging.getLogger("ytdlp.utils")
LOG = get_logger()
class _DATA:

View file

@ -1,5 +1,4 @@
# flake8: noqa: F401, RUF100, W291, I001
import logging
import sys
from typing import Any
@ -10,6 +9,7 @@ from yt_dlp.utils import make_archive_id
from app.features.ytdlp.outtmpl import rewrite_outtmpl
from app.features.ytdlp.patches import apply_ytdlp_patches
from app.library.cf_solver_handler import set_cf_handler
from app.library.log import get_logger
class _ArchiveProxy:
@ -67,7 +67,7 @@ class YTDLP(yt_dlp.YoutubeDL):
postprocessors.value.update({"NFOMakerPP": NFOMakerPP})
YTDLP._registered = True
except Exception:
logging.getLogger("ytdlp.wrapper").exception("Failed to register yt-dlp plugins")
get_logger().exception("Failed to register yt-dlp plugins")
# Avoid yt-dlp preloading the archive file by stripping the param first
orig_file = None

View file

@ -1,4 +1,3 @@
import logging
import shlex
from pathlib import Path
from typing import Any
@ -6,9 +5,10 @@ from typing import Any
from app.features.presets.schemas import Preset
from app.features.ytdlp.utils import arg_converter
from app.library.config import Config
from app.library.log import get_logger
from app.library.Utils import calc_download_path, create_cookies_file, merge_dict
LOG: logging.Logger = logging.getLogger("ytdlp.ytdlp_opts")
LOG = get_logger()
class ARGSMerger:

View file

@ -1,15 +1,16 @@
import asyncio
import inspect
import logging
import threading
from queue import Empty, Queue
from aiohttp import web
from app.library.log import get_logger
from .Services import Services
from .Singleton import Singleton
LOG: logging.Logger = logging.getLogger("BackgroundWorker")
LOG = get_logger()
class CloseThread:

View file

@ -1,15 +1,16 @@
import copy
import logging
from collections import OrderedDict
from collections.abc import Iterable
from enum import Enum
from app.library.log import get_logger
from .downloads import Download
from .ItemDTO import ItemDTO
from .operations import matches_condition
from .sqlite_store import SqliteStore
LOG = logging.getLogger("datastore")
LOG = get_logger()
class StoreType(str, Enum):

View file

@ -1,16 +1,16 @@
import asyncio
import datetime
import logging
from collections.abc import Callable
from dataclasses import dataclass, field
from typing import Any
from app.features.core.utils import gen_random
from app.library.log import get_logger
from .BackgroundWorker import BackgroundWorker
from .Singleton import Singleton
LOG: logging.Logger = logging.getLogger("events")
LOG = get_logger()
class Events:

View file

@ -1,7 +1,6 @@
import base64
import hmac
import inspect
import logging
from collections.abc import Awaitable
from datetime import UTC, datetime, timedelta
from pathlib import Path
@ -10,6 +9,7 @@ import anyio
from aiohttp import web
from aiohttp.web import Request, RequestHandler, Response
from app.library.log import get_logger
from app.library.Services import Services
from .cache import Cache
@ -19,7 +19,7 @@ from .Events import EventBus
from .router import RouteType, get_routes
from .Utils import decrypt_data, encrypt_data, get_file, load_modules
LOG: logging.Logger = logging.getLogger("http_api")
LOG = get_logger("http")
class HttpAPI:

View file

@ -1,13 +1,13 @@
import asyncio
import functools
import json
import logging
from pathlib import Path
from typing import Any
from aiohttp import web
from app.features.core.utils import gen_random
from app.library.log import get_logger
from app.library.router import Route, RouteType, get_routes
from app.library.Services import Services
from app.library.Utils import load_modules
@ -17,7 +17,7 @@ from .encoder import Encoder
from .Events import Event, EventBus, Events
from .ItemDTO import Item
LOG: logging.Logger = logging.getLogger("socket_api")
LOG = get_logger()
class WebSocketHub:

View file

@ -1,4 +1,3 @@
import logging
import re
import time
import uuid
@ -10,12 +9,13 @@ from typing import TYPE_CHECKING, Any
from app.features.ytdlp.utils import archive_add, archive_delete, archive_read, get_archive_id
from app.features.ytdlp.ytdlp_opts import YTDLPOpts
from app.library.encoder import Encoder
from app.library.log import get_logger
from app.library.Utils import clean_item, get_file, get_file_sidecar
if TYPE_CHECKING:
from app.features.presets.schemas import Preset
LOG: logging.Logger = logging.getLogger("ItemDTO")
LOG = get_logger()
@dataclass(kw_only=True)

View file

@ -1,14 +1,15 @@
import importlib
import importlib.metadata
import logging
import os
import subprocess
import sys
from pathlib import Path
from app.library.log import get_logger
from .httpx_client import sync_client
LOG: logging.Logger = logging.getLogger("package_installer")
LOG = get_logger()
def parse_version(v: str) -> tuple[int, ...]:

View file

@ -1,13 +1,14 @@
import asyncio
import logging
from aiocron import Cron
from aiohttp import web
from app.library.log import get_logger
from .Events import EventBus, Events
from .Singleton import Singleton
LOG = logging.getLogger("scheduler")
LOG = get_logger()
class Scheduler(metaclass=Singleton):

View file

@ -1,12 +1,12 @@
import inspect
import logging
from dataclasses import dataclass
from typing import Annotated, Any, TypeVar, get_args, get_origin, get_type_hints
from app.library.log import get_logger
from app.library.Singleton import Singleton
T = TypeVar("T")
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
def _unwrap_annotation(ann: Any) -> Any:

View file

@ -3,7 +3,6 @@ from __future__ import annotations
import asyncio
import errno
import json
import logging
import os
import shlex
import shutil
@ -16,6 +15,7 @@ from typing import TYPE_CHECKING, Any
from aiohttp import web
from app.library.config import Config
from app.library.log import get_logger
from app.library.Scheduler import Scheduler
from app.library.Services import Services
from app.library.Singleton import Singleton
@ -26,7 +26,7 @@ if TYPE_CHECKING:
from aiohttp.web import Request
LOG: logging.Logger = logging.getLogger("terminal_manager")
LOG = get_logger()
ACTIVE_FILE_NAME = "active.json"
METADATA_FILE_NAME = "metadata.json"

View file

@ -1,10 +1,11 @@
import asyncio
import logging
import re
from typing import Any
from aiohttp import web
from app.library.log import get_logger
from .cache import Cache
from .config import Config
from .Events import EventBus, Events
@ -13,7 +14,7 @@ from .Scheduler import Scheduler
from .Singleton import Singleton
from .version import APP_VERSION
LOG: logging.Logger = logging.getLogger("update_checker")
LOG = get_logger()
class UpdateChecker(metaclass=Singleton):

View file

@ -18,7 +18,9 @@ from typing import Any
from Crypto.Cipher import AES
LOG: logging.Logger = logging.getLogger("Utils")
from app.library.log import get_logger
LOG = get_logger()
ALLOWED_SUBS_EXTENSIONS: set[str] = {".srt", ".vtt", ".ass"}
"Allowed subtitle file extensions."

View file

@ -1,17 +1,17 @@
import hashlib
import logging
import threading
import time
from typing import Any
from aiohttp import web
from app.library.log import get_logger
from app.library.Services import Services
from .Scheduler import Scheduler
from .Singleton import ThreadSafe
LOG = logging.getLogger("cache")
LOG = get_logger()
class Cache(metaclass=ThreadSafe):

View file

@ -1,7 +1,6 @@
from __future__ import annotations
import http.cookiejar
import logging
from abc import ABC
from collections.abc import Callable
from typing import Any, ClassVar
@ -20,8 +19,9 @@ from yt_dlp.networking.exceptions import HTTPError
from yt_dlp.utils.networking import clean_headers
from app.library.cf_solver_shared import CACHE, is_cf_challenge, solver
from app.library.log import get_logger
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
SolverFn = Callable[[Request, Response, RequestHandler], Request | None]

View file

@ -2,16 +2,17 @@
from __future__ import annotations
import json
import logging
import time
import urllib.request
from typing import Any
from urllib.parse import urlparse
from app.library.log import get_logger
from .cache import Cache
CACHE: Cache = Cache()
LOG: logging.Logger = logging.getLogger("cf_solver")
LOG = get_logger()
def solver(url: str, cookies: list[dict[str, Any]], user_agent: str | None) -> dict[str, Any] | None:

View file

@ -12,6 +12,8 @@ from typing import TYPE_CHECKING, Any
import coloredlogs
from dotenv import load_dotenv
from app.library.log import get_logger
from .Singleton import Singleton
from .Utils import JsonLogFormatter
from .version import APP_BRANCH, APP_BUILD_DATE, APP_COMMIT_SHA, APP_VERSION
@ -430,7 +432,7 @@ class Config(metaclass=Singleton):
encoding="utf-8",
)
LOG: logging.Logger = logging.getLogger("config")
LOG = get_logger()
if self.debug:
try:

View file

@ -19,6 +19,7 @@ from app.features.ytdlp.utils import extract_ytdlp_logs
from app.features.ytdlp.ytdlp import YTDLP
from app.library.config import Config
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.Utils import create_cookies_file
from ...features.ytdlp.extractor import REEXTRACT_INFO_KEY, extract_info_sync
@ -64,7 +65,7 @@ class Download:
self.max_workers = int(config.max_workers)
self.is_live: bool = bool(info.is_live) or info.live_in is not None
self.info_dict: dict | None = info_dict
self.logger: logging.Logger = logging.getLogger(f"Download.{info.id or info._id}")
self.logger: logging.Logger = get_logger()
self.started_time = 0
self.queue_time: datetime = datetime.now(tz=UTC)
self.logs: list[str] = logs or []

View file

@ -14,6 +14,7 @@ from app.features.ytdlp.extractor import fetch_info
from app.features.ytdlp.utils import archive_add, archive_read, arg_converter, get_extras, ytdlp_reject
from app.library.Events import Events
from app.library.ItemDTO import ItemDTO
from app.library.log import get_logger
from app.library.Utils import create_cookies_file, merge_dict
from .core import Download
@ -26,7 +27,7 @@ if TYPE_CHECKING:
from .queue_manager import DownloadQueue
LOG: logging.Logger = logging.getLogger("downloads.add")
LOG = get_logger()
def _get_ignored_conditions(extras: dict | None) -> list[str]:

View file

@ -1,6 +1,5 @@
"""Queue monitoring functions."""
import logging
from datetime import UTC, datetime, timedelta
from pathlib import Path
from typing import TYPE_CHECKING
@ -8,12 +7,13 @@ from typing import TYPE_CHECKING
from app.library.ag_utils import ag
from app.library.Events import Events
from app.library.ItemDTO import Item, ItemDTO
from app.library.log import get_logger
from app.library.Utils import dt_delta, str_to_dt
if TYPE_CHECKING:
from .queue_manager import DownloadQueue
LOG: logging.Logger = logging.getLogger("downloads.monitors")
LOG = get_logger()
async def check_for_stale(queue: "DownloadQueue") -> None:

View file

@ -1,9 +1,9 @@
"""Playlist processing."""
import logging
from typing import TYPE_CHECKING, Any
from app.features.ytdlp.utils import ytdlp_reject
from app.library.log import get_logger
from app.library.Utils import merge_dict
if TYPE_CHECKING:
@ -11,7 +11,7 @@ if TYPE_CHECKING:
from .queue_manager import DownloadQueue
LOG: logging.Logger = logging.getLogger("downloads.playlist")
LOG = get_logger()
async def process_playlist(

View file

@ -1,10 +1,10 @@
"""Download pool management - worker coordination and execution."""
import asyncio
import logging
from typing import TYPE_CHECKING
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.Utils import calc_download_path
from .core import Download
@ -15,7 +15,7 @@ if TYPE_CHECKING:
from .queue_manager import DownloadQueue
LOG: logging.Logger = logging.getLogger("downloads.pool")
LOG = get_logger()
class PoolManager:

View file

@ -1,6 +1,5 @@
import functools
import glob
import logging
from datetime import UTC, datetime
from pathlib import Path
from typing import TYPE_CHECKING
@ -10,6 +9,7 @@ from aiohttp import web
from app.library.config import Config
from app.library.Events import EventBus, Events
from app.library.ItemDTO import Item, ItemDTO
from app.library.log import get_logger
from app.library.Scheduler import Scheduler
from app.library.Services import Services
from app.library.Singleton import Singleton
@ -24,7 +24,7 @@ from .pool_manager import PoolManager
if TYPE_CHECKING:
from app.library.DataStore import StoreType
LOG: logging.Logger = logging.getLogger("downloads.queue")
LOG = get_logger()
class DownloadQueue(metaclass=Singleton):

View file

@ -1,6 +1,5 @@
"""Video entry processing."""
import logging
import time
from datetime import UTC, datetime, timedelta
from email.utils import formatdate
@ -11,6 +10,7 @@ from app.features.ytdlp.utils import extract_ytdlp_logs, get_extras
from app.library.downloads import Download
from app.library.Events import Events
from app.library.ItemDTO import ItemDTO
from app.library.log import get_logger
from app.library.Utils import calc_download_path, merge_dict, str_to_dt
if TYPE_CHECKING:
@ -18,7 +18,7 @@ if TYPE_CHECKING:
from .queue_manager import DownloadQueue
LOG: logging.Logger = logging.getLogger("downloads.video")
LOG = get_logger()
async def add_video(queue: "DownloadQueue", entry: dict, item: "Item", logs: list[str] | None = None) -> dict[str, str]:

View file

@ -2,13 +2,14 @@ from __future__ import annotations
import asyncio
import functools
import logging
import threading
from dataclasses import dataclass
from typing import Any, Literal, cast, overload
import httpx
from app.library.log import get_logger
from .cf_solver_shared import is_cf_challenge, solver
__all__: list[str] = [
@ -21,7 +22,7 @@ __all__: list[str] = [
"sync_client",
]
LOG: logging.Logger = logging.getLogger("httpx_cf")
LOG = get_logger()
class Globals:

13
app/library/log.py Normal file
View file

@ -0,0 +1,13 @@
from __future__ import annotations
import logging
from typing import Literal
APP_LOGGER_NAME = "ytptube"
HTTP_LOGGER_NAME = "http_api"
LoggerKind = Literal["app", "http"]
def get_logger(kind: LoggerKind = "app") -> logging.Logger:
return logging.getLogger(HTTP_LOGGER_NAME if kind == "http" else APP_LOGGER_NAME)

View file

@ -1,11 +1,12 @@
import logging
import re
from collections.abc import Awaitable, Callable
from enum import Enum
from functools import wraps
from typing import Any
LOG: logging.Logger = logging.getLogger(__name__)
from app.library.log import get_logger
LOG = get_logger()
# make a enum for route types

View file

@ -1,7 +1,6 @@
import asyncio
import contextlib
import json
import logging
import os
from collections.abc import Iterable
from dataclasses import fields
@ -14,6 +13,8 @@ from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.ext.asyncio.engine import AsyncConnection
from app.library.log import get_logger
from .Events import EventBus, Events
from .ItemDTO import ItemDTO
from .operations import Operation, matches_condition
@ -21,7 +22,7 @@ from .Services import Services
from .Singleton import ThreadSafe
from .Utils import init_class
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
ITEM_DTO_FIELDS: set[str] = {f.name for f in fields(ItemDTO)}

View file

@ -33,13 +33,14 @@ from app.library.Events import EventBus, Events
from app.library.HttpAPI import HttpAPI
from app.library.HttpSocket import HttpSocket
from app.library.httpx_client import close_shared_clients
from app.library.log import get_logger
from app.library.Scheduler import Scheduler
from app.library.Services import Services
from app.library.sqlite_store import SqliteStore
from app.library.TerminalSessionManager import TerminalSessionManager
from app.library.UpdateChecker import UpdateChecker
LOG = logging.getLogger("app")
LOG = get_logger()
MIME = magic.Magic(mime=True)
ROOT_PATH: Path = Path(__file__).parent.absolute()

View file

@ -1,4 +1,3 @@
import logging
from pathlib import Path, PurePosixPath
import magic
@ -6,11 +5,12 @@ from aiohttp import web
from aiohttp.web import Request, StreamResponse
from app.library.config import Config
from app.library.log import get_logger
from app.library.router import add_route
from app.library.Utils import get_file
MIME = magic.Magic(mime=True)
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
EXT_TO_MIME: dict[str, str] = {
".html": "text/html",

View file

@ -1,5 +1,4 @@
import asyncio
import logging
from pathlib import Path
from typing import Any
from urllib.parse import unquote_plus
@ -14,10 +13,11 @@ from app.library.config import Config
from app.library.downloads import DownloadQueue
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.router import route
from app.library.Utils import delete_dir, get_file, get_file_sidecar, get_files, get_mime_type, move_file, rename_file
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
@route("GET", "api/file/ffprobe/{file:.*}", "ffprobe")

View file

@ -1,14 +1,14 @@
import asyncio
import logging
from aiohttp import web
from aiohttp.web import Response
from app.library.config import Config
from app.library.encoder import Encoder
from app.library.log import get_logger
from app.library.router import route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
@route("GET", "api/dev/loop/", "debug_loop")

View file

@ -1,4 +1,3 @@
import logging
import time
from datetime import UTC, datetime
@ -9,9 +8,10 @@ from app.features.ytdlp.ytdlp_opts import YTDLPOpts
from app.library.cache import Cache
from app.library.config import Config
from app.library.httpx_client import Globals, build_request_headers, get_async_client, resolve_curl_transport
from app.library.log import get_logger
from app.library.router import add_route, route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
STATIC_FILES = ["README.md", "FAQ.md", "API.md", "sc_short.jpg", "sc_simple.jpg"]
EXT_TO_MIME: dict = {

View file

@ -1,13 +1,12 @@
import logging
from aiohttp import web
from aiohttp.web import Request, Response
from app.library.config import Config
from app.library.log import get_logger
from app.library.router import route
from app.library.Utils import get_file
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
@route(["GET", "HEAD"], "/api/download/{filename:.+}", "download_static")

View file

@ -1,5 +1,4 @@
import asyncio
import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any
@ -17,6 +16,7 @@ from app.library.downloads.utils import safe_relative_path
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.ItemDTO import Item
from app.library.log import get_logger
from app.library.router import route
from app.library.Utils import calc_download_path, get_file_sidecar, rename_file
@ -24,7 +24,7 @@ if TYPE_CHECKING:
from library.downloads import Download
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
@route("GET", r"api/history/", "items_list")

View file

@ -1,4 +1,3 @@
import logging
import random
from typing import Any
from urllib.parse import urlparse, urlsplit, urlunsplit
@ -11,9 +10,10 @@ from app.library.ag_utils import ag
from app.library.cache import Cache
from app.library.config import Config
from app.library.httpx_client import Globals, build_request_headers, get_async_client, resolve_curl_transport
from app.library.log import get_logger
from app.library.router import route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
IS_REQUESTING_BACKGROUND: bool = False

View file

@ -1,6 +1,5 @@
import asyncio
import json
import logging
import os
from pathlib import Path
@ -9,9 +8,10 @@ from aiohttp.web import Request, Response
from app.library.config import Config
from app.library.encoder import Encoder
from app.library.log import get_logger
from app.library.router import route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
def _parse_jsonl_line(line: bytes | str) -> dict | None:

View file

@ -1,5 +1,4 @@
import asyncio
import logging
import os
import time
from pathlib import Path
@ -17,12 +16,13 @@ from app.library.downloads import DownloadQueue
from app.library.downloads.core import Download
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.router import route
from app.library.TerminalSessionManager import TerminalSessionConflictError, TerminalSessionManager
from app.library.UpdateChecker import UpdateChecker
from app.library.Utils import list_folders
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
DIAGNOSTICS_CACHE_KEY = "system:diagnostics"
DIAGNOSTICS_CACHE_TTL = 5.0

View file

@ -1,9 +1,8 @@
import logging
from app.library.Events import EventBus, Events
from app.library.log import get_logger
from app.library.router import RouteType, route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
@route(RouteType.SOCKET, "connect", "socket_connect")

View file

@ -1,11 +1,10 @@
import logging
from app.library.downloads import DownloadQueue
from app.library.Events import EventBus, Events
from app.library.ItemDTO import Item
from app.library.log import get_logger
from app.library.router import RouteType, route
LOG: logging.Logger = logging.getLogger(__name__)
LOG = get_logger()
@route(RouteType.SOCKET, "add_url", "add_url")

View file

@ -23,11 +23,12 @@ if APP_ROOT not in sys.path:
from app.library.DataStore import StoreType
from app.library.encoder import Encoder
from app.library.log import get_logger
if TYPE_CHECKING:
from collections.abc import Iterable, Iterator, Sequence
LOG = logging.getLogger("seed_db")
LOG = get_logger()
USED_IDS: set[str] = set()

View file

@ -12,7 +12,9 @@ from pathlib import Path
from library.PackageInstaller import PackageInstaller, Packages
LOG: logging.Logger = logging.getLogger("upgrader")
from app.library.log import get_logger
LOG = get_logger()
class Upgrader: