Copy link to clipboard
Copied
Hi I'm trying to write a lightroom classic plugin, and I am having a hard time simply saving metadata to a photo. In my test plugin i am simply trying to set a rating to a photo, but the saving keeps failing. Of course i know you can do this in lightroom, but this is just a test for something later. thank you for any advice someone can give.
the full plugin code is here https://github.com/radialmonster/lr-image-rater
Here's your previous script modified so the Rate 1 button works. Changes:
1. Integrated with the debugging toolkit. Debug.showErrors() wraps every function passed back into the SDK API. That allows errors to be displayed rather than silently discarded.
2. The action for the "Rate 1" button calls setRating() in an async task.
3. In setRating(), LrTasks.pcall() is used instead of the Lua built-in pcall(). The built-in pcall() interferes with LR's tasking and the called function is always invoked
...Copy link to clipboard
Copied
[This post contains formatting and embedded images that don't appear in email. View the post in your Web browser.]
There are a couple of errors:
1. The variable "LrFunctionContext" isn't defined -- it needs to be imported:
2. catalog:withWriteAccessDo() needs to be called from an async task. It's invoked by the action callback passed to f:push_button(), and such callbacks are always invoked from LR's main task:
You're not seeing these errors because by default, plugin tasks don't have any error handlers -- LR just silently throws away the error and terminates the task!
I strongly recommend that you use either the Zerobrane IDE or my very lightweight Lightroom Debugging Toolkit. Zerobrane is a full-fledged IDE, but it doesn't know about LR's task architecture, whereas the Toolkit does. Both require the same level of annotating your code to support error handling, break points, and stepping.
Copy link to clipboard
Copied
I know this may be very simple however I am limited to a little bit of knowledge and help with AI. I am spinning wheels here. I have given your directions and still spinning. I have whittled it down a simple test to just set a 3 star rating or cancel buttons. but i keep getting messages about either the
An internal error has occurred: LrCatalog:withWriteAccessDo: could not execute action 'Set Rating'. It was blocked by another write access call, and no timeout parameters were provided.
Or if I get past that I get a message about it failing to yield or something like that.
I have previously tried to integrate your toolkit also and it really messed up the code i had trying to integrate that. I had the rest of my plugin features working like i wanted, but it would not save the data. I will literally pay you to help me. I just want a simple plugin to select 1 photo, a box pops up and shows buttons for Rate 1, Rate 2, Rate 3, Rate 4, Rate 5, Clear Rating, Cancel. and the user clicks their choice and it does that and closes the box. the catalog should immedietly show the new rating on the photo. you can do a new one or modify the existing one. dm me a quote if you would be open to do that. thank you so much
Copy link to clipboard
Copied
Here's your previous script modified so the Rate 1 button works. Changes:
1. Integrated with the debugging toolkit. Debug.showErrors() wraps every function passed back into the SDK API. That allows errors to be displayed rather than silently discarded.
2. The action for the "Rate 1" button calls setRating() in an async task.
3. In setRating(), LrTasks.pcall() is used instead of the Lua built-in pcall(). The built-in pcall() interferes with LR's tasking and the called function is always invoked in the main task. The documentation for this is buried in the API reference for LrTasks.
4. The action for "Rate 1" was calling LrDialogs.stopModalWithResult (contents, ...). But "contents" wasn't yet defined:
local contents = ... stopModalWithResult (contents, ...) ...
(The local variable "contents" isn't defined until after the "local" statement.)
Here's the modified script:
local Require = require 'Require'.path ("../common")
local Debug = require 'Debug'.init ()
require 'strict'
local LrApplication = import 'LrApplication'
local LrDialogs = import 'LrDialogs'
local LrFunctionContext = import 'LrFunctionContext'
local LrTasks = import 'LrTasks'
local LrView = import 'LrView'
local LrLogger = import 'LrLogger'
local showErrors = Debug.showErrors
-- Initialize logger with default Lightroom log location
local logger = LrLogger('ImageRaterLogger')
logger:enable("logfile")
logger:info("Logger initialized.")
LrDialogs.message("Logger initialized.") -- Debug message
-- Function to set a rating
local function setRating(rating)
LrDialogs.message("setRating function called with rating: " .. (rating or "nil")) -- Debug message
local catalog = LrApplication.activeCatalog()
local photo = catalog:getTargetPhoto()
if photo then
LrDialogs.message("Photo selected. Attempting to set rating: " .. (rating or "nil")) -- Debug message
LrFunctionContext.callWithContext("Set Rating Context 1", showErrors (function(context)
end))
LrFunctionContext.callWithContext("Set Rating Context", showErrors (function(context)
local success, err = LrTasks.pcall(showErrors (function()
catalog:withWriteAccessDo("Set Rating", function()
photo:setRawMetadata('rating', rating)
end, {
timeout = 1, -- Wait for up to 1 second for write access
callback = function()
LrDialogs.message("Write access timeout. Could not set rating.") -- Debug message
end
})
end))
if success then
LrDialogs.message("Rating set successfully.") -- Debug message
else
LrDialogs.message("Failed to set rating: " .. (err or "Unknown error")) -- Debug message
end
local message = rating and ("Rated " .. rating .. " stars") or "Rating cleared"
LrDialogs.showBezel(message)
end))
else
LrDialogs.message("No photo selected. Cannot set rating.") -- Debug message
end
end
-- Show the rating dialog
local function showRater()
local catalog = LrApplication.activeCatalog()
if not catalog then
logger:info("No active catalog found.")
LrDialogs.message("No active catalog found.") -- Debug message
return
end
local photo = catalog:getTargetPhoto()
if not photo then
logger:info("No photo selected in catalog.")
LrDialogs.message("No photo selected in catalog.") -- Debug message
LrDialogs.message("Please select a photo", "No photo selected", "info")
return
end
logger:info("Photo selected. Showing rating dialog.")
LrDialogs.message("Photo selected. Showing rating dialog.") -- Debug message
local f = LrView.osFactory()
local contents
contents = f:column {
spacing = f:control_spacing(),
f:row {
f:push_button {
title = "Rate 1",
action = showErrors (function()
LrTasks.startAsyncTask (showErrors (function ()
LrDialogs.message("Rate 1 button clicked") -- Debug message
setRating(1)
LrDialogs.stopModalWithResult(contents, "ok")
end))
end),
},
f:push_button {
title = "Rate 2",
action = function()
LrDialogs.message("Rate 2 button clicked") -- Debug message
setRating(2)
LrDialogs.stopModalWithResult(contents, "ok")
end,
},
f:push_button {
title = "Rate 3",
action = function()
LrDialogs.message("Rate 3 button clicked") -- Debug message
setRating(3)
LrDialogs.stopModalWithResult(contents, "ok")
end,
},
},
f:row {
f:push_button {
title = "Rate 4",
action = function()
LrDialogs.message("Rate 4 button clicked") -- Debug message
setRating(4)
LrDialogs.stopModalWithResult(contents, "ok")
end,
},
f:push_button {
title = "Rate 5",
action = function()
LrDialogs.message("Rate 5 button clicked") -- Debug message
setRating(5)
LrDialogs.stopModalWithResult(contents, "ok")
end,
},
f:push_button {
title = "Clear Rating",
action = function()
LrDialogs.message("Clear Rating button clicked") -- Debug message
setRating(nil)
LrDialogs.stopModalWithResult(contents, "ok")
end,
},
},
}
LrDialogs.presentModalDialog({
title = "Rate Image",
contents = contents,
})
end
-- Start the task
LrTasks.startAsyncTask(showErrors (showRater))
Copy link to clipboard
Copied
This works! Let me play with this a bit to test out thxxxxxxxxxxxxxx
Copy link to clipboard
Copied
I'm in a very good point I just need to finish some more items and I'll share my plugin to you. Bedtime now though thxxxx
Copy link to clipboard
Copied
OK I have finished (for now) my plugin! I would be honored if you wanted to check it out
https://github.com/radialmonster/lr-image-rater
I don't like Lightroom's Compare feature. So I made my own. You compare images, and it will assign ratings to them. If you try it and have any issues or suggestions please let me know. thxxx