Skip to content

Commit 8bceb5b

Browse files
committed
fix: Refactor sign_file to use new API internally, but keep the emthod for compatibility
1 parent b3d5926 commit 8bceb5b

23 files changed

+121
-30
lines changed

src/c2pa/c2pa.py

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import Optional, Union, Callable, Any
88
import time
99
from .lib import dynamically_load_library
10+
import mimetypes
1011

1112
# Define required function names
1213
_REQUIRED_FUNCTIONS = [
@@ -16,7 +17,6 @@
1617
'c2pa_load_settings',
1718
'c2pa_read_file',
1819
'c2pa_read_ingredient_file',
19-
'c2pa_sign_file',
2020
'c2pa_reader_from_stream',
2121
'c2pa_reader_from_manifest_data_and_stream',
2222
'c2pa_reader_free',
@@ -247,13 +247,6 @@ def _setup_function(func, argtypes, restype=None):
247247
_setup_function(
248248
_lib.c2pa_read_ingredient_file, [
249249
ctypes.c_char_p, ctypes.c_char_p], ctypes.c_void_p)
250-
_setup_function(_lib.c2pa_sign_file,
251-
[ctypes.c_char_p,
252-
ctypes.c_char_p,
253-
ctypes.c_char_p,
254-
ctypes.POINTER(C2paSignerInfo),
255-
ctypes.c_char_p],
256-
ctypes.c_void_p)
257250

258251
# Set up Reader and Builder function prototypes
259252
_setup_function(_lib.c2pa_reader_from_stream,
@@ -600,31 +593,61 @@ def sign_file(
600593
data_dir: Optional directory to write binary resources to
601594
602595
Returns:
603-
Result information as a JSON string
596+
The signed manifest as a JSON string
604597
605598
Raises:
606599
C2paError: If there was an error signing the file
607600
C2paError.Encoding: If any of the string inputs contain invalid UTF-8 characters
601+
C2paError.NotSupported: If the file type cannot be determined
608602
"""
609-
# Store encoded strings as attributes of signer_info to keep them alive
610603
try:
611-
signer_info._source_str = str(source_path).encode('utf-8')
612-
signer_info._dest_str = str(dest_path).encode('utf-8')
613-
signer_info._manifest_str = manifest.encode('utf-8')
614-
signer_info._data_dir_str = str(data_dir).encode(
615-
'utf-8') if data_dir else None
616-
except UnicodeError as e:
617-
raise C2paError.Encoding(
618-
f"Invalid UTF-8 characters in input strings: {str(e)}")
619-
620-
result = _lib.c2pa_sign_file(
621-
signer_info._source_str,
622-
signer_info._dest_str,
623-
signer_info._manifest_str,
624-
ctypes.byref(signer_info),
625-
signer_info._data_dir_str
626-
)
627-
return _parse_operation_result_for_error(result)
604+
# Create a signer from the signer info
605+
signer = Signer.from_info(signer_info)
606+
607+
# Create a builder from the manifest
608+
builder = Builder(manifest)
609+
610+
# Open source and destination files
611+
with open(source_path, 'rb') as source_file, open(dest_path, 'wb') as dest_file:
612+
# Get the MIME type from the file extension
613+
mime_type = mimetypes.guess_type(str(source_path))[0]
614+
if not mime_type:
615+
raise C2paError.NotSupported(f"Could not determine MIME type for file: {source_path}")
616+
617+
# Sign the file using the builder
618+
manifest_bytes = builder.sign(
619+
signer=signer,
620+
format=mime_type,
621+
source=source_file,
622+
dest=dest_file
623+
)
624+
625+
# If we have manifest bytes and a data directory, write them
626+
if manifest_bytes and data_dir:
627+
manifest_path = os.path.join(str(data_dir), 'manifest.json')
628+
with open(manifest_path, 'wb') as f:
629+
f.write(manifest_bytes)
630+
631+
# Read the signed manifest from the destination file
632+
with Reader(dest_path) as reader:
633+
return reader.json()
634+
635+
except Exception as e:
636+
# Clean up destination file if it exists and there was an error
637+
if os.path.exists(dest_path):
638+
try:
639+
os.remove(dest_path)
640+
except OSError:
641+
pass # Ignore cleanup errors
642+
643+
# Re-raise the error
644+
raise C2paError(f"Error signing file: {str(e)}")
645+
finally:
646+
# Ensure resources are cleaned up
647+
if 'builder' in locals():
648+
builder.close()
649+
if 'signer' in locals():
650+
signer.close()
628651

629652

630653
class Stream:
@@ -958,7 +981,7 @@ def __init__(self,
958981

959982
path = str(format_or_path)
960983
mime_type = mimetypes.guess_type(
961-
path)[0] or 'application/octet-stream'
984+
path)[0]
962985

963986
# Keep mime_type string alive
964987
try:
40.6 KB
Binary file not shown.
50 KB
Binary file not shown.
50 KB
Binary file not shown.
50 KB
Binary file not shown.
50 KB
Binary file not shown.
50 KB
Binary file not shown.
50 KB
Binary file not shown.
50 KB
Binary file not shown.
50 KB
Binary file not shown.

0 commit comments

Comments
 (0)