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") }}:
+
+
+
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)