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 f3310dc32..1a06ded3d 100755 Binary files a/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/csv2notion and b/src/plugins/finalcutpro/toolbox/shotdata/csv2notion/csv2notion differ 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)