I’m developing lua scripts for darktable. I have one problem at the moment I don’t know how to solve. It looks like I have to restart darktable every time I made a change to my script, for the new version to become active. This is a real pain in the butt !
Is there a way to get darktable to reload a script without restarting it ?
Only if the script tells script_manager how to stop it (and it’s not a lib).
Here’s a minimal script that can be stopped, edited, and restarted with the changes taking effect without having to restart darktable.
local dt = require "darktable"
local script_data = {}
local function destroy()
dt.print_log("destroying shutdown")
end
script_data.destroy = destroy
dt.print("this is a different sentence to see if I can see the print")
dt.control.sleep(5000)
return script_data
You can start the script in darktable, open it in an editor, change the message, stop it, start it, and then see the changed message.
Any register_ function called in the script (register_action, register_selection, register_event, register_storage) must call the corresponding destroy_ function in the destroy() routine as part of removing the script from the running darktable. Scripts that show how to do that are:
contrib/clear_GPS.lua
contrib/gimp.lua
contrib/select_untagged.lua
The exception to this is register_lib. I haven’t figured out the darktable code for destroying a lib yet, so at present it gets hidden when it is turned off and shown when it is turned on (reference examples/moduleExample.lua).
One more question / problem. I do use register_storage. There is one callback for initializing. I use that that the paramaters (target directory) actually work and are accessible.
The way it is supposed to work is that you return an empty array (of images). But I’m unable to do that. If I use
return {}
Darktable just crashes. How do I return an empty array to signal that there is nothing to do / export ?
local function destroy()
-- destroy any register_ items
end
local script_data = {}
script_data.destroy = destroy
return script_data
script_data is a table of data about how to handle the script that gets returned to script_manager when it starts the script. I just chose script_data as the name, but you could name it anything.
Unfortunately that does not work as the return goes back to darktable and is part of the API. Returning nothing or nil tells darktable that everything is ok and that is should run the export subroutine for each exported image. Returning and empty table tells Darktable that there is nothing to export. This is how it is documented on the Darktable documentation.
local script_data = {}
script_data.destroy = local function()
-- destroy any register_ items
end
return script_data
In other words suppose you had
local function function_with_a_really_long_name_that_i_dont_want_to_type_every_time()
-- do something
end
local short_name = function_with_a_really_long_name_that_i_dont_want_to_type_every_time
Now every time I call short_name()function_with_a_really_long_name_that_i_dont_want_to_type_every_time gets called
Yes, I have the darktable lua documentation open. Unfortunately is has no snippets on how to use stuff and the is my first go at lua.
local function initialize_export(storage, format, images, high_quality, extra_data)
if not file_exists(pa_path.text) then
dt.print_hinter("Error: Target path '"..pa_path.text.."' does not exist !")
return -- This return should return an empty table
end
end
dt.register_storage("pa_export","Export to photoarchive",
export_file,
--nil,
nil,
initialize_export,
dt.new_widget("box") {
orientation ="horizontal",
dt.new_widget("label"){label = "Photoarchive path "}, pa_path,
}
)
The best place for understanding how the scripts work, is the scripts themselves. Find scripts that use register_storage and see how they used it. Run the script and see how it works. The scripts are located in your darktable configuration directory (in the lua subdirectory) or at GitHub - darktable-org/lua-scripts.
Most of time you only need the finalize step for a storage, unless you are trying to do something tricky. See contrib/gimp.lua
Your other question
Tables are simply arrays of whatever you put in them.
And finally your script should be
local function export_file(storage, images, extra_data)
if not file_exists(pa_path.text) then
dt.print_hinter("Error: Target path '"..pa_path.text.."' does not exist !")
return -- This return should return without doing anything
else
for _, image in ipairs(images) do
-- export the image
end
end
dt.register_storage("pa_export","Export to photoarchive",
export_file,
nil,
nil,
dt.new_widget("box") {
orientation ="horizontal",
dt.new_widget("label"){label = "Photoarchive path "}, pa_path,
}
)