Can not run script more than once in Darktable

Hi,
I am new in LUA sctipts, and try to write an import script based on selected images path.
First I’d like to write a test script “import_and_group.lua” to see I can get the paths.
The symptom:

  1. when I start DT, the script runs immediatelly
  2. the “selected_images.log” file created
  3. in the script manager I see: “import_and_group stopped”
  4. whether if I select other images or not, after clicking on the name of the script in the script manager it changes to: “import_and_group started
  5. the log file don’t changes (if I delete previously, not created again)
  6. can’t stop the script → clicking on the script name again, still stays: “import_and_group started

This is the script:

darktable = require "darktable"
-- Open file to write
local logFileName = "d:/selected_images.log"
local file = io.open(logFileName, "a")

if file then
  -- Write selected images path to file
  local selectedImages = darktable.gui.selection()
  if selectedImages then
    file:write("Selected images path:\n")
    for _, image in pairs(selectedImages) do
      file:write(image.path, "\n")
    end
  else
    file:write("There are no selected images in the Lighttable.\n")
  end
	
  file:close()

end

local script_data = {}
script_data.destroy = destroy
return script_data

What is wrong with the script?

Thank you

It doesn’t work? :smile:

When script_manager starts it finds all the scripts, then for each one checks whether it was running or not when darktable stopped. If it was running, then darktable starts it again. Since the script is written to run and be done, it exits. Actually in this case it errors at the end because you referenced a function that didn’t exist, i.e. destroy()

because an error was encountered

The status is set to start so the next time darktable loads, the script will be started. When you click to stop the script, it can’t do it because the destroy() function doesn’t exist.

That’s because the script is still loaded, but has already run (at startup). The lua scripts don’t reload when they are stopped and started.

Here’s a version with the missing piece (destroy()) and a shortcut that you can assign a key to so that you can have the script log multiple times.

darktable = require "darktable"

local MODULE = "my_script_name"

local function create_selected_images_log()
  -- Open file to write
  local logFileName = "d:/selected_images.log"
  local file = io.open(logFileName, "a")

  if file then
    -- Write selected images path to file
    local selectedImages = darktable.gui.selection()
    if selectedImages then
      file:write("Selected images path:\n")
      for _, image in pairs(selectedImages) do
        file:write(image.path, "\n")
      end
    else
      file:write("There are no selected images in the Lighttable.\n")
    end
  	
    file:close()

  end
end

-- function to actually destroy the things that need destroyed
--   before the script ends
local function destroy()
  -- destroy what you need to here
  -- since the original script didn't have anything to destroy you could either
  --   have an empty function or do script_data.destroy = nil

  -- but now we've added a shortcut event, so that should be destroyed before the
  --   script exits
  darktable.destroy_event(MODULE .. "_log_selected_images", "shortcut")
end

-- create a shortcut that can have a keystroke assigned to it to cause
--   the selection to get logged.
darktable.register_event(MODULE .. "_log_selected_images", "shortcut",
  function(event, shortcut)
    create_selected_images_log()
  end
)

local script_data = {}
-- this is a function that gets called to destroy the script
script_data.destroy = destroy
return script_data
2 Likes

Thank you for the detailed description and the script.
Two questions:

  • how can I assing the shortcut key?
  • when I click on the name of the script in script manager it says “failed to load”… do I need to add something to the script?

Thank you

1 Like

Oops, left out an argument

darktable = require "darktable"

local MODULE = "my_script_name"

local function create_selected_images_log()
  -- Open file to write
  local logFileName = "d:/selected_images.log"
  local file = io.open(logFileName, "a")

  if file then
    -- Write selected images path to file
    local selectedImages = darktable.gui.selection()
    if selectedImages then
      file:write("Selected images path:\n")
      for _, image in pairs(selectedImages) do
        file:write(image.path, "\n")
      end
    else
      file:write("There are no selected images in the Lighttable.\n")
    end
  	
    file:close()

  end
end

-- function to actually destroy the things that need destroyed
--   before the script ends
local function destroy()
  -- destroy what you need to here
  -- since the original script didn't have anything to destroy you could either
  --   have an empty function or do script_data.destroy = nil

  -- but now we've added a shortcut event, so that should be destroyed before the
  --   script exits
  darktable.destroy_event(MODULE .. "_log_selected_images", "shortcut")
end

-- create a shortcut that can have a keystroke assigned to it to cause
--   the selection to get logged.
darktable.register_event(MODULE .. "_log_selected_images", "shortcut",
  function(event, shortcut)
    create_selected_images_log()
  end, "Log Selected Images"
)

local script_data = {}
-- this is a function that gets called to destroy the script
script_data.destroy = destroy
return script_data

you can assign the shortcut by clicking on the settings icon in darktable, then going to shortcuts, then going to lua scripts. Double click on the shortcut and assign a key

2 Likes

Perfect! Thank you very much :wink:

2 Likes