diff --git a/ChangeLog.md b/ChangeLog.md index 1e534bf0..4f5f8bcb 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -7,6 +7,8 @@ - Added the ability to copy a link, as Gemtext, to the clipboard (`gemtext_link.copy_link_as_gemtext`). ([#492](https://github.com/davep/rogallo/pull/492)) +- Fixed MIME type checks to ensure parameters are ignored when performing + the check. ([#495](https://github.com/davep/rogallo/pull/495)) ## v3.1.0 diff --git a/src/rogallo/document.py b/src/rogallo/document.py index 0e84e615..00d66a94 100644 --- a/src/rogallo/document.py +++ b/src/rogallo/document.py @@ -28,7 +28,7 @@ ############################################################################## # Local imports. -from .mime_checks import is_gemini_mime_type, is_gopher_mime_type +from .mime_checks import clean_mime_type, is_gemini_mime_type, is_gopher_mime_type from .types import RogalloLocation @@ -83,13 +83,10 @@ def __bool__(self) -> bool: """Return `True` if there is a location, `False` if not.""" return self.location is not None - @cached_property + @property def mime_type_sans_parameters(self) -> str | None: """The MIME type cleaned of any parameters..""" - if self.mime_type is None: - return None - mime_type, _, _ = self.mime_type.partition(";") - return mime_type.strip().lower() + return clean_mime_type(self.mime_type) @property def is_gemtext(self) -> bool: diff --git a/src/rogallo/mime_checks.py b/src/rogallo/mime_checks.py index 2281c3c4..b5d131da 100644 --- a/src/rogallo/mime_checks.py +++ b/src/rogallo/mime_checks.py @@ -47,6 +47,23 @@ def is_gopher_mime_type(mime_type: str | None) -> bool: ) +############################################################################## +def clean_mime_type(mime_type: str | None) -> str | None: + """The MIME type cleaned of any parameters. + + Args: + mime_type: The MIME type to clean. + + Returns: + The MIME type cleaned of any parameters, or `None` if the input was + `None`. + """ + if mime_type is None: + return None + mime_type, _, _ = mime_type.partition(";") + return mime_type.strip().lower() + + ############################################################################## @cache def is_displayable_mime_type(mime_type: str | None) -> bool: @@ -58,9 +75,8 @@ def is_displayable_mime_type(mime_type: str | None) -> bool: Returns: `True` if the MIME type is displayable, `False` otherwise. """ - if mime_type is None: + if (mime_type := clean_mime_type(mime_type)) is None: return False - mime_type, _, _ = mime_type.partition(";") return mime_type.startswith("text/") or mime_type in { ItemType.MENU.mime_type, ItemType.INDEX_SEARCH.mime_type, diff --git a/src/rogallo/screens/main/unsupported.py b/src/rogallo/screens/main/unsupported.py index 34dddb5e..2ed69146 100644 --- a/src/rogallo/screens/main/unsupported.py +++ b/src/rogallo/screens/main/unsupported.py @@ -23,6 +23,7 @@ save_trusted_schemes, ) from ...messages import DownloadURI +from ...mime_checks import clean_mime_type from ..confirm_unsupported import ConfirmUnsupportedURI from .local_messages import OpenUnsupportedMIMEType, OpenUnsupportedURI @@ -91,17 +92,17 @@ async def maybe_open_unsupported_mime_type( ) return + mime_type = clean_mime_type(message.mime_type) or "application/octet-stream" + # If the MIME type isn't trusted, let's see what the user wants to # do about it. if not ( - open_uri := ( - message.mime_type in (trusted_mime_types := load_trusted_mime_types()) - ) + open_uri := (mime_type in (trusted_mime_types := load_trusted_mime_types())) ): match await owner.app.push_screen_wait( ConfirmUnsupportedURI( str(message.location), - f"The MIME type '{message.mime_type}' is not supported by Rogallo. " + f"The MIME type '{mime_type}' is not supported by Rogallo. " "Do you want to open the location in your external browser?", allow_download=not isinstance(message.location, Path), ) @@ -110,7 +111,7 @@ async def maybe_open_unsupported_mime_type( open_uri = True case "always": open_uri = True - trusted_mime_types.add(message.mime_type) + trusted_mime_types.add(mime_type) save_trusted_mime_types(trusted_mime_types) case "download": open_uri = False