Merge branch 'logging'

This commit is contained in:
Joakim Holm 2023-05-18 22:55:39 +02:00
commit 4da73a73e1
10 changed files with 131 additions and 33 deletions

View File

@ -1,6 +1,6 @@
from .book import Book, Series
from .config import load_config, Config, SourceConfig
from .exceptions import SourceNotAuthenticated
from .exceptions import SourceNotAuthenticated, GrawlixError
from .sources import load_source, Source
from .output import download_book
from . import arguments, logging
@ -68,23 +68,27 @@ async def authenticate(source: Source, config: Config, options):
async def main() -> None:
args = arguments.parse_arguments()
config = load_config()
logging.debug_mode = args.debug
urls = get_urls(args)
for url in urls:
source: Source = load_source(url)
if not source.authenticated and source.requires_authentication:
await authenticate(source, config, args)
result = await source.download(url)
if isinstance(result, Book):
with logging.progress(result.metadata.title, source.name) as progress:
template: str = args.output or "{title}.{ext}"
await download_with_progress(result, progress, template)
elif isinstance(result, Series):
with logging.progress(result.title, source.name, len(result.book_ids)) as progress:
for book_id in result.book_ids:
book: Book = await source.download_book_from_id(book_id)
template: str = args.output or "{series}/{title}.{ext}"
await download_with_progress(book, progress, template)
logging.info("")
try:
source: Source = load_source(url)
if not source.authenticated and source.requires_authentication:
await authenticate(source, config, args)
result = await source.download(url)
if isinstance(result, Book):
with logging.progress(result.metadata.title, source.name) as progress:
template: str = args.output or "{title}.{ext}"
await download_with_progress(result, progress, template)
elif isinstance(result, Series):
with logging.progress(result.title, source.name, len(result.book_ids)) as progress:
for book_id in result.book_ids:
book: Book = await source.download_book_from_id(book_id)
template: str = args.output or "{series}/{title}.{ext}"
await download_with_progress(book, progress, template)
logging.info("")
except GrawlixError as error:
error.print_error()
async def download_with_progress(book: Book, progress: Progress, template: str):

View File

@ -51,4 +51,10 @@ def parse_arguments() -> argparse.Namespace:
help = "Output destination",
dest = "output"
)
# Logging
parser.add_argument(
'--debug',
help = "Enable debug messages",
dest = "debug"
)
return parser.parse_args()

View File

@ -0,0 +1,9 @@
[red]ERROR: Missing data from source[/red]
grawlix is missing data from source. This can happen when you try to
download ebooks you don't have access too (not logged in or your profile
doesn't have the right permissions), the site has been updated and grawlix
hasn't implemented the new version, or it could be a bug in grawlix.
If you think it is a problem with grawlix please create an issue at
https://github.com/jo1gi/grawlix/issues

View File

@ -0,0 +1,6 @@
[red]ERROR: The given url does not match any sources[/red]
Please make sure the link goes to the ebook you want to download and the site is
supported by grawlix. Try the link to the reader page if available.
If nothing works please create an issue at {issue}

View File

@ -0,0 +1,8 @@
[red]ERROR: Source has not been authenticated[/red]
You need to login to use this site. You can either use
* [green]--username[/] and [green]--password[/]
* Write username and password in the config file
* Use a cookie file with [green]--cookies[/]
See the README for more information: {repo}

View File

@ -0,0 +1,4 @@
[red]ERROR: Your connection has been throttled[/]
The site you are downloading from has temporarily blocked you.
Please wait a bit before downloading again or try another site or account.

View File

@ -1,23 +1,30 @@
from grawlix.logging import print_error_file
ISSUE_URL = "https://github.com/jo1gi/grawlix/issues"
REPO_URL = "https://github.com/jo1gi/grawlix"
class GrawlixError(Exception):
pass
error_file: str
def print_error(self) -> None:
print_error_file(
self.error_file,
repo = REPO_URL,
issue = ISSUE_URL,
)
class DataNotFound(GrawlixError):
pass
error_file = "data_not_found"
class InvalidUrl(GrawlixError):
pass
error_file = "invalid_url"
class UnsupportedOutputFormat(GrawlixError):
pass
class NoSourceFound(GrawlixError):
pass
error_file = "unsupported_output_format"
class SourceNotAuthenticated(GrawlixError):
pass
class MissingArgument(GrawlixError):
pass
error_file = "source_not_authenticated"
class ThrottleError(GrawlixError):
pass
error_file = "throttle"

View File

@ -1,22 +1,63 @@
from grawlix.book import Book
from rich.console import Console
from rich.progress import Progress, BarColumn, ProgressColumn, TaskID, SpinnerColumn
import rich
from rich.console import Console
from rich.markup import render
from rich.progress import Progress, BarColumn, ProgressColumn, TaskID, SpinnerColumn
from rich.style import Style
from typing import Union
from dataclasses import dataclass
import importlib.resources
console = Console(stderr=True)
debug_mode = False
DEBUG_PREFIX = render("[yellow bold]DEBUG[/]")
def debug(msg: str, remove_styling=False) -> None:
"""
Print debug message in console
:param msg: Message to print
:param remove_styling: Remove automated styling from message
"""
if debug_mode:
if remove_styling:
rendered_msg = render(msg, style=Style(bold=False, color="white"))
console.print(DEBUG_PREFIX, rendered_msg)
else:
console.print(DEBUG_PREFIX, msg)
def info(msg: str) -> None:
"""
Print message in log
Print message in console
:param msg: Message to print
"""
console.print(msg)
def error(msg: str) -> None:
console.print(msg)
def print_error_file(name: str, **kwargs) -> None:
"""
Print predefined error message
:param name: Name of error file
"""
message = importlib.resources.files("grawlix") \
.joinpath(f"assets/errors/{name}.txt") \
.read_text("utf8") \
.format(**kwargs) \
.strip()
error(message)
def progress(category_name: str, source_name: str, count=1) -> Progress:
if count > 1:
console.print(f"Downloading [yellow not bold]{count}[/] books in [blue]{category_name}[/] from [magenta]{source_name}[/]")
@ -31,6 +72,7 @@ def progress(category_name: str, source_name: str, count=1) -> Progress:
)
return progress
def add_book(progress: Progress, book: Book) -> TaskID:
task = progress.add_task(
f"[blue]{book.metadata.title}[/]",

View File

@ -1,4 +1,4 @@
from grawlix.exceptions import NoSourceFound
from grawlix.exceptions import InvalidUrl
from .source import Source
from .ereolen import Ereolen
@ -42,7 +42,7 @@ def find_source(url: str) -> type[Source]:
for num, match in enumerate(cls.match):
if re.match(match, url):
return cls
raise NoSourceFound
raise InvalidUrl
def get_source_classes() -> list[type[Source]]:

View File

@ -2,6 +2,7 @@ from grawlix.exceptions import DataNotFound
from urllib.parse import urlparse, parse_qs
from functools import lru_cache
import importlib.resources
def get_arg_from_url(url: str, key: str) -> str:
parsed_url = urlparse(url)
@ -38,3 +39,14 @@ def nearest_string(input: str, list: list[str]) -> str:
Finds the nearest string in `list` to `input` based on levenstein distance
"""
return sorted(list, key = lambda x: levenstein_distance(input, x))[0]
def read_asset_file(path: str) -> str:
"""
Read asset file from the grawlix module
:param path: Path relative to root of grawlix module
"""
return importlib.resources.files("grawlix") \
.joinpath(path) \
.read_text(encoding="utf8")