@@ -45,7 +45,7 @@ def _parse_source_options(
4545
4646 for s in video_geotag_source :
4747 for video_option in parse_source_option (s ):
48- video_option .filetypes = _combine_filetypes (
48+ video_option .filetypes = types . combine_filetype_filters (
4949 video_option .filetypes , {types .FileType .VIDEO }
5050 )
5151 parsed_options .append (video_option )
@@ -69,35 +69,6 @@ def _parse_source_options(
6969 return parsed_options
7070
7171
72- # Assume {GOPRO, VIDEO} are the NATIVE_VIDEO_FILETYPES:
73- # a | b = result
74- # {CAMM} | {GOPRO} = {}
75- # {CAMM} | {GOPRO, VIDEO} = {CAMM}
76- # {GOPRO} | {GOPRO, VIDEO} = {GOPRO}
77- # {GOPRO} | {VIDEO} = {GOPRO}
78- # {CAMM, GOPRO} | {VIDEO} = {CAMM, GOPRO}
79- # {VIDEO} | {VIDEO} = {CAMM, GOPRO, VIDEO}
80- def _combine_filetypes (
81- a : set [types .FileType ] | None , b : set [types .FileType ] | None
82- ) -> set [types .FileType ] | None :
83- if a is None :
84- return b
85-
86- if b is None :
87- return a
88-
89- # VIDEO is a superset of NATIVE_VIDEO_FILETYPES,
90- # so we add NATIVE_VIDEO_FILETYPES to each set for intersection later
91-
92- if types .FileType .VIDEO in a :
93- a = a | types .NATIVE_VIDEO_FILETYPES
94-
95- if types .FileType .VIDEO in b :
96- b = b | types .NATIVE_VIDEO_FILETYPES
97-
98- return a .intersection (b )
99-
100-
10172def process_geotag_properties (
10273 import_path : Path | T .Sequence [Path ],
10374 filetypes : set [types .FileType ] | None ,
@@ -135,7 +106,7 @@ def process_geotag_properties(
135106 )
136107
137108 for option in options :
138- option .filetypes = _combine_filetypes (option .filetypes , filetypes )
109+ option .filetypes = types . combine_filetype_filters (option .filetypes , filetypes )
139110 option .num_processes = num_processes
140111 if option .interpolation is None :
141112 option .interpolation = InterpolationOption (
@@ -236,9 +207,7 @@ def _write_metadatas(
236207 LOG .info ("Check the description file for details: %s" , desc_path )
237208
238209
239- def _is_error_skipped (
240- error_type : str , skipped_process_errors : T .Set [T .Type [Exception ]]
241- ):
210+ def _is_error_skipped (error_type : str , skipped_process_errors : set [T .Type [Exception ]]):
242211 skipped_process_error_names = set (err .__name__ for err in skipped_process_errors )
243212 skip_all = Exception in skipped_process_errors
244213 return skip_all or error_type in skipped_process_error_names
@@ -248,17 +217,13 @@ def _show_stats(
248217 metadatas : T .Sequence [types .MetadataOrError ],
249218 skipped_process_errors : T .Set [T .Type [Exception ]],
250219) -> None :
251- metadatas_by_filetype : T . Dict [types .FileType , list [types .MetadataOrError ]] = {}
220+ metadatas_by_filetype : dict [types .FileType , list [types .MetadataOrError ]] = {}
252221 for metadata in metadatas :
253- filetype : types .FileType | None
254222 if isinstance (metadata , types .ImageMetadata ):
255223 filetype = types .FileType .IMAGE
256224 else :
257225 filetype = metadata .filetype
258- if filetype :
259- metadatas_by_filetype .setdefault (types .FileType (filetype ), []).append (
260- metadata
261- )
226+ metadatas_by_filetype .setdefault (filetype , []).append (metadata )
262227
263228 for filetype , group in metadatas_by_filetype .items ():
264229 _show_stats_per_filetype (group , filetype , skipped_process_errors )
@@ -278,19 +243,16 @@ def _show_stats(
278243
279244
280245def _show_stats_per_filetype (
281- metadatas : T .Sequence [types .MetadataOrError ],
246+ metadatas : T .Collection [types .MetadataOrError ],
282247 filetype : types .FileType ,
283248 skipped_process_errors : T .Set [T .Type [Exception ]],
284249):
285- good_metadatas : list [T .Union [types .VideoMetadata , types .ImageMetadata ]] = []
286- filesize_to_upload = 0
287- error_metadatas : list [types .ErrorMetadata ] = []
288- for metadata in metadatas :
289- if isinstance (metadata , types .ErrorMetadata ):
290- error_metadatas .append (metadata )
291- else :
292- good_metadatas .append (metadata )
293- filesize_to_upload += metadata .filesize or 0
250+ good_metadatas : list [types .Metadata ]
251+ good_metadatas , error_metadatas = types .separate_errors (metadatas )
252+
253+ filesize_to_upload = sum (
254+ [0 if m .filesize is None else m .filesize for m in good_metadatas ]
255+ )
294256
295257 LOG .info ("%8d %s(s) read in total" , len (metadatas ), filetype .value )
296258 if good_metadatas :
@@ -317,8 +279,10 @@ def _show_stats_per_filetype(
317279
318280
319281def _validate_metadatas (
320- metadatas : T .Sequence [types .MetadataOrError ], num_processes : int | None
282+ metadatas : T .Collection [types .MetadataOrError ], num_processes : int | None
321283) -> list [types .MetadataOrError ]:
284+ LOG .debug ("Validating %d metadatas" , len (metadatas ))
285+
322286 # validating metadatas is slow, hence multiprocessing
323287
324288 # Do not pass error metadatas where the error object can not be pickled for multiprocessing to work
@@ -361,34 +325,45 @@ def process_finalize(
361325 desc_path : str | None = None ,
362326 num_processes : int | None = None ,
363327) -> list [types .MetadataOrError ]:
328+ image_metadatas : list [types .ImageMetadata ] = []
329+ video_metadatas : list [types .VideoMetadata ] = []
330+
364331 for metadata in metadatas :
365332 if isinstance (metadata , types .VideoMetadata ):
366- if device_make is not None :
367- metadata .make = device_make
368- if device_model is not None :
369- metadata .model = device_model
333+ video_metadatas .append (metadata )
370334 elif isinstance (metadata , types .ImageMetadata ):
371- if device_make is not None :
372- metadata .MAPDeviceMake = device_make
373- if device_model is not None :
374- metadata .MAPDeviceModel = device_model
335+ image_metadatas .append (metadata )
336+
337+ for metadata in video_metadatas :
338+ if device_make is not None :
339+ metadata .make = device_make
340+ if device_model is not None :
341+ metadata .model = device_model
342+
343+ for metadata in image_metadatas :
344+ if device_make is not None :
345+ metadata .MAPDeviceMake = device_make
346+ if device_model is not None :
347+ metadata .MAPDeviceModel = device_model
348+ # Add the basename
349+ metadata .MAPFilename = metadata .filename .name
375350
376351 # modified in place
377352 _apply_offsets (
378- [
379- metadata
380- for metadata in metadatas
381- if isinstance (metadata , types .ImageMetadata )
382- ],
353+ image_metadatas ,
383354 offset_time = offset_time ,
384355 offset_angle = offset_angle ,
385356 )
386357
387- LOG .debug ("Validating %d metadatas" , len (metadatas ))
388358 metadatas = _validate_metadatas (metadatas , num_processes = num_processes )
389359
360+ # image_metadatas and video_metadatas get stale after the validation,
361+ # hence delete them to avoid confusion
362+ del image_metadatas
363+ del video_metadatas
364+
390365 _overwrite_exif_tags (
391- # search image metadatas again because some of them might have been failed
366+ # Search image metadatas again because some of them might have been failed
392367 [
393368 metadata
394369 for metadata in metadatas
@@ -426,10 +401,10 @@ def process_finalize(
426401 # write descs first because _show_stats() may raise an exception
427402 _write_metadatas (metadatas , desc_path )
428403
429- # show stats
404+ # Show stats
430405 skipped_process_errors : T .Set [T .Type [Exception ]]
431406 if skip_process_errors :
432- # skip all exceptions
407+ # Skip all exceptions
433408 skipped_process_errors = {Exception }
434409 else :
435410 skipped_process_errors = {exceptions .MapillaryDuplicationError }
0 commit comments