Replace log.info calls with console.log calls

I've moved log.info calls to console.log calls to reduce conflicts of logs at the same time as console refreshes, but also to reduce unnecessary log level text being printed to the console.

We don't need to know if a log is an `info` level log, but I've kept log.error's and such as we would want to know if a log is an error log and such.
This commit is contained in:
rlaphoenix 2023-02-25 12:11:17 +00:00
parent 3e1a067724
commit 62d91a3e77
9 changed files with 133 additions and 139 deletions

View File

@ -10,6 +10,7 @@ import click
from ruamel.yaml import YAML
from devine.core.config import Config, config
from devine.core.console import console
from devine.core.constants import context_settings
from devine.core.credential import Credential
@ -28,15 +29,13 @@ def auth(ctx: click.Context) -> None:
short_help="List profiles and their state for a service or all services.",
context_settings=context_settings)
@click.argument("service", type=str, required=False)
@click.pass_context
def list_(ctx: click.Context, service: Optional[str] = None) -> None:
def list_(service: Optional[str] = None) -> None:
"""
List profiles and their state for a service or all services.
\b
Profile and Service names are case-insensitive.
"""
log = ctx.obj
service_f = service
auth_data: dict[str, dict[str, list]] = defaultdict(lambda: defaultdict(list))
@ -55,9 +54,9 @@ def list_(ctx: click.Context, service: Optional[str] = None) -> None:
for service, profiles in dict(sorted(auth_data.items())).items(): # type:ignore
if service_f and service != service_f.upper():
continue
log.info(service)
console.log(service)
for profile, authorizations in dict(sorted(profiles.items())).items():
log.info(f' "{profile}": {", ".join(authorizations)}')
console.log(f' "{profile}": {", ".join(authorizations)}')
@auth.command(
@ -82,7 +81,7 @@ def view(ctx: click.Context, profile: str, service: str) -> None:
if cookie_dir.name == service_f:
for cookie in cookie_dir.glob("*.txt"):
if cookie.stem == profile_f:
log.info(f"Cookie: {cookie}")
console.log(f"Cookie: {cookie}")
log.debug(cookie.read_text(encoding="utf8").strip())
found = True
break
@ -91,7 +90,7 @@ def view(ctx: click.Context, profile: str, service: str) -> None:
if service == service_f:
for profile, credential in credentials.items():
if profile == profile_f:
log.info(f"Credential: {':'.join(list(credential))}")
console.log(f"Credential: {':'.join(list(credential))}")
found = True
break
@ -106,26 +105,24 @@ def view(ctx: click.Context, profile: str, service: str) -> None:
short_help="Check what profile is used by services.",
context_settings=context_settings)
@click.argument("service", type=str, required=False)
@click.pass_context
def status(ctx: click.Context, service: Optional[str] = None) -> None:
def status(service: Optional[str] = None) -> None:
"""
Check what profile is used by services.
\b
Service names are case-sensitive.
"""
log = ctx.obj
found_profile = False
for service_, profile in config.profiles.items():
if not service or service_.upper() == service.upper():
log.info(f"{service_}: {profile or '--'}")
console.log(f"{service_}: {profile or '--'}")
found_profile = True
if not found_profile:
log.info(f"No profile has been explicitly set for {service}")
console.log(f"No profile has been explicitly set for {service}")
default = config.profiles.get("default", "not set")
log.info(f"The default profile is {default}")
console.log(f"The default profile is {default}")
@auth.command(
@ -135,8 +132,7 @@ def status(ctx: click.Context, service: Optional[str] = None) -> None:
@click.argument("service", type=str)
@click.option("--cookie", is_flag=True, default=False, help="Only delete the cookie.")
@click.option("--credential", is_flag=True, default=False, help="Only delete the credential.")
@click.pass_context
def delete(ctx: click.Context, profile: str, service: str, cookie: bool, credential: bool):
def delete(profile: str, service: str, cookie: bool, credential: bool):
"""
Delete a profile and all of its authorization from a service.
@ -148,7 +144,6 @@ def delete(ctx: click.Context, profile: str, service: str, cookie: bool, credent
Profile and Service names are case-sensitive.
Comments may be removed from config!
"""
log = ctx.obj
service_f = service
profile_f = profile
found = False
@ -159,7 +154,7 @@ def delete(ctx: click.Context, profile: str, service: str, cookie: bool, credent
for cookie_ in cookie_dir.glob("*.txt"):
if cookie_.stem == profile_f:
cookie_.unlink()
log.info(f"Deleted Cookie: {cookie_}")
console.log(f"Deleted Cookie: {cookie_}")
found = True
break
@ -174,7 +169,7 @@ def delete(ctx: click.Context, profile: str, service: str, cookie: bool, credent
data = yaml.load(config_path)
del data["credentials"][key][profile_f]
yaml.dump(data, config_path)
log.info(f"Deleted Credential: {credential_}")
console.log(f"Deleted Credential: {credential_}")
found = True
break
@ -224,7 +219,7 @@ def add(ctx: click.Context, profile: str, service: str, cookie: Optional[str] =
if cookie:
cookie = Path(cookie)
else:
log.info("Skipped adding a Cookie...")
console.log("Skipped adding a Cookie...")
if credential:
try:
@ -239,7 +234,7 @@ def add(ctx: click.Context, profile: str, service: str, cookie: Optional[str] =
except ValueError as e:
raise click.ClickException(str(e))
else:
log.info("Skipped adding a Credential...")
console.log("Skipped adding a Credential...")
if cookie:
final_path = (config.directories.cookies / service / profile).with_suffix(".txt")
@ -248,7 +243,7 @@ def add(ctx: click.Context, profile: str, service: str, cookie: Optional[str] =
log.error(f"A Cookie file for the Profile {profile} on {service} already exists.")
sys.exit(1)
shutil.move(cookie, final_path)
log.info(f"Moved Cookie file to: {final_path}")
console.log(f"Moved Cookie file to: {final_path}")
if credential:
config_path = Config._Directories.user_configs / Config._Filenames.root_config
@ -263,4 +258,4 @@ def add(ctx: click.Context, profile: str, service: str, cookie: Optional[str] =
data["credentials"][service] = {}
data["credentials"][service][profile] = credential.dumps()
yaml.dump(data, config_path)
log.info(f"Added Credential: {credential}")
console.log(f"Added Credential: {credential}")

View File

@ -6,6 +6,7 @@ import click
from ruamel.yaml import YAML
from devine.core.config import config
from devine.core.console import console
from devine.core.constants import context_settings
@ -80,10 +81,10 @@ def cfg(ctx: click.Context, key: str, value: str, unset: bool, list_: bool) -> N
parent_data = parent_data[key]
if is_write:
parent_data[trailing_key] = value
log.info(f"Set {key} to {repr(value)}")
console.log(f"Set {key} to {repr(value)}")
elif is_delete:
del parent_data[trailing_key]
log.info(f"Unset {key}")
console.log(f"Unset {key}")
except KeyError:
raise click.ClickException(f"Key '{key}' does not exist in the config.")
config_path.parent.mkdir(parents=True, exist_ok=True)

View File

@ -30,6 +30,7 @@ from pywidevine.remotecdm import RemoteCdm
from tqdm import tqdm
from devine.core.config import config
from devine.core.console import console
from devine.core.constants import AnyTrack, context_settings
from devine.core.credential import Credential
from devine.core.downloaders import aria2c
@ -140,43 +141,43 @@ class dl:
self.service = Services.get_tag(ctx.invoked_subcommand)
self.log.info(f"Loading Profile Data for {self.service}")
console.log(f"Loading Profile Data for {self.service}")
if profile:
self.profile = profile
self.log.info(f" + Profile: {self.profile} (explicit)")
console.log(f" + Profile: {self.profile} (explicit)")
else:
self.profile = self.get_profile(self.service)
self.log.info(f" + Profile: {self.profile} (from config)")
console.log(f" + Profile: {self.profile} (from config)")
self.log.info("Initializing Widevine CDM")
console.log("Initializing Widevine CDM")
try:
self.cdm = self.get_cdm(self.service, self.profile)
except ValueError as e:
self.log.error(f" - {e}")
sys.exit(1)
self.log.info(
console.log(
f" + {self.cdm.__class__.__name__}: {self.cdm.system_id} (L{self.cdm.security_level})"
)
self.log.info("Loading Vaults")
console.log("Loading Vaults")
self.vaults = Vaults(self.service)
for vault in config.key_vaults:
vault_type = vault["type"]
del vault["type"]
self.vaults.load(vault_type, **vault)
self.log.info(f" + {len(self.vaults)} Vaults")
console.log(f" + {len(self.vaults)} Vaults")
self.log.info("Getting Service Config")
console.log("Getting Service Config")
service_config_path = Services.get_path(self.service) / config.filenames.config
if service_config_path.is_file():
self.service_config = yaml.safe_load(service_config_path.read_text(encoding="utf8"))
self.log.info(" + Got Service Config")
console.log(" + Got Service Config")
else:
self.service_config = {}
self.log.info(" - No Service Config")
console.log(" - No Service Config")
merge_dict(config.services.get(self.service), self.service_config)
self.log.info("Loading Proxy Providers")
console.log("Loading Proxy Providers")
self.proxy_providers = []
if config.proxy_providers.get("basic"):
self.proxy_providers.append(Basic(**config.proxy_providers["basic"]))
@ -185,7 +186,7 @@ class dl:
if get_binary_path("hola-proxy"):
self.proxy_providers.append(Hola())
for proxy_provider in self.proxy_providers:
self.log.info(f" + {proxy_provider.__class__.__name__}: {repr(proxy_provider)}")
console.log(f" + {proxy_provider.__class__.__name__}: {repr(proxy_provider)}")
if proxy:
requested_provider = None
@ -194,7 +195,7 @@ class dl:
requested_provider, proxy = proxy.split(":", maxsplit=1)
if re.match(r"^[a-z]{2}(?:\d+)?$", proxy, re.IGNORECASE):
proxy = proxy.lower()
self.log.info(f"Getting a Proxy to '{proxy}'")
console.log(f"Getting a Proxy to '{proxy}'")
if requested_provider:
proxy_provider = next((
x
@ -209,16 +210,16 @@ class dl:
self.log.error(f"The proxy provider {requested_provider} had no proxy for {proxy}")
sys.exit(1)
proxy = ctx.params["proxy"] = proxy_uri
self.log.info(f" + {proxy} (from {proxy_provider.__class__.__name__})")
console.log(f" + {proxy} (from {proxy_provider.__class__.__name__})")
else:
for proxy_provider in self.proxy_providers:
proxy_uri = proxy_provider.get_proxy(proxy)
if proxy_uri:
proxy = ctx.params["proxy"] = proxy_uri
self.log.info(f" + {proxy} (from {proxy_provider.__class__.__name__})")
console.log(f" + {proxy} (from {proxy_provider.__class__.__name__})")
break
else:
self.log.info(f"Proxy: {proxy} (from args)")
console.log(f"Proxy: {proxy} (from args)")
ctx.obj = ContextData(
config=self.service_config,
@ -274,32 +275,32 @@ class dl:
self.log.error(f"The Profile '{self.profile}' has no Cookies or Credentials. Check for typos.")
sys.exit(1)
self.log.info(f"Authenticating with Profile '{self.profile}'")
console.log(f"Authenticating with Profile '{self.profile}'")
service.authenticate(cookies, credential)
self.log.info(" + Authenticated")
console.log(" + Authenticated")
self.log.info("Retrieving Titles")
console.log("Retrieving Titles")
titles = service.get_titles()
if not titles:
self.log.error(" - No titles returned!")
sys.exit(1)
for line in str(titles).splitlines(keepends=False):
self.log.info(line)
console.log(line)
if list_titles:
for title in titles:
self.log.info(title)
console.log(title)
return
for i, title in enumerate(titles):
if isinstance(title, Episode) and wanted and f"{title.season}x{title.number}" not in wanted:
continue
self.log.info(f"Getting tracks for {title}")
console.log(f"Getting tracks for {title}")
if slow and i != 0:
delay = random.randint(60, 120)
self.log.info(f" - Delaying by {delay} seconds due to --slow ...")
console.log(f" - Delaying by {delay} seconds due to --slow ...")
time.sleep(delay)
title.tracks.add(service.get_tracks(title), warn_only=True)
@ -324,10 +325,10 @@ class dl:
title.tracks.sort_subtitles(by_language=s_lang)
title.tracks.sort_chapters()
self.log.info("> All Tracks:")
console.log("> All Tracks:")
title.tracks.print()
self.log.info("> Selected Tracks:") # log early so errors logs make sense
console.log("> Selected Tracks:") # log early so errors logs make sense
if isinstance(title, (Movie, Episode)):
# filter video tracks
@ -412,7 +413,7 @@ class dl:
continue # only wanted to see what tracks were available and chosen
if skip_dl:
self.log.info("Skipping Download...")
console.log("Skipping Download...")
else:
with tqdm(total=len(title.tracks)) as pbar:
with ThreadPoolExecutor(workers) as pool:
@ -458,7 +459,7 @@ class dl:
except KeyboardInterrupt:
self.DL_POOL_STOP.set()
pool.shutdown(wait=False, cancel_futures=True)
self.log.info("Received Keyboard Interrupt, stopping...")
console.log("Received Keyboard Interrupt, stopping...")
return
if not skip_dl:
@ -473,7 +474,7 @@ class dl:
cookie_jar.set_cookie(cookie)
cookie_jar.save(ignore_discard=True)
self.log.info("Processed all titles!")
console.log("Processed all titles!")
def prepare_drm(
self,
@ -494,7 +495,7 @@ class dl:
return
if isinstance(drm, Widevine):
self.log.info(f"Licensing Content Keys using Widevine for {drm.pssh.dumps()}")
console.log(f"Licensing Content Keys using Widevine for {drm.pssh.dumps()}")
for kid in drm.kids:
if kid in drm.content_keys:
@ -504,9 +505,9 @@ class dl:
content_key, vault_used = self.vaults.get_key(kid)
if content_key:
drm.content_keys[kid] = content_key
self.log.info(f" + {kid.hex}:{content_key} ({vault_used})")
console.log(f" + {kid.hex}:{content_key} ({vault_used})")
add_count = self.vaults.add_key(kid, content_key, excluding=vault_used)
self.log.info(f" + Cached to {add_count}/{len(self.vaults) - 1} Vaults")
console.log(f" + Cached to {add_count}/{len(self.vaults) - 1} Vaults")
elif vaults_only:
self.log.error(f" - No Content Key found in any Vault for {kid.hex}")
sys.exit(1)
@ -530,7 +531,7 @@ class dl:
msg += " *"
if key == "0" * 32:
msg += " (Unusable!)"
self.log.info(msg)
console.log(msg)
drm.content_keys = {
kid_: key
@ -543,7 +544,7 @@ class dl:
drm.content_keys.update(from_vaults)
cached_keys = self.vaults.add_keys(drm.content_keys)
self.log.info(f" + Newly added to {cached_keys}/{len(drm.content_keys)} Vaults")
console.log(f" + Newly added to {cached_keys}/{len(drm.content_keys)} Vaults")
if kid not in drm.content_keys:
self.log.error(f" - No usable key was returned for {kid.hex}, cannot continue")
@ -576,7 +577,7 @@ class dl:
else:
proxy = None
self.log.info(f"Downloading: {track}")
console.log(f"Downloading: {track}")
if config.directories.temp.is_file():
self.log.error(f"Temp Directory '{config.directories.temp}' must be a Directory, not a file")
@ -681,9 +682,9 @@ class dl:
track.OnDownloaded(track)
if track.needs_repack:
self.log.info("Repackaging stream with FFMPEG (fix malformed streams)")
console.log("Repackaging stream with FFMPEG (fix malformed streams)")
track.repackage()
self.log.info(" + Repackaged")
console.log(" + Repackaged")
if callable(track.OnRepacked):
track.OnRepacked(track)
@ -695,7 +696,7 @@ class dl:
for x in ffprobe(track.path).get("streams", [])
)
):
self.log.info("Checking for EIA-CC Captions")
console.log("Checking for EIA-CC Captions")
try:
# TODO: Figure out the real language, it might be different
# EIA-CC tracks sadly don't carry language information :(
@ -714,15 +715,15 @@ class dl:
)
if cc:
title.tracks.add(cc)
self.log.info(" + Found & Extracted an EIA-CC Caption")
console.log(" + Found & Extracted an EIA-CC Caption")
except EnvironmentError:
self.log.error(" - Track needs to have CC extracted, but ccextractor wasn't found")
sys.exit(1)
self.log.info(" + No EIA-CC Captions...")
console.log(" + No EIA-CC Captions...")
def mux_tracks(self, title: Title_T, season_folder: bool = True, add_source: bool = True) -> None:
"""Mux Tracks, Delete Pre-Mux files, and move to the final location."""
self.log.info("Muxing Tracks into a Matroska Container")
console.log("Muxing Tracks into a Matroska Container")
if isinstance(title, (Movie, Episode)):
muxed_path, return_code = title.tracks.mux(str(title))
@ -731,7 +732,7 @@ class dl:
elif return_code >= 2:
self.log.error(" - Failed to Mux video to Matroska file")
sys.exit(1)
self.log.info(f" + Muxed to {muxed_path}")
console.log(f" + Muxed to {muxed_path}")
else:
# dont mux
muxed_path = title.tracks.audio[0].path
@ -747,7 +748,7 @@ class dl:
final_path = final_dir / f"{final_filename}{muxed_path.suffix}"
shutil.move(muxed_path, final_path)
self.log.info(f" + Moved to {final_path}")
console.log(f" + Moved to {final_path}")
@staticmethod
def get_profile(service: str) -> Optional[str]:

View File

@ -1,10 +1,10 @@
import logging
import shutil
from typing import Optional
import click
from devine.core.config import config
from devine.core.console import console
from devine.core.constants import context_settings
from devine.core.services import Services
@ -17,14 +17,13 @@ def env() -> None:
@env.command()
def info() -> None:
"""Displays information about the current environment."""
log = logging.getLogger("env")
log.info(f"[Root Config] : {config.directories.user_configs / config.filenames.root_config}")
log.info(f"[Cookies] : {config.directories.cookies}")
log.info(f"[WVDs] : {config.directories.wvds}")
log.info(f"[Cache] : {config.directories.cache}")
log.info(f"[Logs] : {config.directories.logs}")
log.info(f"[Temp Files] : {config.directories.temp}")
log.info(f"[Downloads] : {config.directories.downloads}")
console.log(f"[Root Config] : {config.directories.user_configs / config.filenames.root_config}")
console.log(f"[Cookies] : {config.directories.cookies}")
console.log(f"[WVDs] : {config.directories.wvds}")
console.log(f"[Cache] : {config.directories.cache}")
console.log(f"[Logs] : {config.directories.logs}")
console.log(f"[Temp Files] : {config.directories.temp}")
console.log(f"[Downloads] : {config.directories.downloads}")
@env.group(name="clear", short_help="Clear an environment directory.", context_settings=context_settings)
@ -36,29 +35,27 @@ def clear() -> None:
@click.argument("service", type=str, required=False)
def cache(service: Optional[str]) -> None:
"""Clear the environment cache directory."""
log = logging.getLogger("env")
cache_dir = config.directories.cache
if service:
cache_dir = cache_dir / Services.get_tag(service)
log.info(f"Clearing cache directory: {cache_dir}")
console.log(f"Clearing cache directory: {cache_dir}")
files_count = len(list(cache_dir.glob("**/*")))
if not files_count:
log.info("No files to delete")
console.log("No files to delete")
else:
log.info(f"Deleting {files_count} files...")
console.log(f"Deleting {files_count} files...")
shutil.rmtree(cache_dir)
log.info("Cleared")
console.log("Cleared")
@clear.command()
def temp() -> None:
"""Clear the environment temp directory."""
log = logging.getLogger("env")
log.info(f"Clearing temp directory: {config.directories.temp}")
console.log(f"Clearing temp directory: {config.directories.temp}")
files_count = len(list(config.directories.temp.glob("**/*")))
if not files_count:
log.info("No files to delete")
console.log("No files to delete")
else:
log.info(f"Deleting {files_count} files...")
console.log(f"Deleting {files_count} files...")
shutil.rmtree(config.directories.temp)
log.info("Cleared")
console.log("Cleared")

View File

@ -6,6 +6,7 @@ from typing import Optional
import click
from devine.core.config import config
from devine.core.console import console
from devine.core.constants import context_settings
from devine.core.services import Services
from devine.core.vault import Vault
@ -52,10 +53,10 @@ def copy(to_vault: str, from_vaults: list[str], service: Optional[str] = None) -
to_vault: Vault = vaults.vaults[0]
from_vaults: list[Vault] = vaults.vaults[1:]
log.info(f"Copying data from {', '.join([x.name for x in from_vaults])}, into {to_vault.name}")
console.log(f"Copying data from {', '.join([x.name for x in from_vaults])}, into {to_vault.name}")
if service:
service = Services.get_tag(service)
log.info(f"Only copying data for service {service}")
console.log(f"Only copying data for service {service}")
total_added = 0
for from_vault in from_vaults:
@ -65,7 +66,7 @@ def copy(to_vault: str, from_vaults: list[str], service: Optional[str] = None) -
services = from_vault.get_services()
for service_ in services:
log.info(f"Getting data from {from_vault} for {service_}")
console.log(f"Getting data from {from_vault} for {service_}")
content_keys = list(from_vault.get_keys(service_)) # important as it's a generator we iterate twice
bad_keys = {
@ -84,7 +85,7 @@ def copy(to_vault: str, from_vaults: list[str], service: Optional[str] = None) -
}
total_count = len(content_keys)
log.info(f"Adding {total_count} Content Keys to {to_vault} for {service_}")
console.log(f"Adding {total_count} Content Keys to {to_vault} for {service_}")
try:
added = to_vault.add_keys(service_, content_keys)
@ -95,9 +96,9 @@ def copy(to_vault: str, from_vaults: list[str], service: Optional[str] = None) -
total_added += added
existed = total_count - added
log.info(f"{to_vault} ({service_}): {added} newly added, {existed} already existed (skipped)")
console.log(f"{to_vault} ({service_}): {added} newly added, {existed} already existed (skipped)")
log.info(f"{to_vault}: {total_added} total newly added")
console.log(f"{to_vault}: {total_added} total newly added")
@kv.command()
@ -141,7 +142,6 @@ def add(file: Path, service: str, vaults: list[str]) -> None:
if len(vaults) < 1:
raise click.ClickException("You must provide at least one Vault.")
log = logging.getLogger("kv")
service = Services.get_tag(service)
vaults_ = Vaults()
@ -168,12 +168,12 @@ def add(file: Path, service: str, vaults: list[str]) -> None:
total_count = len(kid_keys)
for vault in vaults_:
log.info(f"Adding {total_count} Content Keys to {vault}")
console.log(f"Adding {total_count} Content Keys to {vault}")
added_count = vault.add_keys(service, kid_keys)
existed_count = total_count - added_count
log.info(f"{vault}: {added_count} newly added, {existed_count} already existed (skipped)")
console.log(f"{vault}: {added_count} newly added, {existed_count} already existed (skipped)")
log.info("Done!")
console.log("Done!")
@kv.command()
@ -196,15 +196,15 @@ def prepare(vaults: list[str]) -> None:
if hasattr(vault, "has_table") and hasattr(vault, "create_table"):
for service_tag in Services.get_tags():
if vault.has_table(service_tag):
log.info(f"{vault} already has a {service_tag} Table")
console.log(f"{vault} already has a {service_tag} Table")
else:
try:
vault.create_table(service_tag, commit=True)
log.info(f"{vault}: Created {service_tag} Table")
console.log(f"{vault}: Created {service_tag} Table")
except PermissionError:
log.error(f"{vault} user has no create table permission, skipping...")
continue
else:
log.info(f"{vault} does not use tables, skipping...")
console.log(f"{vault} does not use tables, skipping...")
log.info("Done!")
console.log("Done!")

View File

@ -10,6 +10,7 @@ from pywidevine.license_protocol_pb2 import FileHashes
from unidecode import UnidecodeError, unidecode
from devine.core.config import config
from devine.core.console import console
from devine.core.constants import context_settings
@ -34,28 +35,26 @@ def parse(path: Path) -> None:
if named:
path = config.directories.wvds / f"{path.name}.wvd"
log = logging.getLogger("wvd")
device = Device.load(path)
log.info(f"System ID: {device.system_id}")
log.info(f"Security Level: {device.security_level}")
log.info(f"Type: {device.type}")
log.info(f"Flags: {device.flags}")
log.info(f"Private Key: {bool(device.private_key)}")
log.info(f"Client ID: {bool(device.client_id)}")
log.info(f"VMP: {bool(device.client_id.vmp_data)}")
console.log(f"System ID: {device.system_id}")
console.log(f"Security Level: {device.security_level}")
console.log(f"Type: {device.type}")
console.log(f"Flags: {device.flags}")
console.log(f"Private Key: {bool(device.private_key)}")
console.log(f"Client ID: {bool(device.client_id)}")
console.log(f"VMP: {bool(device.client_id.vmp_data)}")
log.info("Client ID:")
log.info(device.client_id)
console.log("Client ID:")
console.log(device.client_id)
log.info("VMP:")
console.log("VMP:")
if device.client_id.vmp_data:
file_hashes = FileHashes()
file_hashes.ParseFromString(device.client_id.vmp_data)
log.info(str(file_hashes))
console.log(str(file_hashes))
else:
log.info("None")
console.log("None")
@wvd.command()
@ -82,9 +81,9 @@ def dump(wvd_paths: list[Path], out_dir: Path) -> None:
device = Device.load(wvd_path)
log = logging.getLogger("wvd")
log.info(f"Dumping: {wvd_path}")
log.info(f"L{device.security_level} {device.system_id} {device.type.name}")
log.info(f"Saving to: {out_path}")
console.log(f"Dumping: {wvd_path}")
console.log(f"L{device.security_level} {device.system_id} {device.type.name}")
console.log(f"Saving to: {out_path}")
device_meta = {
"wvd": {
@ -100,7 +99,7 @@ def dump(wvd_paths: list[Path], out_dir: Path) -> None:
device_meta_path = out_path / "metadata.yml"
device_meta_path.write_text(yaml.dump(device_meta), encoding="utf8")
log.info(" + Device Metadata")
console.log(" + Device Metadata")
if device.private_key:
private_key_path = out_path / "private_key.pem"
@ -111,23 +110,23 @@ def dump(wvd_paths: list[Path], out_dir: Path) -> None:
private_key_path.with_suffix(".der").write_bytes(
device.private_key.export_key(format="DER")
)
log.info(" + Private Key")
console.log(" + Private Key")
else:
log.warning(" - No Private Key available")
if device.client_id:
client_id_path = out_path / "client_id.bin"
client_id_path.write_bytes(device.client_id.SerializeToString())
log.info(" + Client ID")
console.log(" + Client ID")
else:
log.warning(" - No Client ID available")
if device.client_id.vmp_data:
vmp_path = out_path / "vmp.bin"
vmp_path.write_bytes(device.client_id.vmp_data)
log.info(" + VMP (File Hashes)")
console.log(" + VMP (File Hashes)")
else:
log.info(" - No VMP (File Hashes) available")
console.log(" - No VMP (File Hashes) available")
@wvd.command()
@ -191,15 +190,15 @@ def new(
log = logging.getLogger("wvd")
log.info(f"Created binary WVD file, {out_path.name}")
log.info(f" + Saved to: {out_path.absolute()}")
log.info(f" + System ID: {device.system_id}")
log.info(f" + Security Level: {device.security_level}")
log.info(f" + Type: {device.type}")
log.info(f" + Flags: {device.flags}")
log.info(f" + Private Key: {bool(device.private_key)}")
log.info(f" + Client ID: {bool(device.client_id)}")
log.info(f" + VMP: {bool(device.client_id.vmp_data)}")
console.log(f"Created binary WVD file, {out_path.name}")
console.log(f" + Saved to: {out_path.absolute()}")
console.log(f" + System ID: {device.system_id}")
console.log(f" + Security Level: {device.security_level}")
console.log(f" + Type: {device.type}")
console.log(f" + Flags: {device.flags}")
console.log(f" + Private Key: {bool(device.private_key)}")
console.log(f" + Client ID: {bool(device.client_id)}")
console.log(f" + VMP: {bool(device.client_id.vmp_data)}")
log.debug("Client ID:")
log.debug(device.client_id)
@ -208,6 +207,6 @@ def new(
if device.client_id.vmp_data:
file_hashes = FileHashes()
file_hashes.ParseFromString(device.client_id.vmp_data)
log.info(str(file_hashes))
console.log(str(file_hashes))
else:
log.info("None")
console.log("None")

View File

@ -25,6 +25,7 @@ from pywidevine.pssh import PSSH
from requests import Session
from tqdm import tqdm
from devine.core.console import console
from devine.core.constants import AnyTrack
from devine.core.downloaders import aria2c
from devine.core.drm import Widevine
@ -524,7 +525,7 @@ class DASH:
except KeyboardInterrupt:
state_event.set()
pool.shutdown(wait=False, cancel_futures=True)
log.info("Received Keyboard Interrupt, stopping...")
console.log("Received Keyboard Interrupt, stopping...")
return
@staticmethod

View File

@ -23,6 +23,7 @@ from pywidevine.pssh import PSSH
from requests import Session
from tqdm import tqdm
from devine.core.console import console
from devine.core.constants import AnyTrack
from devine.core.downloaders import aria2c
from devine.core.drm import DRM_T, ClearKey, Widevine
@ -371,7 +372,7 @@ class HLS:
except KeyboardInterrupt:
state_event.set()
pool.shutdown(wait=False, cancel_futures=True)
log.info("Received Keyboard Interrupt, stopping...")
console.log("Received Keyboard Interrupt, stopping...")
return
@staticmethod

View File

@ -1,6 +1,5 @@
from __future__ import annotations
import logging
import math
import re
import subprocess
@ -11,6 +10,7 @@ from typing import Any, Optional, Union
from langcodes import Language
from devine.core.config import config
from devine.core.console import console
from devine.core.tracks.subtitle import Subtitle
from devine.core.tracks.track import Track
from devine.core.utilities import FPS, get_binary_path, get_boxes
@ -296,15 +296,14 @@ class Video(Track):
if not executable:
raise EnvironmentError("FFmpeg executable \"ffmpeg\" was not found but is required for this call.")
log = logging.getLogger("x264-clean")
log.info("Removing EIA-CC from Video Track with FFMPEG")
console.log("Removing EIA-CC from Video Track with FFMPEG")
with open(self.path, "rb") as f:
file = f.read(60000)
x264 = re.search(br"(.{16})(x264)", file)
if not x264:
log.info(" - No x264 encode settings were found, unsupported...")
console.log(" - No x264 encode settings were found, unsupported...")
return False
uuid = x264.group(1).hex()
@ -323,7 +322,7 @@ class Video(Track):
str(cleaned_path)
], check=True)
log.info(" + Removed")
console.log(" + Removed")
self.swap(cleaned_path)