Skip to content

Commit

Permalink
Handle unsupported SVG files gracefully
Browse files Browse the repository at this point in the history
  • Loading branch information
titusz committed Jun 30, 2024
1 parent 3deed67 commit 4a23267
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Added support for scene based granular video code processing
- Added ffprobe video metadata extraction (duration, fps, width, height, language)
- Added support str and Path objects for all file inpunts
- Handle unsupported SVG files gracefully

## 0.6.2 - 2024-06-13
- Update and relax dependencies
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Added support for scene based granular video code processing
- Added ffprobe video metadata extraction (duration, fps, width, height, language)
- Added support str and Path objects for all file inpunts
- Handle unsupported SVG files gracefully

## 0.6.2 - 2024-06-13
- Update and relax dependencies
Expand Down
8 changes: 6 additions & 2 deletions iscc_sdk/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,12 @@ def create(file: Path):
"""Create ISCC-CODE for single FILE."""
log.remove()
if file.is_file() and file.exists():
result = idk.code_iscc(file.as_posix())
typer.echo(result.json(indent=2))
try:
result = idk.code_iscc(file.as_posix())
typer.echo(result.json(indent=2))
except idk.IsccUnsupportedMediatype as e:
typer.echo(e)
raise typer.Exit(code=1)
else:
typer.echo(f"Invalid file path {file}")
raise typer.Exit(code=1)
Expand Down
2 changes: 2 additions & 0 deletions iscc_sdk/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ def image_meta_embed(fp, meta):
cmdf += f"set Xmp.dc.creator {meta.creator}\n"
if meta.rights:
cmdf += f"set Xmp.dc.rights {meta.rights}\n"
if meta.identifier:
cmdf += f"set Xmp.dc.identifier {meta.identifier}\n"

# Create temp filepaths
tempdir = Path(tempfile.mkdtemp())
Expand Down
15 changes: 11 additions & 4 deletions iscc_sdk/mediatype.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ def mediatype_to_mode(mime_type):
# type: (str) -> str
"""Get perceptual processing mode from mimetype.
:param str mime_type: RFC-6838 mediatype string
:return str: Processing mode ("text", "image", "audio", "video")
:raise ValueError: if no matching processing mode was found.
:param mime_type: RFC-6838 mediatype string
:return Processing mode ("text", "image", "audio", "video")
:raise IsccUnsupportedMediatype: if no matching processing mode was found.
"""

mime_type = mediatype_clean(mime_type)
Expand All @@ -181,7 +181,7 @@ def mediatype_to_mode(mime_type):

# Fallback to guess mode by top-level type
mode = mime_type.split("/")[0]
if mode in ["text", "image", "audio", "video"]:
if mode in ["text", "image", "audio", "video"] and mime_type not in UNSUPPORTED_MEDIATYPES:
log.warning(f"Guessing perceptual mode from {mime_type}")
return mode

Expand All @@ -202,6 +202,7 @@ def mediatype_to_mode(mime_type):
mimetypes.add_type("image/heic", ".heic")
mimetypes.add_type("image/avif", ".avif")


SUPPORTED_MEDIATYPES = {
# Text Formats
"application/rtf": {"mode": "text", "ext": "rtf"},
Expand Down Expand Up @@ -278,6 +279,12 @@ def mediatype_to_mode(mime_type):
"video/x-ms-wmv": {"mode": "video", "ext": "wmv"},
}

# Signals eplixitly unsupported mediatypes that fail processing
UNSUPPORTED_MEDIATYPES = {
"image/svg+xml": {"mode": "image", "ext": "svg"},
}


MEDIATYPE_NORM = {
"audio/x-aiff": "audio/aiff",
"audio/x-wav": "audio/wav",
Expand Down
1 change: 1 addition & 0 deletions iscc_sdk/metadata.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""*Metadata handling functions*"""

from loguru import logger as log
from pathlib import Path
from typing import Optional

Expand Down
12 changes: 12 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ def epub_file(tmp_path_factory):
return dst.as_posix()


@pytest.fixture(scope="module")
def svg_file(tmp_path_factory) -> str:
dst = tmp_path_factory.mktemp("data") / "image.svg"
svg_content = """
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
"""
dst.write_text(svg_content)
return dst.as_posix()


@pytest.fixture(scope="module")
def asset_tree(tmp_path_factory):
dst = Path(tmp_path_factory.mktemp("data"))
Expand Down
6 changes: 6 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ def test_cli_create():
}


def test_cli_create_unsupported(svg_file):
result = runner.invoke(app, ["create", svg_file])
assert result.exit_code == 1
assert "Unsupported mediatype image/svg+xml" in result.stdout


def test_cli_batch_no_arg():
result = runner.invoke(app, ["batch"])
assert result.exit_code == 2
Expand Down
20 changes: 20 additions & 0 deletions tests/test_metadata.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import pytest

import iscc_sdk as idk


Expand All @@ -10,6 +12,11 @@ def test_extract_metadata(jpg_file):
}


def test_extract_metadata_unsupported(svg_file):
with pytest.raises(idk.IsccUnsupportedMediatype):
idk.extract_metadata(svg_file)


def test_embed_metadata(jpg_file):
meta = idk.IsccMeta(name="Some Title", description="Some Description")
new_file = idk.embed_metadata(jpg_file, meta)
Expand All @@ -22,6 +29,19 @@ def test_embed_metadata(jpg_file):
}


def test_metadata_identifier_field_image(jpg_file):
meta = idk.IsccMeta(name="Some Title", description="Some Description", identifier="abcdefghijk")
new_file = idk.embed_metadata(jpg_file, meta)
assert idk.extract_metadata(new_file).dict() == {
"name": "Some Title",
"description": "Some Description",
"creator": "Some Cat Lover",
"height": 133,
"width": 200,
"identifier": "abcdefghijk",
}


def test_embed_metadata_unsupported(doc_file):
meta = idk.IsccMeta(name="Some Title", description="Some Description")
new_file = idk.embed_metadata(doc_file, meta)
Expand Down

0 comments on commit 4a23267

Please sign in to comment.