Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mapillary_tools/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class MapillaryVideoGPSNotFoundError(MapillaryDescriptionError):
pass


class MapillaryInvalidGPXError(MapillaryDescriptionError):
pass


class MapillaryInvalidVideoError(MapillaryDescriptionError):
pass

Expand Down
10 changes: 9 additions & 1 deletion mapillary_tools/geotag/video_extractors/gpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import typing as T
from pathlib import Path

import gpxpy

if sys.version_info >= (3, 12):
from typing import override
else:
Expand Down Expand Up @@ -50,7 +52,13 @@ def __init__(

@override
def extract(self) -> types.VideoMetadata:
gpx_tracks = parse_gpx(self.gpx_path)
try:
gpx_tracks = parse_gpx(self.gpx_path)
except (OSError, UnicodeError, gpxpy.gpx.GPXException) as ex:
raise exceptions.MapillaryInvalidGPXError(
f"{self.gpx_path.name} is not a valid GPX file. "
"Replace it with a valid GPX file."
) from ex

if 1 < len(gpx_tracks):
LOG.warning(
Expand Down
25 changes: 25 additions & 0 deletions tests/integration/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,31 @@ def test_process_geotag_with_gpx_pattern(setup_data: py.path.local):
assert len(descs[0]["MAPGPSTrack"]) > 0


def test_process_geotag_with_malformed_gpx_pattern(setup_data: py.path.local):
video_path = setup_data.join("gopro_data").join("max-360mode.mp4")
gpx_file = setup_data.join("gopro_data").join("max-360mode.gpx")
gpx_file.write("<gpx><broken>")

descs = run_process_for_descs(
[
*[
"--geotag_source",
json.dumps({"source": "gpx", "filetypes": ["video"]}),
],
*["--geotag_source", "native"],
str(video_path),
]
)

video_desc = next(desc for desc in descs if desc["filename"] == str(video_path))
assert video_desc["error"] == {
"type": "MapillaryInvalidGPXError",
"message": (
"max-360mode.gpx is not a valid GPX file. Replace it with a valid GPX file."
),
}


def test_process_video_geotag_source_with_exiftool_runtime(setup_data: py.path.local):
pytest_skip_if_not_exiftool_installed()

Expand Down
Loading