local Require = require "Require".path ("../common") local Debug = require "Debug".init () require "strict" -- Access the Lightroom SDK namespaces. local LrDialogs = import 'LrDialogs' local LrFunctionContext = import 'LrFunctionContext' local LrBinding = import 'LrBinding' local LrView = import 'LrView' local LrApplication = import 'LrApplication' local LrExportSession = import 'LrExportSession' local LrTasks = import 'LrTasks' local catalog = LrApplication.activeCatalog() local showErrors = Debug.showErrors -- Process pictures and save them as JPEG local function processPhotos(photos, outputFolderPath) LrFunctionContext.callWithContext("export", showErrors (function(context) local progressScope = LrDialogs.showModalProgressDialog({ title = "Auto applying presets", caption = "", cannotCancel = false, functionContext = context }) local exportSession = LrExportSession({ photosToExport = photos, exportSettings = { LR_collisionHandling = "rename", LR_export_bitDepth = "8", LR_export_colorSpace = "sRGB", LR_export_destinationPathPrefix = outputFolderPath, LR_export_destinationType = "specificFolder", LR_export_useSubfolder = false, LR_format = "JPEG", LR_jpeg_quality = 1, LR_minimizeEmbeddedMetadata = true, LR_outputSharpeningOn = false, LR_reimportExportedPhoto = false, LR_renamingTokensOn = true, -- LR_size_doConstrain = true, LR_size_doNotEnlarge = true, -- LR_size_maxHeight = 2000, -- LR_size_maxWidth = 2000, -- LR_size_resolution = 72, LR_size_units = "pixels", LR_tokens = "{{image_name}}", LR_useWatermark = true, LR_watermarking_id = "26AD02C4-3781-45BF-A629-F8E8AA44C932", } }) local numPhotos = exportSession:countRenditions() local renditionParams = { progressScope = progressScope, renderProgressPortion = 1, stopIfCanceled = true, } for i, rendition in exportSession:renditions(renditionParams) do -- Stop processing if the cancel button has been pressed if progressScope:isCanceled() then break end -- Common caption for progress bar local progressCaption = rendition.photo:getFormattedMetadata("fileName") .. " (" .. i .. "/" .. numPhotos .. ")" progressScope:setPortionComplete(i - 1, numPhotos) progressScope:setCaption("Processing " .. progressCaption) rendition:waitForRender() end end)) end -- Import pictures from folder where the rating is not 2 stars local function importFolder(folderPath, outputFolderPath) LrTasks.startAsyncTask(showErrors (function() local folder = catalog:getFolderByPath (folderPath) local outputFolder = catalog:getFolderByPath (outputFolderPath) local presetFolders = LrApplication.developPresetFolders() local presetFolder = presetFolders[1] local presets = presetFolder:getDevelopPresets() local export = {} for _, photo in pairs(folder:getPhotos()) do if photo:getRawMetadata("rating") ~= 2 then catalog:withWriteAccessDo("Apply Preset", showErrors (function() for _, preset in pairs(presets) do photo:applyDevelopPreset(preset) end photo:setRawMetadata("rating", 2) table.insert(export, photo) end), {timeout = 30}) end end if #export > 0 then processPhotos(export, outputFolderPath) end end)) end -- GUI specification local function customPicker(context) local props = LrBinding.makePropertyTable(context) local f = LrView.osFactory() props.status = "Not started" props.folderPath = "/Users/john/Desktop/test-pics" props.outputFolderPath = "/Users/john/Desktop/hendik" local folderItems = {} for _, folder in ipairs (catalog:getFolders()) do table.insert (folderItems, folder:getPath()) end local watcherRunning = false -- Watcher, executes function and then sleeps 60 seconds using PowerShell local function watch() LrTasks.startAsyncTask(showErrors (function() while watcherRunning do LrDialogs.showBezel("Processing images.") importFolder(props.folderPath, props.outputFolderPath) if LrTasks.canYield() then LrTasks.yield() end LrTasks.sleep (3) end end)) end local c = f:column { bind_to_object = props, spacing = f:dialog_spacing(), f:row { fill_horizontal = 1, f:static_text { alignment = "right", width = LrView.share "label_width", title = "Watcher running: " }, f:static_text { width_in_chars = 25, title = LrView.bind "status" } }, f:row { f:static_text { alignment = "right", width = LrView.share "label_width", title = "Select folder: " }, f:combo_box { items = folderItems, value = LrView.bind "folderPath" } }, f:row { f:static_text { alignment = "right", width = LrView.share "label_width", title = "Output folder: " }, f:combo_box { items = {}, value = LrView.bind "outputFolderPath" } }, f:row { f:push_button { title = "Process once", action = showErrors (function() if props.folderPath ~= "" and props.folderPath ~= nil then props.status = "Processed once" importFolder(props.folderPath, props.outputFolderPath) else LrDialogs.message("Please select an input folder") end end) }, f:push_button { title = "Watch every 3s", action = showErrors (function() watcherRunning = true if props.folderPath ~= "" and props.folderPath ~= nil then props.status = "Running" watch() else LrDialogs.message("Please select an input folder") end end) }, f:push_button { title = "Pause watcher", action = showErrors (function() watcherRunning = false props.myObservedString = "Stopped after running" end) } }, } LrDialogs.presentModalDialog { title = "Auto Export fullsize Watcher", contents = c, -- Preferrably cancel should stop the script -- OK can be changed to run in background -- actionBinding = { -- enabled = { -- bind_to_object = props, -- key = 'actionDisabled' -- }, -- } } end Debug.pause(false) LrFunctionContext.postAsyncTaskWithContext ("", showErrors (customPicker))