WiP: more changes to classes to support Path

This commit is contained in:
arabcoders 2025-06-09 00:47:11 +03:00
parent 6a9beea89e
commit b1bc399a0c
6 changed files with 46 additions and 46 deletions

View file

@ -47,6 +47,7 @@ from .Utils import (
get_file_sidecar,
get_files,
get_mime_type,
init_class,
read_logfile,
validate_url,
validate_uuid,
@ -914,7 +915,7 @@ class HttpAPI(Common):
status=web.HTTPBadRequest.status_code,
)
items.append(Condition(**item))
items.append(init_class(Condition, item))
try:
items = cls.save(items=items).load().get_all()
except Exception as e:

View file

@ -6,6 +6,7 @@ import os
import shlex
import time
from datetime import UTC, datetime
from pathlib import Path
import anyio
import socketio
@ -289,13 +290,17 @@ class HttpSocket(Common):
manual_archive = self.config.manual_archive
if manual_archive:
manual_archive = Path(manual_archive)
if not manual_archive.exists():
manual_archive.touch(exist_ok=True)
previouslyArchived = False
if os.path.exists(manual_archive):
async with await anyio.open_file(manual_archive) as f:
async for line in f:
if idDict["archive_id"] in line:
previouslyArchived = True
break
async with await anyio.open_file(manual_archive) as f:
async for line in f:
if idDict["archive_id"] in line:
previouslyArchived = True
break
if not previouslyArchived:
async with await anyio.open_file(manual_archive, "a") as f:
@ -313,9 +318,7 @@ class HttpSocket(Common):
"paused": self.queue.is_paused(),
}
# get download folder listing.
downloadPath: str = self.config.download_path
data["folders"] = [name for name in os.listdir(downloadPath) if os.path.isdir(os.path.join(downloadPath, name))]
data["folders"] = [folder.name for folder in Path(self.config.download_path).iterdir() if folder.is_dir()]
await self._notify.emit(Events.INITIAL_DATA, data=data, to=sid)
@ -355,10 +358,11 @@ class HttpSocket(Common):
await self.subscribe_emit(event=event, data=data)
if "log_lines" == event and self.log_task is None:
LOG.debug("Starting log tailing task.")
log_file = Path(self.config.config_path) / "logs" / "app.log"
LOG.debug(f"Starting tailing '{log_file!s}'.")
self.log_task = asyncio.create_task(
tail_log(
file=os.path.join(self.config.config_path, "logs", "app.log"),
file=log_file,
emitter=emit_logs,
),
name="tail_log",

View file

@ -1,10 +1,10 @@
import asyncio
import json
import logging
import os
from collections.abc import Awaitable
from dataclasses import dataclass, field
from datetime import datetime
from pathlib import Path
from typing import Any
import httpx
@ -134,15 +134,15 @@ class Notification(metaclass=Singleton):
config: Config = config or Config.get_instance()
self._debug = config.debug
self._file: str = file or os.path.join(config.config_path, "notifications.json")
self._file: Path = Path(file) if file else (Path(config.config_path) / "notifications.json")
self._client: httpx.AsyncClient = client or httpx.AsyncClient()
self._encoder: Encoder = encoder or Encoder()
self._version = config.version
if os.path.exists(self._file):
if self._file.exists():
try:
if "600" != oct(os.stat(self._file).st_mode)[-3:]:
os.chmod(self._file, 0o600)
if "600" != self._file.stat().st_mode:
self._file.chmod(0o600)
except Exception:
pass
@ -184,34 +184,30 @@ class Notification(metaclass=Singleton):
Notification: The Notification instance.
"""
LOG.info(f"Saving notification targets to '{self._file}'.")
try:
with open(self._file, "w") as f:
json.dump([t.serialize() for t in targets], fp=f, indent=4)
self._file.write_text(json.dumps([t.serialize() for t in targets], indent=4))
LOG.info(f"Updated '{self._file}'.")
except Exception as e:
LOG.exception(e)
LOG.error(f"Error saving notification targets to '{self._file}'. '{e!s}'")
LOG.error(f"Error saving '{self._file}'. '{e!s}'")
return self
def load(self) -> "Notification":
"""Load or reload notification targets from the file."""
if len(self._targets) > 0:
LOG.info("Clearing existing notification targets.")
self.clear()
if not os.path.exists(self._file) or os.path.getsize(self._file) < 10:
if not self._file.exists() or self._file.stat().st_size < 1:
return self
targets = []
LOG.info(f"Loading notification targets from '{self._file}'.")
try:
with open(self._file) as f:
targets = json.load(f)
LOG.info(f"Loading '{self._file}'.")
targets = json.loads(self._file.read_text())
except Exception as e:
LOG.error(f"Error loading notification targets from '{self._file}'. '{e!s}'")
LOG.error(f"Error loading '{self._file}'. '{e!s}'")
for target in targets:
try:
@ -227,7 +223,7 @@ class Notification(metaclass=Singleton):
self._targets.append(target)
LOG.info(
f"Will send {target.request.type} request on '{', '.join(target.on) if len(target.on) > 0 else 'all events'}' to '{target.name}'."
f"Send '{target.request.type}' request on '{', '.join(target.on) if len(target.on) > 0 else 'all events'}' to '{target.name}'."
)
except Exception as e:
LOG.error(f"Error loading notification target '{target}'. '{e!s}'")

View file

@ -951,7 +951,7 @@ async def read_logfile(file: str, offset: int = 0, limit: int = 50) -> dict:
return {"logs": [], "next_offset": None, "end_is_reached": True}
async def tail_log(file: str, emitter: callable, sleep_time: float = 0.5):
async def tail_log(file: pathlib.Path, emitter: callable, sleep_time: float = 0.5):
"""
Continuously read a log file and emit new lines.
@ -966,7 +966,7 @@ async def tail_log(file: str, emitter: callable, sleep_time: float = 0.5):
from anyio import open_file
if not pathlib.Path(file).exists():
if not file.exists():
return
try:

View file

@ -11,7 +11,7 @@ from .config import Config
from .encoder import Encoder
from .Events import EventBus, Events
from .Singleton import Singleton
from .Utils import arg_converter
from .Utils import arg_converter, init_class
LOG = logging.getLogger("conditions")
@ -117,12 +117,12 @@ class Conditions(metaclass=Singleton):
if not self._file.exists() or self._file.stat().st_size < 1:
return self
LOG.info(f"Loading '{self._file}'.")
try:
with open(self._file) as f:
items = json.load(f)
LOG.info(f"Loading '{self._file}'.")
items = json.loads(self._file.read_text())
except Exception as e:
LOG.error(f"Failed to parse '{self._file}'. '{e}'.")
LOG.exception(e)
LOG.error(f"Error loading '{self._file}'. '{e}'.")
return self
if not items or len(items) < 1:
@ -137,15 +137,15 @@ class Conditions(metaclass=Singleton):
item["id"] = str(uuid.uuid4())
need_save = True
item = Condition(**item)
item: Condition = init_class(Condition, item)
self._items.append(item)
except Exception as e:
LOG.error(f"Failed to parse failure condition at list position '{i}'. '{e!s}'.")
LOG.error(f"Failed to parse condition at list position '{i}'. '{e!s}'.")
continue
if need_save:
LOG.info("Saving failure conditions due to format, or id change.")
LOG.info("Saving conditions due to format, or id change.")
self.save(self._items)
return self
@ -229,7 +229,7 @@ class Conditions(metaclass=Singleton):
for i, item in enumerate(items):
try:
if not isinstance(item, Condition):
item = Condition(**item)
item: Condition = init_class(Condition, item)
items[i] = item
except Exception as e:
LOG.error(f"Failed to save '{i}' due to parsing error. '{e!s}'.")
@ -242,12 +242,10 @@ class Conditions(metaclass=Singleton):
continue
try:
with open(self._file, "w") as f:
json.dump(obj=[item.serialize() for item in items], fp=f, indent=4)
self._file.write_text(json.dumps(obj=[item.serialize() for item in items], indent=4))
LOG.info(f"Updated '{self._file}'.")
except Exception as e:
LOG.error(f"Failed to save '{self._file}'. '{e!s}'.")
LOG.error(f"Error saving '{self._file}'. '{e!s}'.")
return self

View file

@ -7,6 +7,7 @@ import functools
import json
import operator
import os
from pathlib import Path
import anyio
@ -271,7 +272,7 @@ async def ffprobe(file: str) -> FFProbeResult:
msg = "ffprobe not found."
raise OSError(msg) from e
if not os.path.isfile(file):
if not Path(file).exists():
msg = f"No such media file '{file}'."
raise OSError(msg)
@ -290,7 +291,7 @@ async def ffprobe(file: str) -> FFProbeResult:
if 0 == exitCode:
parsed: dict = json.loads(data.decode("utf-8"))
else:
msg = f"FFProbe return with non-0 exit code. '{err.decode('utf-8')}'"
msg = f"ffprobe returned with non-0 exit code. '{err.decode('utf-8')}'"
raise FFProbeError(msg)
result = FFProbeResult()