From 7b10ee19d88b7f859f037cf537d1c8f2f1a3020e Mon Sep 17 00:00:00 2001 From: Chris Hocking Date: Sun, 17 Jul 2022 19:09:44 +1000 Subject: [PATCH] Improvements to Shot Data Toolbox - Added a single "Export Destination" path for Shot Data exports. - `cp.apple.fcpxml.valid()` now handles `.fcpxmld` bundles correctly. - Fixed csv2notion code signing. - Closes #3023 --- scripts/build_commandpost_release.sh | 5 + src/extensions/cp/apple/fcpxml/init.lua | 16 +-- src/extensions/languages/English_en.json | 15 +- .../toolbox/shotdata/csv2notion/csv2notion | Bin 7674224 -> 7675280 bytes .../shotdata/csv2notion/entitlements.plist | 14 ++ .../toolbox/shotdata/html/panel.html | 41 ++++-- .../finalcutpro/toolbox/shotdata/init.lua | 136 +++++++++++------- 7 files changed, 152 insertions(+), 75 deletions(-) create mode 100644 src/plugins/finalcutpro/toolbox/shotdata/csv2notion/entitlements.plist diff --git a/scripts/build_commandpost_release.sh b/scripts/build_commandpost_release.sh index fa1617b91..d5ef67e1e 100755 --- a/scripts/build_commandpost_release.sh +++ b/scripts/build_commandpost_release.sh @@ -142,6 +142,11 @@ echo " * Cleaning up prior to build..." echo " * Building CommandPost-App Docs..." ./scripts/build.sh docs +echo " * Signing csv2notion..." +xattr -cr "${COMMANDPOST_HOME}/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/csv2notion" +codesign --verbose --force --deep --options=runtime --timestamp --entitlements "${COMMANDPOST_HOME}/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/entitlements.plist" --sign "Developer ID Application: LateNite Films Pty Ltd" "${COMMANDPOST_HOME}/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/csv2notion" +codesign -dv --verbose=4 "${COMMANDPOST_HOME}/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/csv2notion" + echo " * Building CommandPost-App..." ./scripts/build.sh build -s Release -c Release -d -u diff --git a/src/extensions/cp/apple/fcpxml/init.lua b/src/extensions/cp/apple/fcpxml/init.lua index 2671da88c..a1b010c79 100644 --- a/src/extensions/cp/apple/fcpxml/init.lua +++ b/src/extensions/cp/apple/fcpxml/init.lua @@ -766,6 +766,14 @@ end --- from the file itself, and if that's not possible, we'll default --- to the latest FCPXML version. function mod.valid(path, version) + -------------------------------------------------------------------------------- + -- Look inside FCPXML Bundles for metadata: + -------------------------------------------------------------------------------- + local extension = tools.getFileExtensionFromPath(path) + if extension and extension == "fcpxmld" then + path = path .. "/Info.fcpxml" + end + -------------------------------------------------------------------------------- -- Make sure the file actually exists: -------------------------------------------------------------------------------- @@ -814,14 +822,6 @@ function mod.valid(path, version) version = semver(mod.latestDTDVersion()) end - -------------------------------------------------------------------------------- - -- Look inside FCPXML Bundles for metadata: - -------------------------------------------------------------------------------- - local extension = tools.getFileExtensionFromPath(path) - if extension and extension == "fcpxmld" then - path = path .. "/Info.fcpxml" - end - -------------------------------------------------------------------------------- -- Use `xmllint` to make sure the file is valid: -------------------------------------------------------------------------------- diff --git a/src/extensions/languages/English_en.json b/src/extensions/languages/English_en.json index 08586df2e..e9eb18fc3 100644 --- a/src/extensions/languages/English_en.json +++ b/src/extensions/languages/English_en.json @@ -236,6 +236,7 @@ "changeDestinationFolder": "Change Destination Folder", "changeDestinationFolderInCompressor": "Change Destination Folder in Compressor", "changeDestinationPreset": "Change Destination Preset", + "changeExportDestination": "Change Export Destination", "changeFilenamesInCompressor": "Change Filenames in Compressor", "changeFinalCutProLanguage": "Changing Final Cut Pro's language requires Final Cut Pro to restart.", "changeLanguageRestart": "Changing languages requires CommandPost to Restart.", @@ -832,6 +833,7 @@ "executeLuaCodeSnippet": "Execute Lua Code Snippet", "expandAudio": "Expand Audio", "exportCSV": "Export CSV", + "exportDestination": "Export Destination", "exportFCPXML": "Export FCPXML", "exportSettings": "Export Settings", "exposure": "Exposure", @@ -844,6 +846,8 @@ "failedToAddCustomApplication": "Failed to add Custom Application.", "failedToAddCustomApplicationDescription": "CommandPost was unable to determine the bundle identifier or display name for the custom application.\n\nPlease provide feedback to the CommandPost team so that they can come up with a fix.", "failedToChangeLanguage": "Unable to change Final Cut Pro's language.", + "failedToCreateExportDestination": "Failed to create Export Destination", + "failedToCreateExportDestinationDescription": "Please ensure that CommandPost has access to the folder you want to save files to and try again.", "failedToFindCommandInCommandEditor": "Failed to find '{command}' in Command Editor.", "failedToLaunchFinalCutPro": "Unable to launch Final Cut Pro.", "failedToProcessFCPXML": "Failed to process FCPXML", @@ -2082,12 +2086,13 @@ "shortcutsSetNoneConfirmation": "This will reset all of the shortcuts to None.", "shotData": "Shot Data", "shotDataDescriptionFive": "The images will be renamed based on the Scene and Shot number in the connected Shot Data Title.", - "shotDataDescriptionFour": "on the timeline (but not in a secondary storyline), you'll be asked for an additional folder to consolidate the images to.", + "shotDataDescriptionFour": "on the timeline (but not in a secondary storyline), these images will be consolidated into the same folder as the CSV.", "shotDataDescriptionOne": "This utility allows you to import a FCPXML which contains one or more Shot Data Titles in a timeline, and converts", - "shotDataDescriptionSix": "This utility was commissioned by Vigneswaran Rajkumar for a feature film project.", + "shotDataDescriptionSix": "This utility was commissioned by Vigneswaran Rajkumar for a feature film project, and is built using vzhd1701's csv2notion.", "shotDataDescriptionThree": "If you have a Shot Data Title on the Primary Storyline, and have a single still image connected directly to it", "shotDataDescriptionTwo": "the data from these Motion Templates into a single CSV file for use in other applications.", - "shotDataDropZone": "You can also drag and drop projects from the Final Cut Pro Browser to here for processing...", + "shotDataDropZone": "You can drag and drop projects from the Final Cut Pro Browser to here for processing...", + "shotDataExportDestinationDescription": "Your Shot Data files will be saved to", "shotDataFailedToInstallTemplate": "Failed to install Shot Data Template.", "shotDataFailedToInstallTemplateDescription": "CommandPost was unable to install the Shot Data Motion Template. This is most likely a permissions issue.", "shotDataFCPXMLFailedDescription": "CommandPost was unable to process the FCPXML. Please make sure the FCPXML contains a single timeline, which contains the Shot Data Titles.", @@ -2222,8 +2227,8 @@ "textPasteboardHistory": "Text Pasteboard History", "textToSpeechDestination": "Please select where you want to save your audio files:", "texture": "Texture", - "theBatchOfFCPXMLsHasBeenExportedSuccessfully": "The batch of FCPXMLs has been exported successfully.", - "theCSVAndConsolidatedImagesHasBeenExportedSuccessfully": "The CSV and consolidated images has been exported successfully.", + "theBatchOfFCPXMLsHasBeenExportedSuccessfully": "The batch of FCPXMLs have been exported successfully.", + "theCSVAndConsolidatedImagesHasBeenExportedSuccessfully": "The CSV and consolidated images have been exported successfully.", "theCSVHasBeenExportedSuccessfully": "The CSV has been exported successfully.", "theOriginalAndNewColumnsCannotBeTheSamePleaseCheckYourSettingsAndTryAgain": "The original and new columns cannot be the same. Please check your settings and try again.", "theSharedFolderCouldNotBeFound": "The Shared Folder could not be found.", diff --git a/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/csv2notion b/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/csv2notion index f3310dc32f9d56e7495ffd2b32cde2b6965ea381..1a06ded3defc69f776fae9920663546edc485412 100755 GIT binary patch delta 10763 zcmc(l2Ut@{*T-{{Py(S>X$eI{Amk>YOHrywS3p!0LlPjgU=lz?y$}@(3P`a4B8Unq zt0-2)j!F>~1=orVMMSZIfQ@%T6Ia)L_j~tq^E^Mp+|10KJ9p;H|D5CN1I?JsraVpbpRgXackV1OO4B4bTDT0`vgm0s4Rm00Y28fFZyL zU<@DuOaNp644?q002;s)UmRsd_jB!CUT7GMVuKKo?A6o3Q35#R)H2DkuR z0aF2PfN21CfCs=6;05po_yBwX(*ZL8egJS=Ic z@B^VFWJHC3F?jLR7!IG!i9t;6#l@_S9@l%hgFSWD>z72CZ@6U0%THQ+>vSVL zu;~(AV&mLr^{=n73-arZOzz}eY)8t$c!dv#0Vsk;24AR60O2*^!+w*PfER${Q7e+@B<5^rDm|R;OiV3VkWW_KzOm<9|t&YE+3&~Q)-cG_s z+sWI}Z@Qc}i?-6pKuD@^d2kc(~0#{D`0vGTGTnho}?I z=f_%;$q5MwCUjvn69y+*Sd&Ng;c{YGTz;Yl=#2y#m@xTF9dMta?!OrixXNTR_;wP+ z;g5|riA3}ZXYp7>I+sP{vKGX#xhy6zl*1*4AnX`Am(Ai4L*m#`d}2r<(I?R@hR3Hz zMX|U<5@}2~k*q{JFreX~@mP#FE}Nfd!r+;J%A5pJ1e6yvq4fYeo4&lE2n|6MDS5CSo`C$tj6%==JPB|9vs!;X zXTrv2c=*SSho%K#k-nc7(C$O4B-jMHMsTtyZg6KwL1O5lWH=cNogxEEiQ?v`PK8() zEE*C)jjaS)6$zx5!2&E67NB1gVbBm7Ev~v~SJ~MO+IV5Z;qD+w&@cp{NWwT#j6YUX z0qsA7q5#VY3la(vgZqT&7Q-;1=)-!#i;@bOLl+&vPGE8rJNPoh;T3C~u$p86dp-Zl`hX`)hl z&X!|lB@&GXPd|J#zq|g$#D&gm_Wa1;HCdkub)QR∓1Yv2s=&8UvxA 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 delta 724 zcmW;KJxmjE7{~Gd^~wp-;=2{_r3$`V;pkm^wR%NRRMcXtA}S&+voPxwU0}3ZIzUbD8G!mX6T+7l3;@jI|`s+5eiX+#VCdYPLyB?mSP!}V+B@X6;{KA zH7G?H%CQ#fupS%W#zt&H1uC%_Td)<|upK+F6T9HSZd9QfDr(?`1|2^5VIY7#2x2ex z!G!hqTI@$1>Tv)E(SSoZj3a2oQ5?f@gwcc(h#-oSIEB+_#u>EWEY9IPT5$nwxQKSd z5Jv|(kw6lca2Z|bMh~u_7b&FChkjh0FhiN&&x0cWT?iq=N+oPUQ>CB(=r_fYsnqU8F`2L+9f$D-lxfj5(7PdtA<`JcJ!{|*jE6u0}; z=iu!-|N4u*ff18uK&7*7}7DC!1|o HdY%6P?M~)J diff --git a/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/entitlements.plist b/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/entitlements.plist new file mode 100644 index 000000000..fe2e16cb4 --- /dev/null +++ b/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/entitlements.plist @@ -0,0 +1,14 @@ + + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + + + \ No newline at end of file diff --git a/src/plugins/finalcutpro/toolbox/shotdata/html/panel.html b/src/plugins/finalcutpro/toolbox/shotdata/html/panel.html index addc425c7..20e765a6e 100644 --- a/src/plugins/finalcutpro/toolbox/shotdata/html/panel.html +++ b/src/plugins/finalcutpro/toolbox/shotdata/html/panel.html @@ -35,6 +35,14 @@ text-align: left; } + .destinationText { + font-weight: bold; + text-align: left; + font-size: 13px; + color: #037ffc; + margin-left: 20px; + } + .notionHelpText { font-size: 9px; font-weight: normal; @@ -218,10 +226,19 @@

{{ i18n("shotData") }}


{{ i18n("shotDataDescriptionSix") }}

- +
+ +
- + +
+
+ +
+
+ +
@@ -232,15 +249,19 @@

{{ i18n("shotData") }}

- - - - + +
+ +

{{ i18n("exportDestination") }}

+ +

{{ i18n("shotDataExportDestinationDescription") }}:

+

+ +
- +
-
- -
+
+ {{ i18n("changeExportDestination") }}
diff --git a/src/plugins/finalcutpro/toolbox/shotdata/init.lua b/src/plugins/finalcutpro/toolbox/shotdata/init.lua index 6fbaf0ce4..83e4bbfd9 100644 --- a/src/plugins/finalcutpro/toolbox/shotdata/init.lua +++ b/src/plugins/finalcutpro/toolbox/shotdata/init.lua @@ -306,15 +306,10 @@ mod.lastOpenPath = config.prop("toolbox.shotdata.lastOpenPath", desktopPath) --- Last upload path mod.lastUploadPath = config.prop("toolbox.shotdata.lastUploadPath", desktopPath) ---- plugins.finalcutpro.toolbox.shotdata.lastSavePath +--- plugins.finalcutpro.toolbox.shotdata.destinationPath --- Field --- Last save path -mod.lastSavePath = config.prop("toolbox.shotdata.lastSavePath", desktopPath) - ---- plugins.finalcutpro.toolbox.shotdata.lastConsolidatePath ---- Field ---- Last folder to consolidate the files to -mod.lastConsolidatePath = config.prop("toolbox.shotdata.lastConsolidatePath", desktopPath) +mod.destinationPath = config.prop("toolbox.shotdata.destinationPath", desktopPath) --- plugins.finalcutpro.toolbox.shotdata.automaticallyUploadCSV --- Field @@ -889,72 +884,80 @@ local function processFCPXML(path) end -------------------------------------------------------------------------------- - -- Make sure last save path still exists, otherwise use Desktop: + -- Make sure the destination path still exists, otherwise use Desktop: -------------------------------------------------------------------------------- - if not doesDirectoryExist(mod.lastSavePath()) then - mod.lastSavePath(desktopPath) + if not doesDirectoryExist(mod.destinationPath()) then + mod.destinationPath(desktopPath) end - local exportPathResult = chooseFileOrFolder(i18n("pleaseSelectAFolderToSaveTheCSVTo") .. ":", mod.lastSavePath(), false, true, false) - local exportPath = exportPathResult and exportPathResult["1"] + local destinationPath = mod.destinationPath() - if exportPath then + if destinationPath then -------------------------------------------------------------------------------- - -- Consolidate images: + -- Make a sub-folder for the year/month/day/time: -------------------------------------------------------------------------------- - local consolidateSuccessful = true - if tableCount(filesToCopy) >= 1 then + local dateFolderName = os.date("%Y%m%d %H%M") + local exportPath = destinationPath .. "/" .. dateFolderName + + if doesDirectoryExist(exportPath) then -------------------------------------------------------------------------------- - -- Make sure last save path still exists, otherwise use Desktop: + -- If the folder already exists, add the seconds as well: -------------------------------------------------------------------------------- - if not doesDirectoryExist(mod.lastConsolidatePath()) then - mod.lastConsolidatePath(desktopPath) - end + dateFolderName = os.date("%Y%m%d %H%M %S") + exportPath = destinationPath .. "/" .. dateFolderName + end - local consolidatePathResult = chooseFileOrFolder(i18n("pleaseSelectAFolderToSaveTheConsolidatedImages") .. ":", mod.lastConsolidatePath(), false, true, false) - local consolidatePath = consolidatePathResult and consolidatePathResult["1"] - if consolidatePath then - mod.lastConsolidatePath(consolidatePath) - for destinationFilename, sourcePath in pairs(filesToCopy) do - local status = false - if doesFileExist(sourcePath) then - -------------------------------------------------------------------------------- - -- Save the image as PNG: - -------------------------------------------------------------------------------- - local originalImage = image.imageFromPath(sourcePath) - if originalImage then - local destinationPath = consolidatePath .. "/" .. destinationFilename .. ".png" - status = originalImage:saveToFile(destinationPath) - end - end - if not status then - consolidateSuccessful = false - log.ef("Failed to copy source file: %s", sourcePath) + if not tools.ensureDirectoryExists(destinationPath, dateFolderName) then + -------------------------------------------------------------------------------- + -- Failed to create the necessary sub-folder: + -------------------------------------------------------------------------------- + webviewAlert(mod._manager.getWebview(), function() end, i18n("failedToCreateExportDestination"), i18n("failedToCreateExportDestinationDescription"), i18n("ok")) + return + end + + -------------------------------------------------------------------------------- + -- Consolidate images: + -------------------------------------------------------------------------------- + local consolidateSuccessful = true + if tableCount(filesToCopy) >= 1 then + for destinationFilename, sourcePath in pairs(filesToCopy) do + local status = false + if doesFileExist(sourcePath) then + -------------------------------------------------------------------------------- + -- Save the image as PNG: + -------------------------------------------------------------------------------- + local originalImage = image.imageFromPath(sourcePath) + if originalImage then + local destinationPath = exportPath .. "/" .. destinationFilename .. ".png" + status = originalImage:saveToFile(destinationPath) end end + if not status then + consolidateSuccessful = false + log.ef("Failed to copy source file: %s", sourcePath) + end end end - mod.lastSavePath(exportPath) local exportedFilePath = exportPath .. "/" .. originalFilename .. ".csv" writeToFile(exportedFilePath, output) if consolidateSuccessful then - if tableCount(filesToCopy) >= 1 then - webviewAlert(mod._manager.getWebview(), function() end, i18n("success") .. "!", i18n("theCSVAndConsolidatedImagesHasBeenExportedSuccessfully"), i18n("ok")) + -------------------------------------------------------------------------------- + -- Upload to Notion: + -------------------------------------------------------------------------------- + if mod.automaticallyUploadCSV() then + uploadToNotion(exportedFilePath) else - webviewAlert(mod._manager.getWebview(), function() end, i18n("success") .. "!", i18n("theCSVHasBeenExportedSuccessfully"), i18n("ok")) + if tableCount(filesToCopy) >= 1 then + webviewAlert(mod._manager.getWebview(), function() end, i18n("success") .. "!", i18n("theCSVAndConsolidatedImagesHasBeenExportedSuccessfully"), i18n("ok")) + else + webviewAlert(mod._manager.getWebview(), function() end, i18n("success") .. "!", i18n("theCSVHasBeenExportedSuccessfully"), i18n("ok")) + end end else webviewAlert(mod._manager.getWebview(), function() end, i18n("someErrorsHaveOccurred"), i18n("csvExportedSuccessfullyImagesCouldNotBeConsolidated"), i18n("ok")) end - - -------------------------------------------------------------------------------- - -- Upload to Notion: - -------------------------------------------------------------------------------- - if mod.automaticallyUploadCSV() then - uploadToNotion(exportedFilePath) - end end else webviewAlert(mod._manager.getWebview(), function() end, i18n("invalidFCPXMLFile"), i18n("theSuppliedFCPXMLDidNotPassDtdValidationPleaseCheckThatTheFCPXMLSuppliedIsValidAndTryAgain"), i18n("ok"), nil, "warning") @@ -1014,6 +1017,13 @@ end -- Returns: -- * None local function updateUI() + -------------------------------------------------------------------------------- + -- Make sure the destination path still exists, otherwise use Desktop: + -------------------------------------------------------------------------------- + if not doesDirectoryExist(mod.destinationPath()) then + mod.destinationPath(desktopPath) + end + local injectScript = mod._manager.injectScript local script = "" script = script .. [[ @@ -1024,6 +1034,7 @@ local function updateUI() changeValueByID("token", "]] .. mod.token() .. [["); changeValueByID("databaseURL", "]] .. mod.databaseURL() .. [["); changeValueByID("defaultEmoji", "]] .. mod.defaultEmoji() .. [["); + changeInnerHTMLByID("destinationPath", `]] .. mod.destinationPath() .. [[`); ]] local ignoreColumns = mod.ignoreColumns() @@ -1162,7 +1173,6 @@ local function callback(id, params) -------------------------------------------------------------------------------- -- Load Settings: -------------------------------------------------------------------------------- - local menu = {} local settings = mod.settings() @@ -1227,6 +1237,28 @@ local function callback(id, params) mod.settings(settings) end + elseif callbackType == "changeExportDestination" then + -------------------------------------------------------------------------------- + -- Change Export Destination: + -------------------------------------------------------------------------------- + if not doesDirectoryExist(mod.destinationPath()) then + -------------------------------------------------------------------------------- + -- Make sure the destination path still exists, otherwise use Desktop: + -------------------------------------------------------------------------------- + mod.destinationPath(desktopPath) + end + + local destinationPathResult = chooseFileOrFolder(i18n("pleaseSelectAFolderToSaveTheCSVTo") .. ":", mod.destinationPath(), false, true, false) + local destinationPath = destinationPathResult and destinationPathResult["1"] + + if destinationPath then + mod.destinationPath(destinationPath) + end + + -------------------------------------------------------------------------------- + -- Update the user interface: + -------------------------------------------------------------------------------- + updateUI() else -------------------------------------------------------------------------------- -- Unknown Callback: @@ -1266,7 +1298,7 @@ function plugin.init(deps, env) label = i18n("shotData"), image = image.imageFromPath(env:pathToAbsolute("/images/XML.icns")), tooltip = i18n("shotData"), - height = 935, + height = 1070, }) :addContent(1, generateContent, false)