repo-autoindex/repo_autoindex/_impl/base.py
Rohan McGovern 293f5887b7 Implement error handling
Ultimately, all errors are propagated in some way, but it's important to
differentiate between "the content was invalid" vs "failed to fetch the
content".
2022-08-09 08:51:06 +10:00

81 lines
2 KiB
Python

from abc import ABC, abstractmethod
from collections.abc import AsyncGenerator, Awaitable, Callable
from dataclasses import dataclass
from typing import Optional, Type, TypeVar
T = TypeVar("T")
Fetcher = Callable[[str], Awaitable[Optional[str]]]
ICON_FOLDER = "📂"
ICON_PACKAGE = "📦"
ICON_OPTICAL = "📀"
ICON_QCOW = "🐮"
ICON_OTHER = " "
class ContentError(Exception):
"""An error raised when indexed content appears to be invalid.
Errors of this type are raised when repo-autoindex is able to successfully
retrieve content and determine a repository type but fails to parse
repository metadata. For example, a corrupt yum repository may cause this
error to be raised.
"""
class FetcherError(Exception):
# Internal-only error used to separate exceptions raised by fetchers from
# exceptions raised by anything else.
pass
@dataclass
class GeneratedIndex:
"""A single HTML index page generated by repo-autoindex."""
content: str
"""The content of this index page (an HTML document)."""
relative_dir: str = "."
"""The directory of this index page, relative to the root of the indexed
repository.
"""
@dataclass
class IndexEntry:
href: str
text: str
time: str = ""
size: str = ""
padding: str = ""
icon: str = ICON_OTHER
class Repo(ABC):
def __init__(
self,
base_url: str,
entry_point_content: str,
fetcher: Fetcher,
):
self.base_url = base_url
self.entry_point_content = entry_point_content
self.fetcher = fetcher
@abstractmethod
def render_index(
self, index_href_suffix: str
) -> AsyncGenerator[GeneratedIndex, None]:
pass # pragma: no cover
@classmethod
@abstractmethod
async def probe(cls: Type[T], fetcher: Fetcher, url: str) -> Optional[T]:
"""Determine if a specified URL seems to point at a repository of this type.
If so, returns an initialized Repo of a concrete subtype. If not, returns None.
"""
pass # pragma: no cover