summary history branches tags files
commit:b77a970f99c13fc21a2e47412536291f48673b9d
author:Trevor Bentley
committer:Trevor Bentley
date:Mon Jan 13 19:58:38 2025 +0100
parents:4f7c5318327fff465143b6db459608e2246dacdd
add darktable lua plugin
diff --git a/darktable/photo-what-what.lua b/darktable/photo-what-what.lua
line changes: +178/-0
index 0000000..d06580d
--- /dev/null
+++ b/darktable/photo-what-what.lua
@@ -0,0 +1,178 @@
+--[[
+   photo-what-what.lua - pww plugin for Darktable
+
+   Copyright (C) 2025 Trevor Bentley <pww@x.mrmekon.com>.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+]]
+--[[
+   photo-what-what - use pww to automatically tag selected image(s)
+
+   This launches pww, a utility for automatic image tagging, which
+   analyzes the image and attaches new tags based on its content.
+   These new tags are then imported into Darktable.
+
+   ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
+   * photo-what-what
+   * libexiv2
+   * libgexiv2
+   * libopenimageio
+   * any application that outputs a list of image tags
+
+   USAGE
+   * install & configure pww so it works with `photo-what-what <img>`
+     - or change default paths in darktable settings
+   * copy this script into darktable's lua/contrib/ directory
+   * require this script in darktable's luarc config file
+   * select one or more images
+   * click the "auto-tag images (pww)" button
+
+   BUGS, COMMENTS, SUGGESTIONS
+   * Send to Trevor Bentley: pww@x.mrmekon.com
+
+   CHANGES
+   * 2025-01-13: initial implementation
+]]
+
+local dt = require "darktable"
+local du = require "lib/dtutils"
+local dlog = require "lib/dtutils.log"
+local dsys = require 'lib/dtutils.system'
+
+local namespace <const> = "photo-what-what"
+local LOG_LEVEL <const> = dlog.info
+
+local gettext = dt.gettext.gettext
+
+local function _(msgid)
+    return gettext(msgid)
+end
+
+-- return data structure for script_manager
+local script_data = {}
+
+script_data.metadata = {
+  name = _("photo-what-what"),
+  purpose = _("automatically tag image(s) with photo-what-what analysis tool"),
+  author = "Trevor Bentley <pww@x.mmekon.com>",
+  help = ""
+}
+
+script_data.destroy = nil
+script_data.destroy_method = nil
+script_data.restart = nil
+script_data.show = nil
+
+du.check_min_api_version("9.0.0", "photo-what-what")
+
+local PS <const> = dt.configuration.running_os == "windows" and "\\" or "/"
+
+local settings = {
+   pww_bin_path = {},
+   pww_script_path = {},
+}
+
+local function default_to(value, default)
+    if value == 0 or value == "" then
+        return default
+    end
+    return value
+end
+
+local function load_preferences()
+   settings.pww_bin_path = default_to(dt.preferences.read(namespace, "pww_bin_path", "string"), "photo-what-what")
+   settings.pww_script_path = default_to(dt.preferences.read(namespace, "pww_script_path", "string"), "")
+end
+
+
+local job
+local function stop_job(job)
+   if job then
+      job.valid = false
+   end
+end
+
+local function call_pww(images)
+   load_preferences()
+   local selection = dt.gui.selection()
+
+   -- process each selected image
+   job = dt.gui.create_job(_("pww auto-tagging"), true, stop_job)
+   for idx, image in ipairs(images) do
+      if not job.valid then
+         break
+      end
+      job.percent = ((idx-1) / #images)
+
+      -- I can't believe DT doesn't do this for us
+      local file = image.path .. PS .. image.filename
+
+      -- build up command from strings.  yucky.
+      local cmd = settings.pww_bin_path
+      cmd = string.format("%s -e", cmd)
+      if settings.pww_script_path ~= "" then
+         cmd = string.format("%s -b \"%s\"", cmd, settings.pww_script_path)
+      end
+      cmd = string.format("%s \"%s\"", cmd, file)
+
+      -- run pww
+      local resp = dsys.external_command(cmd)
+      if resp ~= 0 then
+         dt.print("error running photo-what-what")
+         if job.valid then
+            job.valid = false
+         end
+         break
+      end
+
+      -- re-import file to read the updated metadata, since it was changed outside of darktable.
+      -- This does not change the image ID.
+      dt.database.import(file)
+      -- re-select the same selection, since importing clears it
+      dt.gui.selection(selection)
+   end
+
+   if job.valid then
+      job.valid = false
+   end
+end
+
+local function destroy()
+  dt.destroy_event("photo-what-what", "shortcut")
+  dt.gui.libs.image.destroy_action("photo-what-what")
+end
+
+script_data.destroy = destroy
+
+load_preferences()
+
+-- register preferences in darktable settings
+dt.preferences.register(namespace, "pww_script_path", "string", "pww script path", "Full path to identifier application/script used by pww (optional)", "")
+dt.preferences.register(namespace, "pww_bin_path", "string", "pww bin path", "Full path to the photo-what-what executable", "photo-what-what")
+
+-- register button in action menu
+dt.gui.libs.image.register_action(
+   namespace, _("auto-tag images (pww)"),
+   function(event, images) call_pww(images) end,
+   _("auto-tag image(s) with photo-what-what analysis tool")
+)
+
+-- register keyboard shortcut handler
+dt.register_event(
+   namespace, "shortcut",
+   function(event, shortcut) call_pww(dt.gui.action_images) end,
+   _("auto-tag image(s) with photo-what-what analysis tool")
+)
+
+return script_data