""" Example function for use with osxphotos export --post-function option """ from __future__ import annotations import pathlib from typing import Any, Callable from osxphotos import ExportResults, PhotoInfo from osxphotos.cli import echo_error def post_function( photo: PhotoInfo, results: ExportResults, verbose: Callable[[Any], None], **kwargs ) -> ExportResults | None: """Call this with osxphotos export /path/to/export --post-function post_function.py::post_function This will get called immediately after the photo has been exported Args: photo: PhotoInfo instance for the photo that's just been exported see https://rhettbull.github.io/osxphotos/reference.html#osxphotos.PhotoInfo for details results: ExportResults instance with information about the files associated with the exported photo see https://rhettbull.github.io/osxphotos/reference.html#osxphotos.ExportResults for details verbose: A function to print verbose output if --verbose is set; if --verbose is not set, acts as a no-op (nothing gets printed) **kwargs: reserved for future use; recommend you include **kwargs so your function still works if additional arguments are added in future versions Returns: ExportResults instance or None If returning an ExportResults instance, it must be a new instance; do not modify the instance passed in as an argument. You should set only the following values in ExportResults: user_written: list[str], list of files written by your function user_skipped: list[str], list of files skipped by your function user_error: list[tuple[str, str]], list of tuples of (filename, error) for any errors generated by your function For full description of ExportResults see: https://rhettbull.github.io/osxphotos/reference.html#osxphotos.ExportResults Notes: Use verbose(str) instead of print if you want your function to conditionally output text depending on --verbose flag Any string printed with verbose that contains "warning" or "error" (case-insensitive) will be printed with the appropriate warning or error color The function will not be called if --dry-run flag is enabled The function be called immediately after export and before any --post-command commands are executed If your function does not write any files, you can optionally return None instead of an ExportResults instance If you return ExportResults, any files in user_written or user_skipped will be included when writing reports and will be preserved when using --cleanup If you want files previously written by the post_function, but not written this time, to be preserved when using --cleanup, you should include them in user_skipped If the function raises an exception, osxphotos will abort the export and exit with an error. If you want the export to continue, you should catch any exceptions and return an ExportResults instance with the error(s) in specified in ExportResults.user_error which is a list of tuples of (filename, error) The verbose function can be used to print text to stdout if --verbose is set If --verbose is not set, verbose acts as a no-op (nothing gets printed) Verbose output may be stylized with tags as follows; tags must be enclosed in square brackets and closed with [/] to end the style: [change]: something change [no_change]: indicate no change [count]: a count [error]: an error [filename]: a filename [filepath]: a filepath [num]: a number [time]: a time or date [tz]: a timezone [warning]: a warning [uuid]: a uuid """ post_results = ExportResults() for filename in results.exported + results.skipped: # do your processing here # simulate doing some processing new_filename = pathlib.Path(f"{filename}.new") if new_filename.exists(): verbose(f"Skipping file [filepath]{new_filename}[/] as it already exists") post_results.user_skipped.append(new_filename) else: verbose(f"Writing new file [filepath]{new_filename}[/]") new_filename.touch() post_results.user_written.append(new_filename) # if you encounter an error, add it to user_error # echo_error will print the error to stderr with the appropriate formatting # echo_error(f"Encountered an error processing [filepath]{filename}[/]: [error]some error[/]") # post_results.user_error.append((filename, "some error")) # if your function does not write any files, you can return None return post_results