Created a cross platform script that calls an external executable. It also performs a service that some users might find useful, extracting the embedded jpeg image from a raw file, then importing and grouping it with the raw. Updated README.md to reflect the new file
This commit is contained in:
@@ -63,6 +63,7 @@ api_version|Yes|LMW|Print the current API version
|
||||
gettextExample|Yes|LM|How to use translation
|
||||
hello_world|Yes|LMW|Prints hello world when darktable starts
|
||||
moduleExample|Yes|LMW|How to create a lighttable module
|
||||
multi_os|No|LMW|How to create a cross platform script that calls an external executable
|
||||
preferenceExamples|Yes|LMW|How to use preferences in a script
|
||||
printExamples|Yes|LMW|How to use various print functions from a script
|
||||
running_os|Yes|LMW|Print out the running operating system
|
||||
|
||||
243
examples/multi_os.lua
Normal file
243
examples/multi_os.lua
Normal file
@@ -0,0 +1,243 @@
|
||||
--[[
|
||||
This file is part of darktable,
|
||||
copyright (c) 2017,2018 Bill Ferguson <wpferguson@gmail.com>
|
||||
|
||||
darktable 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.
|
||||
|
||||
darktable 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 darktable. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
--[[
|
||||
multi_os - an example script that runs on linux, MacOS, and Windows.
|
||||
|
||||
multi_os is an example of how to write a script that will run on different
|
||||
operating systems. It uses the lua-scripts libraries to lessen the amount
|
||||
of code that needs to be written, as well as gaining access to tested
|
||||
cross-platform routines. This script also performs a function that some
|
||||
may find useful. It creates a button in the lighttable selected images module
|
||||
that extracts the embedded jpeg image from a raw file, then imports it and groups
|
||||
it with the raw file. A keyboard shortcut is also created. A key combination can
|
||||
be assigned to the shortcut in the lua preferences and then the action can be invoked
|
||||
by hovering over the image and pressing the key combination.
|
||||
|
||||
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
|
||||
* ufraw-batch - https://ufraw.sourceforge.net
|
||||
MacOS - install with homebrew
|
||||
|
||||
USAGE
|
||||
* require this script from your main lua file
|
||||
* start darktable, open prefreences, go to lua options
|
||||
and update the executable location if you are running
|
||||
Windows or MacOS, then restart darktable.
|
||||
* select an image or images
|
||||
* click the button to extract the jpeg
|
||||
|
||||
BUGS, COMMENTS, SUGGESTIONS
|
||||
* Send to Bill Ferguson, wpferguson@gmail.com
|
||||
|
||||
CHANGES
|
||||
]]
|
||||
|
||||
--[[
|
||||
require "darktable" provides the interface to the darktable lua functions used to
|
||||
interact with darktable
|
||||
]]
|
||||
|
||||
local dt = require "darktable"
|
||||
|
||||
--[[
|
||||
require "lib/..." provides access to functions that have been pulled from various
|
||||
scripts and consolidated into libraries. Using the libraries eliminates having to
|
||||
recode common functions in every script.
|
||||
]]
|
||||
|
||||
local du = require "lib/dtutils" -- utilities
|
||||
local df = require "lib/dtutils.file" -- file utilities
|
||||
local dtsys = require "lib/dtutils.system" -- system utilities
|
||||
|
||||
--[[
|
||||
darktable is an international program, and it's user interface has been translated into
|
||||
many languages. The lua API provides gettext which is a function that looks for and replaces
|
||||
strings with the translated equivalents based on locale. Even if you don't provide the
|
||||
translations, inserting this lays the groundwork for anyone who wants to translate the strings.
|
||||
]]
|
||||
|
||||
local gettext = dt.gettext
|
||||
|
||||
-- Tell gettext where to find the .mo file translating messages for a particular domain
|
||||
gettext.bindtextdomain("multi_os",dt.configuration.config_dir.."/lua/locale/")
|
||||
|
||||
local function _(msgid)
|
||||
return gettext.dgettext("multi_os", msgid)
|
||||
end
|
||||
|
||||
--[[
|
||||
Specify the version(s) of the lua API that this script is compatible with. This script uses new
|
||||
features released in the latest version of darktable and is only compatible with the latest API version.
|
||||
Multiple API versions may be specified, seperated by commas.
|
||||
]]
|
||||
|
||||
dt.configuration.check_version(...,{5,0,0})
|
||||
|
||||
--[[
|
||||
copy_image_attributes is a local subroutine to copy image attributes in the database from the raw image
|
||||
to the extracted jpeg image. Even though the subroutine could act on the variables in the main program
|
||||
directly, passing them as arguments and using them in the subroutine is much safer.
|
||||
]]
|
||||
|
||||
local function copy_image_attributes(from, to, ...)
|
||||
local args = {...}
|
||||
if #args == 0 then
|
||||
args[1] = "all"
|
||||
end
|
||||
if args[1] == "all" then
|
||||
args[1] = "rating"
|
||||
args[2] = "colors"
|
||||
args[3] = "exif"
|
||||
args[4] = "meta"
|
||||
args[5] = "GPS"
|
||||
end
|
||||
for _,arg in ipairs(args) do
|
||||
if arg == "rating" then
|
||||
to.rating = from.rating
|
||||
elseif arg == "colors" then
|
||||
to.red = from.red
|
||||
to.blue = from.blue
|
||||
to.green = from.green
|
||||
to.yellow = from.yellow
|
||||
to.purple = from.purple
|
||||
elseif arg == "exif" then
|
||||
to.exif_maker = from.exif_maker
|
||||
to.exif_model = from.exif_model
|
||||
to.exif_lens = from.exif_lens
|
||||
to.exif_aperture = from.exif_aperture
|
||||
to.exif_exposure = from.exif_exposure
|
||||
to.exif_focal_length = from.exif_focal_length
|
||||
to.exif_iso = from.exif_iso
|
||||
to.exif_datetime_taken = from.exif_datetime_taken
|
||||
to.exif_focus_distance = from.exif_focus_distance
|
||||
to.exif_crop = from.exif_crop
|
||||
elseif arg == "GPS" then
|
||||
to.elevation = from.elevation
|
||||
to.longitude = from.longitude
|
||||
to.latitude = from.latitude
|
||||
elseif arg == "meta" then
|
||||
to.publisher = from.publisher
|
||||
to.title = from.title
|
||||
to.creator = from.creator
|
||||
to.rights = from.rights
|
||||
to.description = from.description
|
||||
else
|
||||
dt.print_error("Unrecognized option to copy_image_attributes: " .. arg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
The main function called from the button or the shortcut. It takes one or more raw files, passed
|
||||
in a table and extracts the embedded jpeg images
|
||||
]]
|
||||
|
||||
local function extract_embedded_jpeg(images)
|
||||
|
||||
--[[
|
||||
check if the executable exists, since we can't do anything without it. check_if_bin_exists()
|
||||
checks to see if there is a saved executable location. If not, it checks for the executable
|
||||
in the user's path. When it finds the executable, it returns the command to run it.
|
||||
]]
|
||||
|
||||
local ufraw_executable = df.check_if_bin_exists("ufraw-batch")
|
||||
if ufraw_executable then
|
||||
for _, image in ipairs(images) do
|
||||
if image.is_raw then
|
||||
local img_file = du.join({image.path, image.filename}, "/")
|
||||
|
||||
--[[
|
||||
dtsys.external_command() is operating system aware and formats the command as necessary.
|
||||
df.sanitize_filename() is used to quote the image filepath to protect from spaces. It is also
|
||||
operating system aware and uses the corresponding quotes.
|
||||
]]
|
||||
|
||||
if dtsys.external_command(ufraw_executable .. " --silent --embedded-image " .. df.sanitize_filename(img_file)) then
|
||||
local jpg_img_file = df.chop_filetype(img_file) .. ".embedded.jpg"
|
||||
dt.print_log("jpg_img_file set to ", jpg_img_file) -- print a debugging message
|
||||
local myimage = dt.database.import(jpg_img_file)
|
||||
myimage:group_with(image.group_leader)
|
||||
copy_image_attributes(image, myimage, "all")
|
||||
|
||||
--[[
|
||||
copy all of the tags except the darktable tags
|
||||
]]
|
||||
|
||||
for _,tag in pairs(dt.tags.get_tags(image)) do
|
||||
if not (string.sub(tag.name,1,9) == "darktable") then
|
||||
dt.print_log("attaching tag")
|
||||
dt.tags.attach(tag,myimage)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
dt.print_error(image.filename .. " is not a raw file. No image can be extracted") -- print debugging error message
|
||||
dt.print(image.filename .. " is not a raw file. No image can be extracted") -- print the error to the screen
|
||||
end
|
||||
end
|
||||
else
|
||||
dt.print_error("ufraw-batch not found. Exiting...") -- print debugging error message
|
||||
dt.print("ufraw-batch not found. Exiting...") -- print the error to the screen
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Windows and MacOS don't place executables in the user's path so their location needs to be specified
|
||||
so that the script can find them. An exception to this is packages installed on MacOS with homebrew. Those
|
||||
executables are put in /usr/local/bin. These are saved as executable path preferences. check_if_bin_exists()
|
||||
looks for the executable path preference for the executable. If it doesn't find one, then the path is checked
|
||||
to see if the executable is there.
|
||||
]]
|
||||
|
||||
local executable = "ufraw-batch"
|
||||
local ufraw_batch_path_widget = dt.new_widget("file_chooser_button"){
|
||||
title = _("Select ufraw-batch[.exe] executable"),
|
||||
value = df.get_executable_path_preference(executable),
|
||||
is_directory = false,
|
||||
changed_callback = function(self)
|
||||
if df.check_if_bin_exists(self.value) then
|
||||
df.set_executable_path_preference(executable, self.value)
|
||||
end
|
||||
end
|
||||
}
|
||||
dt.preferences.register("executable_paths", "ufraw-batch", -- name
|
||||
"file", -- type
|
||||
_('multi_os: ufraw-batch location'), -- label
|
||||
_('Installed location of ufraw-batch. Requires restart to take effect.'), -- tooltip
|
||||
"ufraw-batch", -- default
|
||||
ufraw_batch_path_widget
|
||||
)
|
||||
|
||||
--[[
|
||||
Add a button to the selected images module in lighttable
|
||||
]]
|
||||
|
||||
dt.gui.libs.image.register_action(
|
||||
_("extract embedded jpeg"),
|
||||
function(event, images) extract_embedded_jpeg(images) end,
|
||||
"extract embedded jpeg"
|
||||
)
|
||||
|
||||
--[[
|
||||
Add a shortcut
|
||||
]]
|
||||
|
||||
dt.register_event(
|
||||
"shortcut",
|
||||
function(event, shortcut) extract_embedded_jpeg(dt.gui.action_images) end,
|
||||
"extract embedded jpeg"
|
||||
)
|
||||
Reference in New Issue
Block a user