From 8bbe53fcf694e5a17b32f6c16e6a94d605e67e85 Mon Sep 17 00:00:00 2001 From: Karthik Bekal Pattathana <133984042+karthikbekalp@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:10:57 +0000 Subject: [PATCH] fix: Ensure filenames are encoded in UTF-8. Signed-off-by: Karthik Bekal Pattathana <133984042+karthikbekalp@users.noreply.github.com> --- .../expected_job_bundle/asset_references.yaml | 12 ++ .../expected_job_bundle/parameter_values.yaml | 18 +++ .../expected_job_bundle/template.yaml | 103 ++++++++++++++++++ .../scene/cube.py | 75 +++++++++++++ .../Cinema4DClient/cinema4d_handler.py | 15 +++ 5 files changed, 223 insertions(+) create mode 100644 job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/asset_references.yaml create mode 100644 job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/parameter_values.yaml create mode 100644 job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/template.yaml create mode 100644 job_bundle_output_tests/redshift_textured_with_nonascii_characters/scene/cube.py diff --git a/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/asset_references.yaml b/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/asset_references.yaml new file mode 100644 index 00000000..0ab41ee3 --- /dev/null +++ b/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/asset_references.yaml @@ -0,0 +1,12 @@ +assetReferences: + inputs: + directories: [] + filenames: + - C:\normalized\job\bundle\dir\redshift_textured-_\u20BF_\u0119_\xF1_\u03B2_\u0411\ + _\u062A.c4d + - C:\normalized\job\bundle\dir\tex\checkerboard-_\u20BF_\u0119_\xF1_\u03B2_\u0411\ + _\u062A.bmp + outputs: + directories: + - C:\normalized\job\bundle\dir\renders + referencedPaths: [] diff --git a/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/parameter_values.yaml b/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/parameter_values.yaml new file mode 100644 index 00000000..608d933a --- /dev/null +++ b/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/parameter_values.yaml @@ -0,0 +1,18 @@ +parameterValues: +- name: Cinema4DFile + value: C:\normalized\job\bundle\dir\redshift_textured-_\u20BF_\u0119_\xF1_\u03B2_\u0411\ + _\u062A.c4d +- name: OutputPath + value: C:\normalized\job\bundle\dir\renders\redshift_textured +- name: MultiPassPath + value: '' +- name: Frames + value: '1' +- name: deadline:targetTaskRunStatus + value: READY +- name: deadline:maxFailedTasksCount + value: 20 +- name: deadline:maxRetriesPerTask + value: 5 +- name: deadline:priority + value: 50 diff --git a/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/template.yaml b/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/template.yaml new file mode 100644 index 00000000..3a87c416 --- /dev/null +++ b/job_bundle_output_tests/redshift_textured_with_nonascii_characters/expected_job_bundle/template.yaml @@ -0,0 +1,103 @@ +specificationVersion: jobtemplate-2023-09 +name: physical-_₿_ę_ñ_β_Б_ت.c4d +parameterDefinitions: +- name: Cinema4DFile + type: PATH + objectType: FILE + dataFlow: IN + userInterface: + control: CHOOSE_INPUT_FILE + label: Cinema4D Document File + groupLabel: Cinema4D Settings + fileFilters: + - label: Cinema4D document files + patterns: + - '*.c4d' + - label: All Files + patterns: + - '*' + description: The Cinema4D document file to render. +- name: Frames + type: STRING + userInterface: + control: LINE_EDIT + label: Frames + groupLabel: Cinema4D Settings + description: The frames to render. E.g. 1-3,8,11-15 + minLength: 1 +- name: OutputPath + type: STRING + userInterface: + control: LINE_EDIT + label: Default image output + groupLabel: Cinema4D Settings + description: Image output path +- name: MultiPassPath + type: STRING + userInterface: + control: LINE_EDIT + label: Multi-pass output path + groupLabel: Cinema4D Settings + description: Multi-pass image output +steps: +- name: Main + parameterSpace: + taskParameterDefinitions: + - name: Frame + type: INT + range: '{{Param.Frames}}' + stepEnvironments: + - name: Cinema4D + description: Runs Cinema4D in the background. + script: + embeddedFiles: + - name: initData + filename: init-data.yaml + type: TEXT + data: |- + scene_file: '{{Param.Cinema4DFile}}' + take: 'Main' + output_path: '{{Param.OutputPath}}' + multi_pass_path: '{{Param.MultiPassPath}}' + actions: + onEnter: + command: cinema4d-openjd + args: + - daemon + - start + - --path-mapping-rules + - file://{{Session.PathMappingRulesFile}} + - --connection-file + - '{{Session.WorkingDirectory}}/connection.json' + - --init-data + - file://{{Env.File.initData}} + cancelation: + mode: NOTIFY_THEN_TERMINATE + onExit: + command: cinema4d-openjd + args: + - daemon + - stop + - --connection-file + - '{{ Session.WorkingDirectory }}/connection.json' + cancelation: + mode: NOTIFY_THEN_TERMINATE + script: + embeddedFiles: + - name: runData + filename: run-data.yaml + type: TEXT + data: | + frame: {{Task.Param.Frame}} + actions: + onRun: + command: cinema4d-openjd + args: + - daemon + - run + - --connection-file + - '{{ Session.WorkingDirectory }}/connection.json' + - --run-data + - file://{{ Task.File.runData }} + cancelation: + mode: NOTIFY_THEN_TERMINATE diff --git a/job_bundle_output_tests/redshift_textured_with_nonascii_characters/scene/cube.py b/job_bundle_output_tests/redshift_textured_with_nonascii_characters/scene/cube.py new file mode 100644 index 00000000..a3a0303e --- /dev/null +++ b/job_bundle_output_tests/redshift_textured_with_nonascii_characters/scene/cube.py @@ -0,0 +1,75 @@ +import os +import struct +import c4d + + +def _checkerboard_bmp(filename): + width = 128 + height = 128 + color1 = (255, 255, 255) + color2 = (0, 0, 0) + # BMP file header + file_size = 14 + 40 + (width * height * 3) + file_header = struct.pack("<2sIHHI", b"BM", file_size, 0, 0, 54) + # DIB header + dib_header = struct.pack( + " None: """ Constructor for the c4dpy handler. Initializes action_dict and render variables """ + self.action_dict = { "scene_file": self.set_scene_file, "take": self.set_take, @@ -164,6 +166,16 @@ def set_frame(self, data: dict) -> None: """ self.render_kwargs["frame"] = int(data.get("frame", "")) + def _convert_filename_to_utf8_encoding(self, scene_file: str) -> str: + try: + return scene_file.encode(locale.getpreferredencoding()).decode("utf-8") + except UnicodeError as ue: + print(f"Error: Encoding to UTF-8 failed due to unicode error. Exception: {ue}") + except Exception as e: + print(f"Error: Encoding to UTF-8 failed due to unexpected error. Exception: {e}") + print("Returning scene file string as is as encoding/decoding failed.") + return scene_file + def set_scene_file(self, data: dict) -> None: """ Opens the scene file in Cinema4D. @@ -175,6 +187,9 @@ def set_scene_file(self, data: dict) -> None: FileNotFoundError: If path to the scene file does not yield a file """ scene_file = data.get("scene_file", "") + + scene_file = self._convert_filename_to_utf8_encoding(scene_file) + if not os.path.isfile(scene_file): raise FileNotFoundError(f"The scene file '{scene_file}' does not exist") doc = c4d.documents.LoadDocument(