2025-12-25 upload
This commit is contained in:
73
venv/Lib/site-packages/mitmproxy/contentviews/_registry.py
Normal file
73
venv/Lib/site-packages/mitmproxy/contentviews/_registry.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import typing
|
||||
from collections.abc import Mapping
|
||||
|
||||
from ..utils import signals
|
||||
from ._api import Contentview
|
||||
from ._api import Metadata
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _on_change(view: Contentview) -> None: ...
|
||||
|
||||
|
||||
class ContentviewRegistry(Mapping[str, Contentview]):
|
||||
def __init__(self):
|
||||
self._by_name: dict[str, Contentview] = {}
|
||||
self.on_change = signals.SyncSignal(_on_change)
|
||||
|
||||
def register(self, instance: Contentview | type[Contentview]) -> None:
|
||||
if isinstance(instance, type):
|
||||
instance = instance()
|
||||
name = instance.name.lower()
|
||||
if name in self._by_name:
|
||||
logger.info(f"Replacing existing {name} contentview.")
|
||||
self._by_name[name] = instance
|
||||
self.on_change.send(instance)
|
||||
|
||||
def available_views(self) -> list[str]:
|
||||
return ["auto", *sorted(self._by_name.keys())]
|
||||
|
||||
def get_view(
|
||||
self, data: bytes, metadata: Metadata, view_name: str = "auto"
|
||||
) -> Contentview:
|
||||
"""
|
||||
Get the best contentview for the given data and metadata.
|
||||
|
||||
If `view_name` is "auto" or the provided view not found,
|
||||
the best matching contentview based on `render_priority` will be returned.
|
||||
"""
|
||||
if view_name != "auto":
|
||||
try:
|
||||
return self[view_name.lower()]
|
||||
except KeyError:
|
||||
logger.warning(
|
||||
f"Unknown contentview {view_name!r}, selecting best match instead."
|
||||
)
|
||||
|
||||
max_prio: tuple[float, Contentview] | None = None
|
||||
for name, view in self._by_name.items():
|
||||
try:
|
||||
priority = view.render_priority(data, metadata)
|
||||
assert isinstance(priority, (int, float)), (
|
||||
f"render_priority for {view.name} did not return a number."
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(f"Error in {view.name}.render_priority")
|
||||
else:
|
||||
if max_prio is None or max_prio[0] < priority:
|
||||
max_prio = (priority, view)
|
||||
assert max_prio, "At least one view needs to have a working `render_priority`."
|
||||
return max_prio[1]
|
||||
|
||||
def __iter__(self) -> typing.Iterator[str]:
|
||||
return iter(self._by_name)
|
||||
|
||||
def __getitem__(self, item: str) -> Contentview:
|
||||
return self._by_name[item.lower()]
|
||||
|
||||
def __len__(self):
|
||||
return len(self._by_name)
|
||||
Reference in New Issue
Block a user