mirror of https://github.com/devine-dl/devine.git
Move --log from the dl cmd to the root cmd
This commit is contained in:
parent
4f1cff681c
commit
c6976a7112
|
@ -10,11 +10,9 @@ import shutil
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from collections import defaultdict
|
|
||||||
from concurrent import futures
|
from concurrent import futures
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from datetime import datetime
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from http.cookiejar import MozillaCookieJar
|
from http.cookiejar import MozillaCookieJar
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -32,7 +30,7 @@ from pywidevine.remotecdm import RemoteCdm
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from devine.core.config import config
|
from devine.core.config import config
|
||||||
from devine.core.constants import LOG_FORMATTER, AnyTrack, context_settings
|
from devine.core.constants import AnyTrack, context_settings
|
||||||
from devine.core.credential import Credential
|
from devine.core.credential import Credential
|
||||||
from devine.core.downloaders import aria2c
|
from devine.core.downloaders import aria2c
|
||||||
from devine.core.drm import DRM_T, Widevine
|
from devine.core.drm import DRM_T, Widevine
|
||||||
|
@ -120,8 +118,6 @@ class dl:
|
||||||
help="Disable the source tag from the output file name and path.")
|
help="Disable the source tag from the output file name and path.")
|
||||||
@click.option("--workers", type=int, default=1,
|
@click.option("--workers", type=int, default=1,
|
||||||
help="Max concurrent workers to use throughout the code, particularly downloads.")
|
help="Max concurrent workers to use throughout the code, particularly downloads.")
|
||||||
@click.option("--log", "log_path", type=Path, default=config.directories.logs / config.filenames.log,
|
|
||||||
help="Log path (or filename). Path can contain the following f-string args: {name} {time}.")
|
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def cli(ctx: click.Context, **kwargs: Any) -> dl:
|
def cli(ctx: click.Context, **kwargs: Any) -> dl:
|
||||||
return dl(ctx, **kwargs)
|
return dl(ctx, **kwargs)
|
||||||
|
@ -131,7 +127,6 @@ class dl:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
ctx: click.Context,
|
ctx: click.Context,
|
||||||
log_path: Path,
|
|
||||||
profile: Optional[str] = None,
|
profile: Optional[str] = None,
|
||||||
proxy: Optional[str] = None,
|
proxy: Optional[str] = None,
|
||||||
group: Optional[str] = None,
|
group: Optional[str] = None,
|
||||||
|
@ -142,11 +137,6 @@ class dl:
|
||||||
raise ValueError("A subcommand to invoke was not specified, the main code cannot continue.")
|
raise ValueError("A subcommand to invoke was not specified, the main code cannot continue.")
|
||||||
|
|
||||||
self.log = logging.getLogger("download")
|
self.log = logging.getLogger("download")
|
||||||
if log_path:
|
|
||||||
new_log_path = self.rotate_log_file(log_path)
|
|
||||||
fh = logging.FileHandler(new_log_path, encoding="utf8")
|
|
||||||
fh.setFormatter(LOG_FORMATTER)
|
|
||||||
self.log.addHandler(fh)
|
|
||||||
|
|
||||||
self.service = Services.get_tag(ctx.invoked_subcommand)
|
self.service = Services.get_tag(ctx.invoked_subcommand)
|
||||||
|
|
||||||
|
@ -759,37 +749,6 @@ class dl:
|
||||||
shutil.move(muxed_path, final_path)
|
shutil.move(muxed_path, final_path)
|
||||||
self.log.info(f" + Moved to {final_path}")
|
self.log.info(f" + Moved to {final_path}")
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def rotate_log_file(log_path: Path, keep: int = 20) -> Path:
|
|
||||||
"""
|
|
||||||
Update Log Filename and delete old log files.
|
|
||||||
It keeps only the 20 newest logs by default.
|
|
||||||
"""
|
|
||||||
if not log_path:
|
|
||||||
raise ValueError("A log path must be provided")
|
|
||||||
|
|
||||||
try:
|
|
||||||
log_path.relative_to(Path("")) # file name only
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
log_path = config.directories.logs / log_path
|
|
||||||
|
|
||||||
log_path = log_path.parent / log_path.name.format_map(defaultdict(
|
|
||||||
str,
|
|
||||||
name="root",
|
|
||||||
time=datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
||||||
))
|
|
||||||
|
|
||||||
if log_path.parent.exists():
|
|
||||||
log_files = [x for x in log_path.parent.iterdir() if x.suffix == log_path.suffix]
|
|
||||||
for log_file in log_files[::-1][keep-1:]:
|
|
||||||
# keep n newest files and delete the rest
|
|
||||||
log_file.unlink()
|
|
||||||
|
|
||||||
log_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
return log_path
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_profile(service: str) -> Optional[str]:
|
def get_profile(service: str) -> Optional[str]:
|
||||||
"""Get profile for Service from config."""
|
"""Get profile for Service from config."""
|
||||||
|
|
|
@ -1,23 +1,34 @@
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import coloredlogs
|
import coloredlogs
|
||||||
|
|
||||||
from devine.core import __version__
|
from devine.core import __version__
|
||||||
from devine.core.commands import Commands
|
from devine.core.commands import Commands
|
||||||
from devine.core.constants import LOG_FORMAT, context_settings
|
from devine.core.config import config
|
||||||
|
from devine.core.constants import LOG_FORMAT, LOG_FORMATTER, context_settings
|
||||||
|
from devine.core.utilities import rotate_log_file
|
||||||
|
|
||||||
|
|
||||||
@click.command(cls=Commands, invoke_without_command=True, context_settings=context_settings)
|
@click.command(cls=Commands, invoke_without_command=True, context_settings=context_settings)
|
||||||
@click.option("-v", "--version", is_flag=True, default=False, help="Print version information.")
|
@click.option("-v", "--version", is_flag=True, default=False, help="Print version information.")
|
||||||
@click.option("-d", "--debug", is_flag=True, default=False, help="Enable DEBUG level logs.")
|
@click.option("-d", "--debug", is_flag=True, default=False, help="Enable DEBUG level logs.")
|
||||||
def main(version: bool, debug: bool) -> None:
|
@click.option("--log", "log_path", type=Path, default=config.directories.logs / config.filenames.log,
|
||||||
|
help="Log path (or filename). Path can contain the following f-string args: {name} {time}.")
|
||||||
|
def main(version: bool, debug: bool, log_path: Path) -> None:
|
||||||
"""Devine—Open-Source Movie, TV, and Music Downloading Solution."""
|
"""Devine—Open-Source Movie, TV, and Music Downloading Solution."""
|
||||||
logging.basicConfig(level=logging.DEBUG if debug else logging.INFO)
|
logging.basicConfig(level=logging.DEBUG if debug else logging.INFO)
|
||||||
log = logging.getLogger()
|
log = logging.getLogger()
|
||||||
coloredlogs.install(level=log.level, fmt=LOG_FORMAT, style="{")
|
coloredlogs.install(level=log.level, fmt=LOG_FORMAT, style="{")
|
||||||
|
|
||||||
|
if log_path:
|
||||||
|
new_log_path = rotate_log_file(log_path)
|
||||||
|
fh = logging.FileHandler(new_log_path, encoding="utf8")
|
||||||
|
fh.setFormatter(LOG_FORMATTER)
|
||||||
|
log.addHandler(fh)
|
||||||
|
|
||||||
log.info(f"Devine version {__version__} Copyright (c) 2019-{datetime.now().year} rlaphoenix")
|
log.info(f"Devine version {__version__} Copyright (c) 2019-{datetime.now().year} rlaphoenix")
|
||||||
log.info("Convenient Widevine-DRM Downloader and Decrypter.")
|
log.info("Convenient Widevine-DRM Downloader and Decrypter.")
|
||||||
log.info("https://github.com/devine-dl/devine")
|
log.info("https://github.com/devine-dl/devine")
|
||||||
|
|
|
@ -5,6 +5,8 @@ import re
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
from collections import defaultdict
|
||||||
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import AsyncIterator, Optional, Sequence, Union
|
from typing import AsyncIterator, Optional, Sequence, Union
|
||||||
|
@ -20,6 +22,37 @@ from devine.core.config import config
|
||||||
from devine.core.constants import LANGUAGE_MAX_DISTANCE
|
from devine.core.constants import LANGUAGE_MAX_DISTANCE
|
||||||
|
|
||||||
|
|
||||||
|
def rotate_log_file(log_path: Path, keep: int = 20) -> Path:
|
||||||
|
"""
|
||||||
|
Update Log Filename and delete old log files.
|
||||||
|
It keeps only the 20 newest logs by default.
|
||||||
|
"""
|
||||||
|
if not log_path:
|
||||||
|
raise ValueError("A log path must be provided")
|
||||||
|
|
||||||
|
try:
|
||||||
|
log_path.relative_to(Path("")) # file name only
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
log_path = config.directories.logs / log_path
|
||||||
|
|
||||||
|
log_path = log_path.parent / log_path.name.format_map(defaultdict(
|
||||||
|
str,
|
||||||
|
name="root",
|
||||||
|
time=datetime.now().strftime("%Y%m%d-%H%M%S")
|
||||||
|
))
|
||||||
|
|
||||||
|
if log_path.parent.exists():
|
||||||
|
log_files = [x for x in log_path.parent.iterdir() if x.suffix == log_path.suffix]
|
||||||
|
for log_file in log_files[::-1][keep-1:]:
|
||||||
|
# keep n newest files and delete the rest
|
||||||
|
log_file.unlink()
|
||||||
|
|
||||||
|
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
return log_path
|
||||||
|
|
||||||
|
|
||||||
def import_module_by_path(path: Path) -> ModuleType:
|
def import_module_by_path(path: Path) -> ModuleType:
|
||||||
"""Import a Python file by Path as a Module."""
|
"""Import a Python file by Path as a Module."""
|
||||||
if not path:
|
if not path:
|
||||||
|
|
Loading…
Reference in New Issue