From 5f6350c21807cd89c6f8b56af0716b0d1dabf7f5 Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Thu, 1 Oct 2015 21:55:19 +0200 Subject: [PATCH 001/865] Add helper that checks GitHub for new dt releases --- official/check_for_updates.lua | 89 ++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 official/check_for_updates.lua diff --git a/official/check_for_updates.lua b/official/check_for_updates.lua new file mode 100644 index 00000000..1e7977ba --- /dev/null +++ b/official/check_for_updates.lua @@ -0,0 +1,89 @@ +--[[ + This file is part of darktable, + copyright (c) 2015 Tobias Ellinghaus + + 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 . +]] +--[[ +CHECK FOR UPDATES +a simple script that will automatically look for newer releases on github and inform +when there is something. it will only check on startup and only once a week. + +USAGE +* install luasec and cjson for Lua 5.2 on your system +* require this script from your main lua file +* restart darktable + +]] + +local dt = require "darktable" +local https = require "ssl.https" +local cjson = require "cjson" + +dt.configuration.check_version(...,{2,0,0}) + +-- compare two version strings of the form "major.minor.patch" +-- returns -1, 0, 1 if the first version is smaller, equal, greater than the second version, +-- or nil if one or both are of the wrong format +-- strings like "release-1.2.3" and "1.2.3+456~gb00b5" are fine, too +local function compare_versions(a, b) + local a_major, a_minor, a_patch = a:match("(%d+)%.(%d+)%.(%d+)") + local b_major, b_minor, b_patch = b:match("(%d+)%.(%d+)%.(%d+)") + if a_major and a_minor and a_patch and b_major and b_minor and b_patch then + if a_major < b_major then return -1 end + if a_major > b_major then return 1 end + + if a_minor < b_minor then return -1 end + if a_minor > b_minor then return 1 end + + if a_patch < b_patch then return -1 end + if a_patch > b_patch then return 1 end + + return 0 + else + return + end +end + + +-- check stored timestamp and skip the check if the last time was not too long ago +-- for now we are assuming that os.time() returns seconds. that's not guaranteed but the case on many systems. +-- the reference date doesn't matter, as long as it's currently positive (we start with 0 the first time) +-- see http://lua-users.org/wiki/DateAndTime +local now = os.time() +local back_then = dt.preferences.read("check_for_updates", "timestamp", "integer") + +-- check once a week +if now > (back_then + 60 * 60 * 24 * 7) then + + -- try to get the latest release's version from github and compare to what we are running + -- see https://developer.github.com/v3/repos/releases/ for the api docs + -- just ignore when anything fails and retry at some other time + local result, error_code = https.request("https://api.github.com/repos/darktable-org/darktable/releases/latest") + + if error_code == 200 then + local name = cjson.decode(result)["name"] -- http://www.kyne.com.au/~mark/software/lua-cjson-manual.html + if name then + local cmp = compare_versions(name, dt.configuration.version) + if cmp then + if cmp > 0 then + dt.print("there seems to be a newer release than what you are running. better update") + end + -- update timestamp to not check again for a while + dt.preferences.write("check_for_updates", "timestamp", "integer", now) + end + end + end + +end From ae627d9f5516ef55187fda1a461e64f9539f6ca1 Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Sat, 14 Nov 2015 13:43:19 +0100 Subject: [PATCH 002/865] Make update check work with RCs --- official/check_for_updates.lua | 50 ++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/official/check_for_updates.lua b/official/check_for_updates.lua index 1e7977ba..659bc284 100644 --- a/official/check_for_updates.lua +++ b/official/check_for_updates.lua @@ -37,9 +37,25 @@ dt.configuration.check_version(...,{2,0,0}) -- returns -1, 0, 1 if the first version is smaller, equal, greater than the second version, -- or nil if one or both are of the wrong format -- strings like "release-1.2.3" and "1.2.3+456~gb00b5" are fine, too +local function parse_version(s) + local rc = 0 + local major, minor, patch = s:match("(%d+)%.(%d+)%.(%d+)") + if not major then + patch = 0 + major, minor, rc = s:match("(%d+)%.(%d+)rc(%d+)") + end + if not major then + patch = 0 + rc = 0 + major, minor = s:match("(%d+)%.(%d+)") + end + return tonumber(major), tonumber(minor), tonumber(patch), tonumber(rc) +end + local function compare_versions(a, b) - local a_major, a_minor, a_patch = a:match("(%d+)%.(%d+)%.(%d+)") - local b_major, b_minor, b_patch = b:match("(%d+)%.(%d+)%.(%d+)") + local a_major, a_minor, a_patch, a_rc = parse_version(a) + local b_major, b_minor, b_patch, b_rc = parse_version(b) + if a_major and a_minor and a_patch and b_major and b_minor and b_patch then if a_major < b_major then return -1 end if a_major > b_major then return 1 end @@ -50,6 +66,13 @@ local function compare_versions(a, b) if a_patch < b_patch then return -1 end if a_patch > b_patch then return 1 end + -- when rc == 0 then it's a proper release and newer than the rcs + local m = math.max(a_rc, b_rc) + 1 + if a_rc == 0 then a_rc = m end + if b_rc == 0 then b_rc = m end + if a_rc < b_rc then return -1 end + if a_rc > b_rc then return 1 end + return 0 else return @@ -57,6 +80,29 @@ local function compare_versions(a, b) end +-- local function test(a, b, r) +-- local cmp = compare_versions(a, b) +-- if(not cmp) then +-- print(a .. " ./. " .. b .. " => MALFORMED INPUT") +-- elseif(cmp == r) then +-- print(a .. " ./. " .. b .. " => PASSED") +-- else +-- print(a .. " ./. " .. b .. " => FAILED") +-- end +-- end +-- +-- test("malformed", "1.0.0", 0) +-- test("2.0rc1+135~ge456b2b-dirty", "release-1.6.9", 1) +-- test("release-1.6.9", "2.0rc1+135~ge456b2b-dirty", -1) +-- test("2.0rc1+135~ge456b2b-dirty", "2.0rc2+135~ge456b2b-dirty", -1) +-- test("2.0rc2+135~ge456b2b-dirty", "2.0rc1+135~ge456b2b-dirty", 1) +-- test("2.0rc3+135~ge456b2b-dirty", "release-2.0", -1) +-- test("2.0rc3+135~ge456b2b-dirty", "release-2.0.0", -1) +-- test("1.0.0", "2.0.0", -1) +-- test("2.0.0", "1.0.0", 1) +-- test("3.0.0", "3.0.0", 0) + + -- check stored timestamp and skip the check if the last time was not too long ago -- for now we are assuming that os.time() returns seconds. that's not guaranteed but the case on many systems. -- the reference date doesn't matter, as long as it's currently positive (we start with 0 the first time) From eff89532076f64f6ce8f08a2daa78ea0f645d918 Mon Sep 17 00:00:00 2001 From: supertobi Date: Tue, 15 Dec 2015 10:41:10 +0100 Subject: [PATCH 003/865] Create geo_uri.lua Maps in 3.20 will be able to handle the 'geo' URI scheme. That means that if you enter the shortcut Gnome Maps will present the current window if there is one and go to location, and start a new instance of maps if there is none. --- contrib/geo_uri.lua | 96 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 contrib/geo_uri.lua diff --git a/contrib/geo_uri.lua b/contrib/geo_uri.lua new file mode 100644 index 00000000..12ac1e15 --- /dev/null +++ b/contrib/geo_uri.lua @@ -0,0 +1,96 @@ +--[[ + This file is part of darktable, + Copyright 2014 by Tobias Jakobs. + + 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 . +]] +--[[ +darktable script to open a geo uri in gnome-maps + +ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT +* gnome-maps >= 3.20 + +WARNING +This script is not testet. + +USAGE +* require this script from your main lua file +* register a shortcut +]] + +local dt = require "darktable" +dt.configuration.check_version(...,{2,0,1}) + +local function checkIfBinExists(bin) + local handle = io.popen("which "..bin) + local result = handle:read() + local ret + handle:close() + if (not result) then + dt.print_error(bin.." not found") + ret = false + end + ret = true + return ret +end + +local function openLocationInGnomeMaps() + if not checkIfBinExists("gnome-maps") then + darktable.print_error("gnome-maps not found") + return + end + + local sel_images = dt.gui.selection() + + local lat1 = 0; + local lon1 = 0; + local i = 0; + + local sel_images = dt.gui.selection() + +-- Use the first image with geo information + for _,image in ipairs(sel_images) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + + i = i + 1; + + if (i == 1) then + lat1 = image.latitude; + lon1 = image.longitude; + end + + end + end + + if (lat1 and lon1) then + + local startCommand + + startCommand = "gnome-maps \"geo:" .. lat1 .. "," .. lon1 .."\"" + end + + dt.print_error(startCommand) + + if coroutine.yield("RUN_COMMAND", startCommand) + then + dt.print("Command failed ...") + end + + end +end + +-- Register +dt.register_event("shortcut", openLocationInGnomeMaps, "Open Location in Gnome Maps") From f4f96d71585beeed1134a486cac42668a4f9628b Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Wed, 16 Dec 2015 11:52:35 +0100 Subject: [PATCH 004/865] Ellipsize a label with image path Otherwise it will make the side panel too wide, breaking the whole gui. --- official/image_path_in_ui.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/official/image_path_in_ui.lua b/official/image_path_in_ui.lua index 7026bfb0..ba93d2d8 100644 --- a/official/image_path_in_ui.lua +++ b/official/image_path_in_ui.lua @@ -1,17 +1,17 @@ --[[ This file is part of darktable, copyright (c) 2014 Jérémy Rosen - + 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 . ]] @@ -31,9 +31,9 @@ This plugin will add a widget at the bottom of the left column in lighttable mod local dt = require "darktable" dt.configuration.check_version(...,{2,0,0}) -local main_label = dt.new_widget("label"){selectable = true} +local main_label = dt.new_widget("label"){selectable = true, ellipsize = "middle", halign = "start"} -local function reset_widget() +local function reset_widget() local selection = dt.gui.selection() local result = "" local array = {} From c56766ef8582238e50182a178233cc5d6ac70030 Mon Sep 17 00:00:00 2001 From: supertobi Date: Wed, 16 Dec 2015 13:51:35 +0100 Subject: [PATCH 005/865] Fixed spaces --- contrib/geo_uri.lua | 84 +++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/contrib/geo_uri.lua b/contrib/geo_uri.lua index 12ac1e15..57f58bfd 100644 --- a/contrib/geo_uri.lua +++ b/contrib/geo_uri.lua @@ -33,63 +33,59 @@ local dt = require "darktable" dt.configuration.check_version(...,{2,0,1}) local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (not result) then - dt.print_error(bin.." not found") - ret = false - end - ret = true - return ret + local handle = io.popen("which "..bin) + local result = handle:read() + local ret + handle:close() + if (not result) then + dt.print_error(bin.." not found") + ret = false + end + ret = true + return ret end local function openLocationInGnomeMaps() - if not checkIfBinExists("gnome-maps") then - darktable.print_error("gnome-maps not found") - return - end + if not checkIfBinExists("gnome-maps") then + darktable.print_error("gnome-maps not found") + return + end - local sel_images = dt.gui.selection() - - local lat1 = 0; - local lon1 = 0; - local i = 0; - - local sel_images = dt.gui.selection() - --- Use the first image with geo information - for _,image in ipairs(sel_images) do - if ((image.longitude and image.latitude) and - (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data - ) then - - i = i + 1; - - if (i == 1) then - lat1 = image.latitude; - lon1 = image.longitude; - end - + local sel_images = dt.gui.selection() + + local lat1 = 0; + local lon1 = 0; + local i = 0; + + local sel_images = dt.gui.selection() + + -- Use the first image with geo information + for _,image in ipairs(sel_images) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + + i = i + 1; + + if (i == 1) then + lat1 = image.latitude; + lon1 = image.longitude; end + + end end if (lat1 and lon1) then - - local startCommand - - startCommand = "gnome-maps \"geo:" .. lat1 .. "," .. lon1 .."\"" - end - + local startCommand + startCommand = "gnome-maps \"geo:" .. lat1 .. "," .. lon1 .."\"" dt.print_error(startCommand) - if coroutine.yield("RUN_COMMAND", startCommand) - then + if coroutine.yield("RUN_COMMAND", startCommand) then dt.print("Command failed ...") end - end + + end end -- Register From a4e26365d8f0a324e141799144a459abfc62cb90 Mon Sep 17 00:00:00 2001 From: Robert William Hutton Date: Sat, 19 Dec 2015 22:33:11 +1100 Subject: [PATCH 006/865] Specify location of luarc file in the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 640a201f..3dd001b3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ lua-scripts The Lua scripts in this repository are meant to be used together with darktable. Either copy them individually to `~/.config/darktable/lua` (you might have to create that folder) or just copy/symlink the whole repository there. That allows to update all your scripts with a simple call to `git pull`. -To enable one of the scripts you have to add a line like `require "official/hello_world"` which would enable the example script in `official/hello_world.lua`. +To enable one of the scripts you have to add a line like `require "official/hello_world"` to your `~/.config/darktable/luarc` file which will enable the example script in `official/hello_world.lua` (note the lack of the `.lua` suffix). Each script includes its own documentation and usage in its header, please refer to them. From 1dc1f5f9efe6fba5a5910f3b4758ae6f6ad3f0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rosen?= Date: Wed, 23 Dec 2015 15:20:24 +0100 Subject: [PATCH 007/865] disable image_path_in_ui since it relies on a disabled feature --- official/image_path_in_ui.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/official/image_path_in_ui.lua b/official/image_path_in_ui.lua index ba93d2d8..0c081c0f 100644 --- a/official/image_path_in_ui.lua +++ b/official/image_path_in_ui.lua @@ -28,6 +28,7 @@ This plugin will add a widget at the bottom of the left column in lighttable mod ]] +--[[ local dt = require "darktable" dt.configuration.check_version(...,{2,0,0}) @@ -58,6 +59,6 @@ dt.register_lib("image_path_no_ui","Selected Images path",true,false,{ ); dt.register_event("mouse-over-image-changed",reset_widget); - +]] -- -- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua From ff1f07653682ee253915da7c9273a0ed9bc7a9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rosen?= Date: Wed, 23 Dec 2015 15:21:38 +0100 Subject: [PATCH 008/865] Revert "disable image_path_in_ui since it relies on a disabled feature" This reverts commit 1dc1f5f9efe6fba5a5910f3b4758ae6f6ad3f0e1. --- official/image_path_in_ui.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/official/image_path_in_ui.lua b/official/image_path_in_ui.lua index 0c081c0f..ba93d2d8 100644 --- a/official/image_path_in_ui.lua +++ b/official/image_path_in_ui.lua @@ -28,7 +28,6 @@ This plugin will add a widget at the bottom of the left column in lighttable mod ]] ---[[ local dt = require "darktable" dt.configuration.check_version(...,{2,0,0}) @@ -59,6 +58,6 @@ dt.register_lib("image_path_no_ui","Selected Images path",true,false,{ ); dt.register_event("mouse-over-image-changed",reset_widget); -]] + -- -- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua From 5d729048499379c6b29b8722b1709f43d3be2ea8 Mon Sep 17 00:00:00 2001 From: chrik5 Date: Sun, 27 Dec 2015 14:52:21 +0100 Subject: [PATCH 009/865] make check_api_version work with API 3 --- contrib/copy_attach_detach_tags.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/copy_attach_detach_tags.lua b/contrib/copy_attach_detach_tags.lua index d5a7ec8e..50817329 100644 --- a/contrib/copy_attach_detach_tags.lua +++ b/contrib/copy_attach_detach_tags.lua @@ -34,7 +34,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,0}) +dt.configuration.check_version(...,{2,0,0},{3,0,0}) local image_tags = {} From 08151e7e2149c1d2c737349a1cde2c269c77f695 Mon Sep 17 00:00:00 2001 From: Laurent Navet Date: Wed, 30 Dec 2015 22:02:18 +0100 Subject: [PATCH 010/865] Fix some typos --- contrib/hugin.lua | 2 +- contrib/kml_export.lua | 4 ++-- contrib/preferenceExamples.lua | 2 +- contrib/video_mencoder.lua | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/hugin.lua b/contrib/hugin.lua index a87437fa..b7ffbfb2 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -24,7 +24,7 @@ HUGIN Add a new storage option to send images to hugin. Images are exported to darktable tmp dir first. -ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT +ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT * hugin USAGE diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index fc6a804e..da3c2d42 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -18,7 +18,7 @@ --[[ darktable KML export script -ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT +ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT * mkdir * zip (only if you create KMZ files) * convert (ImageMagick) @@ -26,7 +26,7 @@ ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT * xdg-user-dir WARNING -This script is only testet with Linux +This script is only tested with Linux USAGE * require this script from your main lua file diff --git a/contrib/preferenceExamples.lua b/contrib/preferenceExamples.lua index 18a6553d..34117e6f 100644 --- a/contrib/preferenceExamples.lua +++ b/contrib/preferenceExamples.lua @@ -16,7 +16,7 @@ along with this program. If not, see . ]] --[[ -darktable script to show the different prefference types that are possible with the Lua +darktable script to show the different preference types that are possible with Lua USAGE * require this script from your main lua file diff --git a/contrib/video_mencoder.lua b/contrib/video_mencoder.lua index e0ba2b61..18ddc253 100644 --- a/contrib/video_mencoder.lua +++ b/contrib/video_mencoder.lua @@ -18,13 +18,13 @@ --[[ darktable video export script -ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT +ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT * mencoder (MEncoder is from the MPlayer Team) * xdg-open * xdg-user-dir WARNING -This script is only testet with Linux +This script is only tested with Linux USAGE * require this script from your main lua file From 28d73b44a6e30e81a11198dbca7ead8af5627fdc Mon Sep 17 00:00:00 2001 From: ribmo Date: Sat, 2 Jan 2016 12:58:35 +0000 Subject: [PATCH 011/865] Shortcuts to rate/reject all images within a group --- contrib/rate_group.lua | 84 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 contrib/rate_group.lua diff --git a/contrib/rate_group.lua b/contrib/rate_group.lua new file mode 100644 index 00000000..b6b7a75d --- /dev/null +++ b/contrib/rate_group.lua @@ -0,0 +1,84 @@ +--[[ + + Rate Group: + + Script to provide shortcuts for rating or rejecting all images within a group; + particularly useful for RAW+JPEG shooters employing a star rating workflow + like the below: + + http://blog.chasejarvis.com/blog/2011/03/photo-editing-101/ + + + Installation and usage: + + 1. Copy this file into ~/.config/darktable/lua/ + + 2. Add `require "rate_group"` to new line in ~/.config/darktable/luarc + + 3. Restart darktable + + 4. Assign a keyboard shortcut to each action via settings > shortcuts > lua + + I use the following shortcuts: + + * Reject group: Ctrl+R + * Rate group 1: Ctrl+1 + * Rate group 2: Ctrl+2 + * Rate group 3: Ctrl+3 + * Rate group 4: Ctrl+4 + * Rate group 5: Ctrl+5 + * Rate group 0: Ctrl+0 + + + Author: Dom H (dom@hxy.io) + License: GPLv2 + + This script is based on Thibault Jouannic's `reject_group` script: + http://redmine.darktable.org/issues/8968#note-20 + +]] + +local dt = require "darktable" + +local function apply_rating(rating) + local images = dt.gui.action_images + for _, i in ipairs(images) do + local members = i:get_group_members() + for _, m in ipairs(members) do + m.rating = rating + end + end + if rating < 0 then + dt.print("rejecting group(s)") + else + dt.print("applying rating " ..rating.. " to group(s)") + end +end + +dt.register_event("shortcut",function(event, shortcut) + apply_rating(-1) +end, "Reject group") + +dt.register_event("shortcut",function(event, shortcut) + apply_rating(0) +end, "Rate group 0") + +dt.register_event("shortcut",function(event, shortcut) + apply_rating(1) +end, "Rate group 1") + +dt.register_event("shortcut",function(event, shortcut) + apply_rating(2) +end, "Rate group 2") + +dt.register_event("shortcut",function(event, shortcut) + apply_rating(3) +end, "Rate group 3") + +dt.register_event("shortcut",function(event, shortcut) + apply_rating(4) +end, "Rate group 4") + +dt.register_event("shortcut",function(event, shortcut) + apply_rating(5) +end, "Rate group 5") \ No newline at end of file From 39531eb4f0a0b4cb2d69c18a23d69d2eee097519 Mon Sep 17 00:00:00 2001 From: spaceChRiS Date: Sun, 3 Jan 2016 10:44:14 +0100 Subject: [PATCH 012/865] Take care for code in for loop to be run even for the last image. The problem: If the last image is a jpeg/raw pair, the code to remove the jpeg from the import list is not run since it is the last image. This is solved by adding an empty line to the images array. It will be counted as new base and therefore the jpeg removal code will be run one more time. I don't know if this is a good solution but I think it solves the problem without adding complexity. --- official/import_filters.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/official/import_filters.lua b/official/import_filters.lua index 5980a727..04a8d5c8 100644 --- a/official/import_filters.lua +++ b/official/import_filters.lua @@ -50,6 +50,7 @@ dt.register_import_filter("prefer raw over jpeg", function(event, images) local current_base = "" local jpg_indices = {} local other_format_found = false + table.insert(images, "") for i, img in ipairs(images) do local extension = img:match("[^.]*$"):upper() local base = img:match("^.*[.]") From fe18256c259836e472700893ac60e3a2320b42d8 Mon Sep 17 00:00:00 2001 From: spaceChRiS Date: Mon, 4 Jan 2016 10:44:41 +0100 Subject: [PATCH 013/865] Remove extra line from image list. --- official/import_filters.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/official/import_filters.lua b/official/import_filters.lua index 04a8d5c8..e3d595c6 100644 --- a/official/import_filters.lua +++ b/official/import_filters.lua @@ -75,6 +75,7 @@ dt.register_import_filter("prefer raw over jpeg", function(event, images) end end + table.remove(images) end) -- vim: shiftwidth=2 expandtab tabstop=2 cindent From 895ad62757e548e4c7e6802c48ba56b6433c12a4 Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Mon, 4 Jan 2016 14:49:12 +0100 Subject: [PATCH 014/865] Fix line endings --- contrib/hugin.lua | 238 ++++++++++++++++++------------------ contrib/video_mencoder.lua | 240 ++++++++++++++++++------------------- 2 files changed, 239 insertions(+), 239 deletions(-) diff --git a/contrib/hugin.lua b/contrib/hugin.lua index b7ffbfb2..819e5b26 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -1,119 +1,119 @@ ---[[ - Hugin storage for darktable - - copyright (c) 2014 Wolfgang Goetz - copyright (c) 2015 Christian Kanzian - copyright (c) 2015 Tobias Jakobs - - 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 . -]] - ---[[ -HUGIN -Add a new storage option to send images to hugin. -Images are exported to darktable tmp dir first. - -ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT -* hugin - -USAGE -* require this file from your main luarc config file. - -This plugin will add a new storage option and calls hugin after export. -]] - -local dt = require "darktable" - --- should work with darktable API version 2.0.0 -dt.configuration.check_version(...,{2,0,0}) - -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (result) then - dt.print_error("true checkIfBinExists: "..bin) - ret = true - else - dt.print_error(bin.." not found") - ret = false - end - - - return ret -end - -local function show_status(storage, image, format, filename, - number, total, high_quality, extra_data) - dt.print("Export to Hugin "..tostring(number).."/"..tostring(total)) -end - -local function create_panorama(storage, image_table, extra_data) --finalize - if not checkIfBinExists("hugin") then - darktable.print_error("hugin not found") - return - end - --- Since Hugin 2015.0.0 hugin provides a command line tool to start the assistant --- http://wiki.panotools.org/Hugin_executor --- We need pto_gen to create pto file for hugin_executor --- http://hugin.sourceforge.net/docs/manual/Pto_gen.html - - local hugin_executor = false - if (checkIfBinExists("hugin_executor") and checkIfBinExists("pto_gen")) then - hugin_executor = true - end - - -- list of exported images - local img_list - - -- reset and create image list - img_list = "" - - for _,v in pairs(image_table) do - img_list = img_list ..v.. " " - end - - dt.print("Will try to stitch now") - - local huginStartCommand - if (hugin_executor) then - huginStartCommand = "pto_gen "..img_list.." -o "..dt.configuration.tmp_dir.."/project.pto" - dt.print("Creating pto file") - coroutine.yield("RUN_COMMAND", huginStartCommand) - - dt.print("Running Assistent") - huginStartCommand = "hugin_executor --assistant "..dt.configuration.tmp_dir.."/project.pto" - coroutine.yield("RUN_COMMAND", huginStartCommand) - - huginStartCommand = "hugin "..dt.configuration.tmp_dir.."/project.pto" - else - huginStartCommand = "hugin "..img_list - end - - dt.print_error(huginStartCommand) - - if coroutine.yield("RUN_COMMAND", huginStartCommand) - then - dt.print("Command hugin failed ...") - end - -end - --- Register -dt.register_storage("module_hugin", "Hugin Panorama", show_status, create_panorama) - --- --- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua +--[[ + Hugin storage for darktable + + copyright (c) 2014 Wolfgang Goetz + copyright (c) 2015 Christian Kanzian + copyright (c) 2015 Tobias Jakobs + + 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 . +]] + +--[[ +HUGIN +Add a new storage option to send images to hugin. +Images are exported to darktable tmp dir first. + +ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT +* hugin + +USAGE +* require this file from your main luarc config file. + +This plugin will add a new storage option and calls hugin after export. +]] + +local dt = require "darktable" + +-- should work with darktable API version 2.0.0 +dt.configuration.check_version(...,{2,0,0}) + +local function checkIfBinExists(bin) + local handle = io.popen("which "..bin) + local result = handle:read() + local ret + handle:close() + if (result) then + dt.print_error("true checkIfBinExists: "..bin) + ret = true + else + dt.print_error(bin.." not found") + ret = false + end + + + return ret +end + +local function show_status(storage, image, format, filename, + number, total, high_quality, extra_data) + dt.print("Export to Hugin "..tostring(number).."/"..tostring(total)) +end + +local function create_panorama(storage, image_table, extra_data) --finalize + if not checkIfBinExists("hugin") then + darktable.print_error("hugin not found") + return + end + +-- Since Hugin 2015.0.0 hugin provides a command line tool to start the assistant +-- http://wiki.panotools.org/Hugin_executor +-- We need pto_gen to create pto file for hugin_executor +-- http://hugin.sourceforge.net/docs/manual/Pto_gen.html + + local hugin_executor = false + if (checkIfBinExists("hugin_executor") and checkIfBinExists("pto_gen")) then + hugin_executor = true + end + + -- list of exported images + local img_list + + -- reset and create image list + img_list = "" + + for _,v in pairs(image_table) do + img_list = img_list ..v.. " " + end + + dt.print("Will try to stitch now") + + local huginStartCommand + if (hugin_executor) then + huginStartCommand = "pto_gen "..img_list.." -o "..dt.configuration.tmp_dir.."/project.pto" + dt.print("Creating pto file") + coroutine.yield("RUN_COMMAND", huginStartCommand) + + dt.print("Running Assistent") + huginStartCommand = "hugin_executor --assistant "..dt.configuration.tmp_dir.."/project.pto" + coroutine.yield("RUN_COMMAND", huginStartCommand) + + huginStartCommand = "hugin "..dt.configuration.tmp_dir.."/project.pto" + else + huginStartCommand = "hugin "..img_list + end + + dt.print_error(huginStartCommand) + + if coroutine.yield("RUN_COMMAND", huginStartCommand) + then + dt.print("Command hugin failed ...") + end + +end + +-- Register +dt.register_storage("module_hugin", "Hugin Panorama", show_status, create_panorama) + +-- +-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua diff --git a/contrib/video_mencoder.lua b/contrib/video_mencoder.lua index 18ddc253..81987805 100644 --- a/contrib/video_mencoder.lua +++ b/contrib/video_mencoder.lua @@ -1,120 +1,120 @@ ---[[ - This file is part of darktable, - Copyright 2014 by Tobias Jakobs. - - 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 . -]] ---[[ -darktable video export script - -ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT -* mencoder (MEncoder is from the MPlayer Team) -* xdg-open -* xdg-user-dir - -WARNING -This script is only tested with Linux - -USAGE -* require this script from your main lua file -]] - -local dt = require "darktable" -dt.configuration.check_version(...,{2,0,1}) - -local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) - dt.print("Export Image "..tostring(number).."/"..tostring(total)) -end - -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (result) then - --dt.print_error("true checkIfBinExists: "..bin) - ret = true - else - dt.print_error(bin.." not found") - ret = false - end - - return ret -end - -local function create_video_mencoder(storage, image_table, extra_data) - if not checkIfBinExists("mencoder") then - return - end - if not checkIfBinExists("xdg-open") then - return - end - if not checkIfBinExists("xdg-user-dir") then - return - end - - exportDirectory = dt.preferences.read("video_mencoder","ExportDirectory","string") - exportFilename = "output.avi" - framsePerSecond = dt.preferences.read("video_mencoder","FramesPerSecond","integer") - - dt.print_error("Will try to create video now") - -- Set the codec - local codec = "" - local codecPreferences = "" - - codecPreferences = dt.preferences.read("video_mencoder","Codec","string") - if (codecPreferences == "H.264 encoding") then - codec = 'x264' - end - if (codecPreferences == "XviD encoding") then - codec = 'xvid' - end - if not codecPreferences then - codec = 'x264' - end - - -- Create the command - local command = "mencoder -idx -nosound -noskip -ovc "..codec.." -lavcopts vcodec=mjpeg -o "..exportDirectory.."/"..exportFilename.." -mf fps="..framsePerSecond .." mf://" - - for _,v in pairs(image_table) do - command = command..v.."," - end - - dt.print_error("this is the command: "..command) - -- USE coroutine.yield. It does not block the UI - coroutine.yield("RUN_COMMAND", command) - - dt.print("Video created in "..exportDirectory) - - if ( dt.preferences.read("video_mencoder","OpenVideo","bool") == true ) then - -- USE coroutine.yield. It does not block the UI - local playVideoCommand = "xdg-open "..exportDirectory.."/"..exportFilename - coroutine.yield("RUN_COMMAND", playVideoCommand) - end -end - --- Preferences -dt.preferences.register("video_mencoder", "FramesPerSecond", "float", "Video exort (MEncoder): Frames per second", "Frames per Second in the Video export", 15, 1, 99, 0.1 ) -dt.preferences.register("video_mencoder", "OpenVideo", "bool", "Video exort (MEncoder): Open video after export", "Opens the Video after the export with the standard video player", false ) - -local handle = io.popen("xdg-user-dir VIDEOS") -local result = handle:read() -handle:close() -dt.preferences.register("video_mencoder", "ExportDirectory", "directory", "Video exort (MEncoder): Video export directory","A directory that will be used to export a Video",result) - --- Get the MEncoder codec list with: mencoder -ovc help -dt.preferences.register("video_mencoder", "Codec", "enum", "Video exort (MEncoder): Codec","Video codec","H.264 encoding","H.264 encoding","XviD encoding") - --- Register -dt.register_storage("video_mencoder", "Video Export (MEncoder)", show_status, create_video) +--[[ + This file is part of darktable, + Copyright 2014 by Tobias Jakobs. + + 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 . +]] +--[[ +darktable video export script + +ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT +* mencoder (MEncoder is from the MPlayer Team) +* xdg-open +* xdg-user-dir + +WARNING +This script is only tested with Linux + +USAGE +* require this script from your main lua file +]] + +local dt = require "darktable" +dt.configuration.check_version(...,{2,0,1}) + +local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) + dt.print("Export Image "..tostring(number).."/"..tostring(total)) +end + +local function checkIfBinExists(bin) + local handle = io.popen("which "..bin) + local result = handle:read() + local ret + handle:close() + if (result) then + --dt.print_error("true checkIfBinExists: "..bin) + ret = true + else + dt.print_error(bin.." not found") + ret = false + end + + return ret +end + +local function create_video_mencoder(storage, image_table, extra_data) + if not checkIfBinExists("mencoder") then + return + end + if not checkIfBinExists("xdg-open") then + return + end + if not checkIfBinExists("xdg-user-dir") then + return + end + + exportDirectory = dt.preferences.read("video_mencoder","ExportDirectory","string") + exportFilename = "output.avi" + framsePerSecond = dt.preferences.read("video_mencoder","FramesPerSecond","integer") + + dt.print_error("Will try to create video now") + -- Set the codec + local codec = "" + local codecPreferences = "" + + codecPreferences = dt.preferences.read("video_mencoder","Codec","string") + if (codecPreferences == "H.264 encoding") then + codec = 'x264' + end + if (codecPreferences == "XviD encoding") then + codec = 'xvid' + end + if not codecPreferences then + codec = 'x264' + end + + -- Create the command + local command = "mencoder -idx -nosound -noskip -ovc "..codec.." -lavcopts vcodec=mjpeg -o "..exportDirectory.."/"..exportFilename.." -mf fps="..framsePerSecond .." mf://" + + for _,v in pairs(image_table) do + command = command..v.."," + end + + dt.print_error("this is the command: "..command) + -- USE coroutine.yield. It does not block the UI + coroutine.yield("RUN_COMMAND", command) + + dt.print("Video created in "..exportDirectory) + + if ( dt.preferences.read("video_mencoder","OpenVideo","bool") == true ) then + -- USE coroutine.yield. It does not block the UI + local playVideoCommand = "xdg-open "..exportDirectory.."/"..exportFilename + coroutine.yield("RUN_COMMAND", playVideoCommand) + end +end + +-- Preferences +dt.preferences.register("video_mencoder", "FramesPerSecond", "float", "Video exort (MEncoder): Frames per second", "Frames per Second in the Video export", 15, 1, 99, 0.1 ) +dt.preferences.register("video_mencoder", "OpenVideo", "bool", "Video exort (MEncoder): Open video after export", "Opens the Video after the export with the standard video player", false ) + +local handle = io.popen("xdg-user-dir VIDEOS") +local result = handle:read() +handle:close() +dt.preferences.register("video_mencoder", "ExportDirectory", "directory", "Video exort (MEncoder): Video export directory","A directory that will be used to export a Video",result) + +-- Get the MEncoder codec list with: mencoder -ovc help +dt.preferences.register("video_mencoder", "Codec", "enum", "Video exort (MEncoder): Codec","Video codec","H.264 encoding","H.264 encoding","XviD encoding") + +-- Register +dt.register_storage("video_mencoder", "Video Export (MEncoder)", show_status, create_video) From 92dcb2901043ab9dd46316f1e7b1e3270c0e7f41 Mon Sep 17 00:00:00 2001 From: supertobi Date: Mon, 4 Jan 2016 22:52:31 +0100 Subject: [PATCH 015/865] Update slideshowMusic.lua Test if old_view is nil --- contrib/slideshowMusic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index d5575a2b..0ba09d90 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -59,7 +59,7 @@ local function playSlideshowMusic(_, old_view, new_view) --dt.print_error(playCommand) coroutine.yield("RUN_COMMAND", playCommand) else - if (old_view.id == "slideshow") then + if (old_view and old_view.id == "slideshow") then stopCommand = "rhythmbox-client --pause" --dt.print_error(stopCommand) coroutine.yield("RUN_COMMAND", stopCommand) From d2a34226a6cbf4055d1d1e99b434451be82b47f7 Mon Sep 17 00:00:00 2001 From: supertobi Date: Mon, 4 Jan 2016 22:53:10 +0100 Subject: [PATCH 016/865] Update slideshowMusic.lua Tested with darktable 2.0 --- contrib/slideshowMusic.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index 0ba09d90..3ba89445 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -25,7 +25,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,2}) +dt.configuration.check_version(...,{2,0,2},{3,0,0}) local function checkIfBinExists(bin) local handle = io.popen("which "..bin) From 38bda12c4bd53f0d4be35a144b5b61df8e452bda Mon Sep 17 00:00:00 2001 From: supertobi Date: Mon, 4 Jan 2016 22:59:18 +0100 Subject: [PATCH 017/865] Update calcDistance.lua Tested with darktable 2.0 --- contrib/calcDistance.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/calcDistance.lua b/contrib/calcDistance.lua index c21dd69d..807e23ab 100644 --- a/contrib/calcDistance.lua +++ b/contrib/calcDistance.lua @@ -26,7 +26,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,1}) +dt.configuration.check_version(...,{2,0,1},{3,0,0}) local function calcDistance() local sel_images = dt.gui.selection() From 0b3b095eac78e8653c72ec95b33fd2960baeb34e Mon Sep 17 00:00:00 2001 From: supertobi Date: Mon, 4 Jan 2016 23:00:33 +0100 Subject: [PATCH 018/865] Update kml_export.lua Tested with darktable 2.0 --- contrib/kml_export.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index da3c2d42..e9e1a312 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -33,7 +33,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,1}) +dt.configuration.check_version(...,{2,0,1},{3,0,0}) local function spairs(_table, order) -- Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua -- collect the keys From 15cd18a5c446832bd4001211e9e0f5b37c57e0d0 Mon Sep 17 00:00:00 2001 From: supertobi Date: Mon, 4 Jan 2016 23:02:01 +0100 Subject: [PATCH 019/865] Update preferenceExamples.lua Tested with darktable 2.0 --- contrib/preferenceExamples.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/preferenceExamples.lua b/contrib/preferenceExamples.lua index 34117e6f..9317aabd 100644 --- a/contrib/preferenceExamples.lua +++ b/contrib/preferenceExamples.lua @@ -22,7 +22,7 @@ USAGE * require this script from your main lua file ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,1}) +dt.configuration.check_version(...,{2,0,1},{3,0,0}) dt.preferences.register("preferenceExamples", -- script: This is a string used to avoid name collision in preferences (i.e namespace). Set it to something unique, usually the name of the script handling the preference. "preferenceExamplesString", -- name From 2e0ccef3f569b9d0943539a2d12e7d3b97dec769 Mon Sep 17 00:00:00 2001 From: supertobi Date: Tue, 5 Jan 2016 10:22:47 +0100 Subject: [PATCH 020/865] Update geo_uri.lua Changes suggested from Boucman --- contrib/geo_uri.lua | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/contrib/geo_uri.lua b/contrib/geo_uri.lua index 57f58bfd..857ae610 100644 --- a/contrib/geo_uri.lua +++ b/contrib/geo_uri.lua @@ -1,6 +1,6 @@ --[[ This file is part of darktable, - Copyright 2014 by Tobias Jakobs. + Copyright 2016 by Tobias Jakobs. 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 @@ -30,7 +30,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,1}) +dt.configuration.check_version(...,{3,0,0}) local function checkIfBinExists(bin) local handle = io.popen("which "..bin) @@ -57,34 +57,25 @@ local function openLocationInGnomeMaps() local lon1 = 0; local i = 0; - local sel_images = dt.gui.selection() - -- Use the first image with geo information for _,image in ipairs(sel_images) do if ((image.longitude and image.latitude) and (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then - - i = i + 1; - - if (i == 1) then - lat1 = image.latitude; - lon1 = image.longitude; - end - + lat1 = image.latitude; + lon1 = image.longitude; + break end end - if (lat1 and lon1) then - local startCommand - startCommand = "gnome-maps \"geo:" .. lat1 .. "," .. lon1 .."\"" - dt.print_error(startCommand) + local startCommand + startCommand = "gnome-maps \"geo:" .. lat1 .. "," .. lon1 .."\"" + dt.print_error(startCommand) - if coroutine.yield("RUN_COMMAND", startCommand) then - dt.print("Command failed ...") - end + if coroutine.yield("RUN_COMMAND", startCommand) then + dt.print("Command failed ...") end - + end end From eff4a3abcbd27aa1d79e221f436ff3999d08ad34 Mon Sep 17 00:00:00 2001 From: supertobi Date: Tue, 5 Jan 2016 10:28:31 +0100 Subject: [PATCH 021/865] Update geo_uri.lua removed the old warning --- contrib/geo_uri.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/contrib/geo_uri.lua b/contrib/geo_uri.lua index 857ae610..34ed1c40 100644 --- a/contrib/geo_uri.lua +++ b/contrib/geo_uri.lua @@ -21,9 +21,6 @@ darktable script to open a geo uri in gnome-maps ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT * gnome-maps >= 3.20 -WARNING -This script is not testet. - USAGE * require this script from your main lua file * register a shortcut From cba5c65608a1f601627d905d6af65a25c68e4d89 Mon Sep 17 00:00:00 2001 From: supertobi Date: Tue, 5 Jan 2016 22:05:18 +0100 Subject: [PATCH 022/865] Update gps_select.lua Tested with darktable 2.0 --- contrib/gps_select.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/gps_select.lua b/contrib/gps_select.lua index 14fbf75b..69559718 100644 --- a/contrib/gps_select.lua +++ b/contrib/gps_select.lua @@ -24,7 +24,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,1}) +dt.configuration.check_version(...,{2,0,1},{3,0,0}) table = require "table" local function selectWithGPS() From a819140c88a2436e83035ca1b0799103a71727df Mon Sep 17 00:00:00 2001 From: supertobi Date: Tue, 5 Jan 2016 22:12:57 +0100 Subject: [PATCH 023/865] Update hugin.lua Tested with darktable 2.0 --- contrib/hugin.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/hugin.lua b/contrib/hugin.lua index 819e5b26..40c2371f 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -35,8 +35,8 @@ This plugin will add a new storage option and calls hugin after export. local dt = require "darktable" --- should work with darktable API version 2.0.0 -dt.configuration.check_version(...,{2,0,0}) +-- works with darktable API version 2.0.0 and 3.0.0 +dt.configuration.check_version(...,{2,0,0},{3,0,0}) local function checkIfBinExists(bin) local handle = io.popen("which "..bin) From 98a41444035efcdd78ba4545e228297cf5165df3 Mon Sep 17 00:00:00 2001 From: wpferguson Date: Wed, 6 Jan 2016 10:51:56 -0500 Subject: [PATCH 024/865] Update selection_to_pdf.lua Added API version 3.0.0 for compatibility with Darktable 2.0. Tested with Darktable 2.0. --- official/selection_to_pdf.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/official/selection_to_pdf.lua b/official/selection_to_pdf.lua index 2930e551..8444e8e8 100644 --- a/official/selection_to_pdf.lua +++ b/official/selection_to_pdf.lua @@ -31,7 +31,7 @@ This plugin will add a new exporter that will allow you to generate the pdf file ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,0}) +dt.configuration.check_version(...,{2,0,0},{3,0,0}) dt.preferences.register ("selection_to_pdf","Open with","string", From 1d3a44a157a570abd4d474b51d41fd5dd47b1c81 Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 7 Jan 2016 09:08:35 +0100 Subject: [PATCH 025/865] Update calcDistance.lua Add the elevation to the calculation of the distance --- contrib/calcDistance.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/contrib/calcDistance.lua b/contrib/calcDistance.lua index 807e23ab..1c76c72b 100644 --- a/contrib/calcDistance.lua +++ b/contrib/calcDistance.lua @@ -1,6 +1,6 @@ --[[ This file is part of darktable, - Copyright 2014 by Tobias Jakobs. + Copyright 2014-2016 by Tobias Jakobs. 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 @@ -26,7 +26,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,1},{3,0,0}) +dt.configuration.check_version(...,{3,0,0}) local function calcDistance() local sel_images = dt.gui.selection() @@ -71,6 +71,11 @@ local function calcDistance() local angle = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)); local distance = earthRadius * angle; -- Distance in km + -- Add the elevation to the calculation + local elevation = 0; + elevation = math.abs(ele1 - ele2) / 1000; --in km + distance = math.sqrt(math.pow(elevation,2) + math.pow(distance,2) ); + dt.print(distance.." km") From fc7a25ca4d56bcc4047c24c2b29cadd311832ef5 Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Thu, 7 Jan 2016 11:23:34 +0100 Subject: [PATCH 026/865] Mark most official scripts as compatible with dt2 --- official/check_for_updates.lua | 2 +- official/delete_long_tags.lua | 2 +- official/generate_image_txt.lua | 4 ++-- official/hello_world.lua | 2 +- official/image_path_in_ui.lua | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/official/check_for_updates.lua b/official/check_for_updates.lua index 659bc284..d102e739 100644 --- a/official/check_for_updates.lua +++ b/official/check_for_updates.lua @@ -31,7 +31,7 @@ local dt = require "darktable" local https = require "ssl.https" local cjson = require "cjson" -dt.configuration.check_version(...,{2,0,0}) +dt.configuration.check_version(...,{2,0,0},{3,0,0}) -- compare two version strings of the form "major.minor.patch" -- returns -1, 0, 1 if the first version is smaller, equal, greater than the second version, diff --git a/official/delete_long_tags.lua b/official/delete_long_tags.lua index 2986f86d..921a4388 100644 --- a/official/delete_long_tags.lua +++ b/official/delete_long_tags.lua @@ -29,7 +29,7 @@ all tags longer than the given length will be automatically deleted at every res ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,0}) +dt.configuration.check_version(...,{2,0,0},{3,0,0}) dt.preferences.register("delete_long_tags", "length", "integer", "maximum length of tags to keep", diff --git a/official/generate_image_txt.lua b/official/generate_image_txt.lua index 7d8b6974..416a8cef 100644 --- a/official/generate_image_txt.lua +++ b/official/generate_image_txt.lua @@ -31,12 +31,12 @@ USAGE -- TODO: -- * enable showing of the txt file (plugins/lighttable/draw_custom_metadata) if this script is enabled --- * maybe allow a lua command returning text instead of a command line call ? both ? +-- * maybe allow a lua command returning text instead of a command line call? both? -- * make filenames with double quotes (") work local dt = require "darktable" require "darktable.debug" -dt.configuration.check_version(...,{2,1,0}) +dt.configuration.check_version(...,{2,1,0},{3,0,0}) dt.preferences.register("generate_image_txt", "enabled", diff --git a/official/hello_world.lua b/official/hello_world.lua index e9028fbd..c2997ac1 100644 --- a/official/hello_world.lua +++ b/official/hello_world.lua @@ -27,7 +27,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,0}) +dt.configuration.check_version(...,{2,0,0},{3,0,0}) dt.print("hello, world") diff --git a/official/image_path_in_ui.lua b/official/image_path_in_ui.lua index ba93d2d8..77b1f9ff 100644 --- a/official/image_path_in_ui.lua +++ b/official/image_path_in_ui.lua @@ -29,7 +29,7 @@ This plugin will add a widget at the bottom of the left column in lighttable mod ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,0}) +dt.configuration.check_version(...,{2,0,0},{3,0,0}) local main_label = dt.new_widget("label"){selectable = true, ellipsize = "middle", halign = "start"} From 29c522484c60fd4072385896510f8e77c375823a Mon Sep 17 00:00:00 2001 From: Tobias Jakobs Date: Thu, 7 Jan 2016 22:01:51 +0100 Subject: [PATCH 027/865] gettextExample.lua with po and mo files --- contrib/de_DE/LC_MESSAGES/gettextExample.mo | Bin 0 -> 596 bytes contrib/de_DE/LC_MESSAGES/gettextExample.po | 20 ++++++++ contrib/gettextExample.lua | 51 ++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 contrib/de_DE/LC_MESSAGES/gettextExample.mo create mode 100644 contrib/de_DE/LC_MESSAGES/gettextExample.po create mode 100644 contrib/gettextExample.lua diff --git a/contrib/de_DE/LC_MESSAGES/gettextExample.mo b/contrib/de_DE/LC_MESSAGES/gettextExample.mo new file mode 100644 index 0000000000000000000000000000000000000000..d0ec975e6f221cb53e8f50151df7a29177c861b0 GIT binary patch literal 596 zcmZvZ&u-K(5XJ+7OW@QqhuIs5b(&-mteh^YT3WWS6#>GZ6VhxlWL>=W%J#POL3lmx zyakgiZ7z)TljqaS*q`m+d-r}t9Cw*V%$T{)957v!%tPiq^XEntU#!#3C@P)3pgM@NMtmmcl{FF;TZEQEpr4^4AL8;|C5|0o;Hr3qfh6Q<_FSZy zNMCR&CzGdXmZsb&KG3D=cKJ_VCMWr>Z-G9D%AxTZgLM)ryHx1m4gRo84+o)_$we;@ z+chek)OP(cUZ82W*pjFS*Ai~Egofhtv-6YT5?PYQ$JPWgeAM-ZJ$Lun-)K~(fO>__ zQ<#0KPQ`TS>nwdICr(Ul8)aGv)1?aWSMiz*xt-V2QlkQ7$uxP!m7Nqv=xKvtB_WAR zy>+O?sdZ~F!EAczXL$j;boSW5Xa?DnVwitR*H_jxexZDjH?Lnb|Gq)yMN<#Cxk* literal 0 HcmV?d00001 diff --git a/contrib/de_DE/LC_MESSAGES/gettextExample.po b/contrib/de_DE/LC_MESSAGES/gettextExample.po new file mode 100644 index 00000000..25cd06be --- /dev/null +++ b/contrib/de_DE/LC_MESSAGES/gettextExample.po @@ -0,0 +1,20 @@ +msgid "" +msgstr "" +"Project-Id-Version: Lua gettextTest\n" +"POT-Creation-Date: 2016-01-07 20:33+0100\n" +"PO-Revision-Date: 2016-01-07 21:32+0100\n" +"Last-Translator: Tobias Jakobs \n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.4\n" +"X-Poedit-Basepath: .\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-KeywordsList: gettext;dgettext:2;dcgettext:2;ngettext:1,2;dngettext:2,3\n" +"X-Poedit-SearchPath-0: .\n" + +#: gettextExample.lua:36 +msgid "Hello World!" +msgstr "Hallo Welt!" diff --git a/contrib/gettextExample.lua b/contrib/gettextExample.lua new file mode 100644 index 00000000..7a904101 --- /dev/null +++ b/contrib/gettextExample.lua @@ -0,0 +1,51 @@ +--[[ + This file is part of darktable, + Copyright 2016 by Tobias Jakobs. + + 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 . +]] +--[[ +darktable script to show how translations works + +To create a .mo file run: +msgfmt -v gettextExample.po -o gettextExample.mo + +USAGE +* require this script from your main lua file (Add 'require "gettextExample"' to luarc.) +* copy the script to: .config/darktable/lua/ +* copy the gettextExample.mo to .config/darktable/lua/de_DE/LC_MESSAGES + +You need to start darktable with the Lua debug option: darktable -d lua +$LANG must set to: de_DE + +The script run on darktable startup and should output this three lines: + +LUA ERROR Hello World! +LUA ERROR Bild +LUA ERROR Hallo Welt! + +]] +local dt = require "darktable" +dt.configuration.check_version(...,{3,0,0}) + +-- Not translated Text +dt.print_error("Hello World!") + +-- Translate a string using the darktable textdomain +dt.print_error(dt.gettext.gettext("image")) + +-- Tell gettext where to find the .mo file translating messages for a particular domain +dt.gettext.bindtextdomain("gettextExample",".config/darktable/lua/") +-- Translate a string using the specified textdomain +dt.print_error(dt.gettext.dgettext("gettextExample", 'Hello World!')) From bc1b908063ac180a0e6f2c955d241f23ccf57354 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 10 Jan 2016 22:28:53 +0100 Subject: [PATCH 028/865] Update kml_export.lua - support of image.title and image.description - support of image.elevation - don't add to many images to the kmz file --- contrib/kml_export.lua | 57 +++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index e9e1a312..ff5ab532 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -33,7 +33,7 @@ USAGE ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,1},{3,0,0}) +dt.configuration.check_version(...,{3,0,0}) local function spairs(_table, order) -- Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua -- collect the keys @@ -110,21 +110,29 @@ local function create_kml_file(storage, image_table, extra_data) -- Create the thumbnails for _,image in pairs(image_table) do - local path, filename, filetype = string.match(image, "(.-)([^\\/]-%.?([^%.\\/]*))$") - filename = string.upper(string.gsub(filename,"%.", "_")) + if ((_.longitude and _.latitude) and + (_.longitude ~= 0 and _.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + local path, filename, filetype = string.match(image, "(.-)([^\\/]-%.?([^%.\\/]*))$") + filename = string.upper(string.gsub(filename,"%.", "_")) - -- convert -size 92x92 filename.jpg -resize 92x92 +profile "*" thumbnail.jpg - -- In this example, '-size 120x120' gives a hint to the JPEG decoder that the image is going to be downscaled to - -- 120x120, allowing it to run faster by avoiding returning full-resolution images to GraphicsMagick for the - -- subsequent resizing operation. The '-resize 120x120' specifies the desired dimensions of the output image. It - -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other - -- profiles that might be present in the input and aren't needed in the thumbnail. - - local concertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" - -- USE coroutine.yield. It does not block the UI - coroutine.yield("RUN_COMMAND", concertToThumbCommand) - local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" - coroutine.yield("RUN_COMMAND", concertCommand) + -- convert -size 92x92 filename.jpg -resize 92x92 +profile "*" thumbnail.jpg + -- In this example, '-size 120x120' gives a hint to the JPEG decoder that the image is going to be downscaled to + -- 120x120, allowing it to run faster by avoiding returning full-resolution images to GraphicsMagick for the + -- subsequent resizing operation. The '-resize 120x120' specifies the desired dimensions of the output image. It + -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other + -- profiles that might be present in the input and aren't needed in the thumbnail. + + local concertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" + -- USE coroutine.yield. It does not block the UI + coroutine.yield("RUN_COMMAND", concertToThumbCommand) + local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" + coroutine.yield("RUN_COMMAND", concertCommand) + end + + -- delete the original image to not get into the kmz file + local rmCommand = "rm "..image + coroutine.yield("RUN_COMMAND", rmCommand) local pattern = "[/]?([^/]+)$" filmName = string.match(_.film.path, pattern) @@ -134,7 +142,7 @@ local function create_kml_file(storage, image_table, extra_data) exportKMZFilename = filmName..".kmz" -- Create the KML file - kml_file = "\n" + local kml_file = "\n" kml_file = kml_file.."\n" kml_file = kml_file.."\n" @@ -149,8 +157,13 @@ local function create_kml_file(storage, image_table, extra_data) (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then kml_file = kml_file.." \n" - kml_file = kml_file.." "..image.filename.."\n" - --kml_file = kml_file.." \n" + if (image.title and image.title ~= "") then + kml_file = kml_file.." "..image.title.."\n" + else + kml_file = kml_file.." "..image.filename.."\n" + end + + kml_file = kml_file.." "..image.description.."\n" kml_file = kml_file.." + + +
+ + + + +]] + + file = io.open(exportDirectory.."/"..exportMapBoxHTMLFilename, "w") + file:write(mapBoxHTML_file) + file:close() + end + + file = io.open(exportDirectory.."/"..exportgeoJSONFilename, "w") + file:write(geoJSON_file) + file:close() + + dt.print("geoJSON file created in "..exportDirectory) + +-- Open the file with the standard programm + if ( dt.preferences.read("geoJSON_export","OpengeoJSONFile","bool") == true ) then + local geoJSONFileOpenCommand + geoJSONFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportgeoJSONFilename.."\"" + coroutine.yield("RUN_COMMAND", geoJSONFileOpenCommand) + end + + +end + +-- Preferences +dt.preferences.register("geoJSON_export", + "CreateMapBoxHTMLFile", + "bool", + _("geoJSON export: Create an additional HTML file"), + _("Creates a HTML file, that loads the geoJASON file. (Needs a MapBox key"), + false ) +dt.preferences.register("geoJSON_export", + "mapBoxKey", + "string", + _("geoJSON export: MapBox Key"), + _("https://www.mapbox.com/studio/account/tokens"), + '' ) +dt.preferences.register("geoJSON_export", + "OpengeoJSONFile", + "bool", + _("geoJSON export: Open geoJSON file after export"), + _("Opens the geoJSON file after the export with the standard program for geoJSON files"), + false ) + +local handle = io.popen("xdg-user-dir DESKTOP") +local result = handle:read() +handle:close() +dt.preferences.register("geoJSON_export", + "ExportDirectory", + "directory", + _("geoJSON export: Export directory"), + _("A directory that will be used to export the geoJSON files"), + result ) + +-- Register +dt.register_storage("geoJSON_export", "geoJSON Export", nil, create_geoJSON_file) From b2ee46804bdc6c2a012da6e461400c099130dd72 Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 17 Mar 2016 22:33:27 +0100 Subject: [PATCH 072/865] marked vars as local, changed gettext domain --- contrib/geoJSON_export.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index 30a2adf6..d19ceb97 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -40,7 +40,7 @@ dt.configuration.check_version(...,{3,0,0}) gettext.bindtextdomain("geoJSON_export",dt.configuration.config_dir.."/lua/") local function _(msgid) - return gettext.dgettext("kml_export", msgid) + return gettext.dgettext("geoJSON_export", msgid) end -- Sort a table @@ -101,10 +101,10 @@ local function create_geoJSON_file(storage, image_table, extra_data) dt.print_error("Will try to export geoJSON file now") - exportDirectory = dt.preferences.read("geoJSON_export","ExportDirectory","string") + local xportDirectory = dt.preferences.read("geoJSON_export","ExportDirectory","string") -- Creates dir if not exsists - imageFoldername = "files/" + local imageFoldername = "files/" local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername coroutine.yield("RUN_COMMAND", mkdirCommand) @@ -137,11 +137,11 @@ local function create_geoJSON_file(storage, image_table, extra_data) filmName = string.match(_.film.path, pattern) end - exportgeoJSONFilename = filmName..".geoJSON" - exportMapBoxHTMLFilename = filmName..".html" + local exportgeoJSONFilename = filmName..".geoJSON" + local exportMapBoxHTMLFilename = filmName..".html" -- Create the geoJSON file - geoJSON_file = [[ + local geoJSON_file = [[ { "type": "FeatureCollection", "features": [ @@ -265,12 +265,12 @@ local function create_geoJSON_file(storage, image_table, extra_data) ]] - file = io.open(exportDirectory.."/"..exportMapBoxHTMLFilename, "w") + local file = io.open(exportDirectory.."/"..exportMapBoxHTMLFilename, "w") file:write(mapBoxHTML_file) file:close() end - file = io.open(exportDirectory.."/"..exportgeoJSONFilename, "w") + local file = io.open(exportDirectory.."/"..exportgeoJSONFilename, "w") file:write(geoJSON_file) file:close() From ef96bfa98c1c4ecf18616cf57a2e38860a669cbb Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 17 Mar 2016 22:35:47 +0100 Subject: [PATCH 073/865] marked vars as local --- contrib/kml_export.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 0be2627e..75e1790d 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -29,7 +29,8 @@ WARNING This script is only tested with Linux USAGE -* require this script from your main lua file +* require this script from your main Lua file + ]] local dt = require "darktable" @@ -101,6 +102,7 @@ local function create_kml_file(storage, image_table, extra_data) dt.print_error("Will try to export KML file now") + local imageFoldername if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then if not checkIfBinExists("zip") then return @@ -234,7 +236,7 @@ local function create_kml_file(storage, image_table, extra_data) kml_file = kml_file.."
\n" kml_file = kml_file.."
" - file = io.open(exportDirectory.."/"..exportKMLFilename, "w") + local file = io.open(exportDirectory.."/"..exportKMLFilename, "w") file:write(kml_file) file:close() @@ -270,7 +272,7 @@ dt.preferences.register("kml_export", "OpenKmlFile", "bool", _("KML export: Open KML/KMZ file after export"), - _("Opens the KML file after the export with the standard programm for KML files"), + _("Opens the KML file after the export with the standard program for KML files"), false ) local handle = io.popen("xdg-user-dir DESKTOP") From f64892d0103cb7b5c4ec5a50b80ba5a689ba9e7c Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 20 Mar 2016 21:50:25 +0100 Subject: [PATCH 074/865] concertToThumbCommand -> convertToThumbCommand --- contrib/geoJSON_export.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index d19ceb97..cbac2a38 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -123,9 +123,9 @@ local function create_geoJSON_file(storage, image_table, extra_data) -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other -- profiles that might be present in the input and aren't needed in the thumbnail. - local concertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" + local convertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" -- USE coroutine.yield. It does not block the UI - coroutine.yield("RUN_COMMAND", concertToThumbCommand) + coroutine.yield("RUN_COMMAND", convertToThumbCommand) local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" coroutine.yield("RUN_COMMAND", concertCommand) end From 2a2bb7199e46b70908be3698be24cb2ca09e4551 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 20 Mar 2016 21:51:26 +0100 Subject: [PATCH 075/865] concertToThumbCommand -> convertToThumbCommand --- contrib/kml_export.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 75e1790d..5cf24d7a 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -134,9 +134,9 @@ local function create_kml_file(storage, image_table, extra_data) -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other -- profiles that might be present in the input and aren't needed in the thumbnail. - local concertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" + local convertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" -- USE coroutine.yield. It does not block the UI - coroutine.yield("RUN_COMMAND", concertToThumbCommand) + coroutine.yield("RUN_COMMAND", convertToThumbCommand) local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" coroutine.yield("RUN_COMMAND", concertCommand) end From 027a24983723122f96cfbb0783c359fcc48a2ccd Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 20 Mar 2016 22:03:41 +0100 Subject: [PATCH 076/865] _ -> exported_image --- contrib/geoJSON_export.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index cbac2a38..af4836d1 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -109,9 +109,9 @@ local function create_geoJSON_file(storage, image_table, extra_data) coroutine.yield("RUN_COMMAND", mkdirCommand) -- Create the thumbnails - for _,image in pairs(image_table) do - if ((_.longitude and _.latitude) and - (_.longitude ~= 0 and _.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + for exported_image,image in pairs(image_table) do + if ((exported_image.longitude and exported_image.latitude) and + (exported_image.longitude ~= 0 and exported_image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then local path, filename, filetype = string.match(image, "(.-)([^\\/]-%.?([^%.\\/]*))$") filename = string.upper(string.gsub(filename,"%.", "_")) @@ -134,7 +134,7 @@ local function create_geoJSON_file(storage, image_table, extra_data) os.remove(image) local pattern = "[/]?([^/]+)$" - filmName = string.match(_.film.path, pattern) + filmName = string.match(exported_image.film.path, pattern) end local exportgeoJSONFilename = filmName..".geoJSON" @@ -147,7 +147,7 @@ local function create_geoJSON_file(storage, image_table, extra_data) "features": [ ]] - for image,_ in pairs(image_table) do + for image,exported_image in pairs(image_table) do filename = string.upper(string.gsub(image.filename,"%.", "_")) if ((image.longitude and image.latitude) and From fb171a459eb00cb0a10e6ef263e7b8a5f0ce5ce4 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 20 Mar 2016 22:21:40 +0100 Subject: [PATCH 077/865] Update geoJSON_export.lua --- contrib/geoJSON_export.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index af4836d1..aca16a5c 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -147,11 +147,11 @@ local function create_geoJSON_file(storage, image_table, extra_data) "features": [ ]] - for image,exported_image in pairs(image_table) do - filename = string.upper(string.gsub(image.filename,"%.", "_")) + for exported_image,image in pairs(image_table) do + filename = string.upper(string.gsub(exported_image.filename,"%.", "_")) - if ((image.longitude and image.latitude) and - (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + if ((exported_image.longitude and exported_image.latitude) and + (exported_image.longitude ~= 0 and exported_image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then geoJSON_file = geoJSON_file.. [[ { @@ -159,12 +159,12 @@ local function create_geoJSON_file(storage, image_table, extra_data) "geometry": { "type": "Point", ]] - geoJSON_file = geoJSON_file.." \"coordinates\": ["..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".").."]\n" + geoJSON_file = geoJSON_file.." \"coordinates\": ["..string.gsub(tostring(exported_image.longitude),",", ".")..","..string.gsub(tostring(exported_image.latitude),",", ".").."]\n" geoJSON_file = geoJSON_file.. [[ }, "properties": { - "title": "]]..image.title..[[", - "description": "]]..image.description..[[", + "title": "]]..exported_image.title..[[", + "description": "]]..exported_image.description..[[", "image": "]]..imageFoldername..filename..[[.jpg", "icon": { "iconUrl": "]]..imageFoldername.."thumb_"..filename..[[.jpg", From ebda3865dc996a6bd21a80e51d809fb40429b9b4 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 20 Mar 2016 22:36:58 +0100 Subject: [PATCH 078/865] Update geoJSON_export.lua --- contrib/geoJSON_export.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index aca16a5c..c5fc0b7c 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -109,9 +109,9 @@ local function create_geoJSON_file(storage, image_table, extra_data) coroutine.yield("RUN_COMMAND", mkdirCommand) -- Create the thumbnails - for exported_image,image in pairs(image_table) do - if ((exported_image.longitude and exported_image.latitude) and - (exported_image.longitude ~= 0 and exported_image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + for image,exported_image in pairs(image_table) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then local path, filename, filetype = string.match(image, "(.-)([^\\/]-%.?([^%.\\/]*))$") filename = string.upper(string.gsub(filename,"%.", "_")) @@ -123,10 +123,10 @@ local function create_geoJSON_file(storage, image_table, extra_data) -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other -- profiles that might be present in the input and aren't needed in the thumbnail. - local convertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" + local convertToThumbCommand = "convert -size 96x96 "..exported_image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" -- USE coroutine.yield. It does not block the UI coroutine.yield("RUN_COMMAND", convertToThumbCommand) - local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" + local concertCommand = "convert -size 438x438 "..exported_image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" coroutine.yield("RUN_COMMAND", concertCommand) end @@ -134,7 +134,7 @@ local function create_geoJSON_file(storage, image_table, extra_data) os.remove(image) local pattern = "[/]?([^/]+)$" - filmName = string.match(exported_image.film.path, pattern) + filmName = string.match(image.film.path, pattern) end local exportgeoJSONFilename = filmName..".geoJSON" @@ -147,11 +147,11 @@ local function create_geoJSON_file(storage, image_table, extra_data) "features": [ ]] - for exported_image,image in pairs(image_table) do - filename = string.upper(string.gsub(exported_image.filename,"%.", "_")) + for image,exported_image in pairs(image_table) do + filename = string.upper(string.gsub(image.filename,"%.", "_")) - if ((exported_image.longitude and exported_image.latitude) and - (exported_image.longitude ~= 0 and exported_image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then geoJSON_file = geoJSON_file.. [[ { @@ -159,12 +159,12 @@ local function create_geoJSON_file(storage, image_table, extra_data) "geometry": { "type": "Point", ]] - geoJSON_file = geoJSON_file.." \"coordinates\": ["..string.gsub(tostring(exported_image.longitude),",", ".")..","..string.gsub(tostring(exported_image.latitude),",", ".").."]\n" + geoJSON_file = geoJSON_file.." \"coordinates\": ["..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".").."]\n" geoJSON_file = geoJSON_file.. [[ }, "properties": { - "title": "]]..exported_image.title..[[", - "description": "]]..exported_image.description..[[", + "title": "]]..image.title..[[", + "description": "]]..image.description..[[", "image": "]]..imageFoldername..filename..[[.jpg", "icon": { "iconUrl": "]]..imageFoldername.."thumb_"..filename..[[.jpg", From 17a8c4f3d5eaa81b2c96f96e58c5add2b32cc664 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 20 Mar 2016 22:59:18 +0100 Subject: [PATCH 079/865] naming changes _ -> exported_image --- contrib/kml_export.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 5cf24d7a..f69efeda 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -120,11 +120,11 @@ local function create_kml_file(storage, image_table, extra_data) -- Create the thumbnails - for _,image in pairs(image_table) do - if ((_.longitude and _.latitude) and - (_.longitude ~= 0 and _.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + for image,exported_image in pairs(image_table) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then - local path, filename, filetype = string.match(image, "(.-)([^\\/]-%.?([^%.\\/]*))$") + local path, filename, filetype = string.match(exported_image, "(.-)([^\\/]-%.?([^%.\\/]*))$") filename = string.upper(string.gsub(filename,"%.", "_")) -- convert -size 92x92 filename.jpg -resize 92x92 +profile "*" thumbnail.jpg @@ -134,18 +134,18 @@ local function create_kml_file(storage, image_table, extra_data) -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other -- profiles that might be present in the input and aren't needed in the thumbnail. - local convertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" + local convertToThumbCommand = "convert -size 96x96 "..exported_image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" -- USE coroutine.yield. It does not block the UI coroutine.yield("RUN_COMMAND", convertToThumbCommand) - local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" + local concertCommand = "convert -size 438x438 "..exported_image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" coroutine.yield("RUN_COMMAND", concertCommand) end -- delete the original image to not get into the kmz file - os.remove(image) + os.remove(exported_image) local pattern = "[/]?([^/]+)$" - filmName = string.match(_.film.path, pattern) + filmName = string.match(image.film.path, pattern) end exportKMLFilename = filmName..".kml" @@ -160,7 +160,7 @@ local function create_kml_file(storage, image_table, extra_data) kml_file = kml_file..""..filmName.."\n" kml_file = kml_file.." Exported from darktable\n" - for image,_ in pairs(image_table) do + for image,exported_image in pairs(image_table) do filename = string.upper(string.gsub(image.filename,"%.", "_")) if ((image.longitude and image.latitude) and @@ -216,7 +216,7 @@ local function create_kml_file(storage, image_table, extra_data) kml_file = kml_file.." \n" kml_file = kml_file.." \n" - for image,_ in spairs(image_table, function(t,a,b) return t[b] < t[a] end) do + for image,exported_image in spairs(image_table, function(t,a,b) return t[b] < t[a] end) do if ((image.longitude and image.latitude) and (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then From 5006c9d6ea70001ee8427b0b959ed57add3fcb1f Mon Sep 17 00:00:00 2001 From: supertobi Date: Tue, 22 Mar 2016 22:34:53 +0100 Subject: [PATCH 080/865] Added missing elevation vars, improved short distance view --- contrib/calcDistance.lua | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/contrib/calcDistance.lua b/contrib/calcDistance.lua index ea1c4b42..b4ce9a11 100644 --- a/contrib/calcDistance.lua +++ b/contrib/calcDistance.lua @@ -43,6 +43,9 @@ local function calcDistance() local lon1 = 0; local lat2 = 0; local lon2 = 0; + local ele1 = 0; + local ele2 = 0; + local i = 0; local sel_images = dt.gui.selection() @@ -57,10 +60,12 @@ local function calcDistance() if (i == 1) then lat1 = image.latitude; lon1 = image.longitude; + ele1 = image.elevation; end lat2 = image.latitude; lon2 = image.longitude; + ele2 = image.elevation; end end @@ -84,7 +89,15 @@ local function calcDistance() elevation = math.abs(ele1 - ele2) / 1000; --in km distance = math.sqrt(math.pow(elevation,2) + math.pow(distance,2) ); - dt.print(distance.." km") + local distanceUnit + if (distance < 1) then + distance = distance * 1000 + distanceUnit = "m" + else + distanceUnit = "km" + end + dt.print(string.format("Distance: %.2f %s", distance, distanceUnit)) + end From 0c9d4a5de4cb94032e91d20848426376ff0954b4 Mon Sep 17 00:00:00 2001 From: supertobi Date: Wed, 23 Mar 2016 10:32:16 +0100 Subject: [PATCH 081/865] added tooltip to new_widget("entry") --- examples/moduleExample.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/moduleExample.lua b/examples/moduleExample.lua index 363ae76a..f484dff6 100644 --- a/examples/moduleExample.lua +++ b/examples/moduleExample.lua @@ -37,7 +37,7 @@ dt.configuration.check_version(...,{3,0,0}) -- add a new lib local check_button = dt.new_widget("check_button"){label = "MyCheck_button", value = true} local combobox = dt.new_widget("combobox"){label = "MyCombobox", value = 2, "8", "16", "32"} -local entry = dt.new_widget("entry"){text = "test", placeholder = "placeholder"} +local entry = dt.new_widget("entry"){text = "test", placeholder = "placeholder", tooltip = "tooltip"} local file_chooser_button = dt.new_widget("file_chooser_button"){title = "MyFile_chooser_button"} local label = dt.new_widget("label") label.label = "MyLabel" -- This is an alternative way to the "{}" syntax to set a property From f6e2037a1bce2fe177835d8a318f9598a91f2e82 Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Tue, 29 Mar 2016 19:52:31 +0200 Subject: [PATCH 082/865] Fix formatting of copyright header --- official/enfuse.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/official/enfuse.lua b/official/enfuse.lua index 32a835b0..3a0ac593 100644 --- a/official/enfuse.lua +++ b/official/enfuse.lua @@ -8,7 +8,7 @@ (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 + 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. From 6c4f9b2c03437e0d00ae60edd9f945b186077968 Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Tue, 29 Mar 2016 20:11:19 +0200 Subject: [PATCH 083/865] Add script to copy & paste metadata between images This not only takes care of tags (we already have a script for that in contrib) but also color labels, rating and the things from the metadata module. --- official/copy_paste_metadata.lua | 128 +++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 official/copy_paste_metadata.lua diff --git a/official/copy_paste_metadata.lua b/official/copy_paste_metadata.lua new file mode 100644 index 00000000..10281cac --- /dev/null +++ b/official/copy_paste_metadata.lua @@ -0,0 +1,128 @@ +--[[ + This file is part of darktable, + copyright (c) 2016 Tobias Ellinghaus + + 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 . +]] +--[[ +ADD SUPPORT FOR COPYING METADATA+RATING+COLOR LABELS+TAGS BETWEEN IMAGES +This script adds keyboard shortcuts and buttons to copy/paste metadata between images. + +USAGE + * require this script from your main lua file + * it adds buttons to the selected images module + * it adds two keyboard shortcuts +]] + +local dt = require "darktable" + +dt.configuration.check_version(...,{3,0,0}) + +-- set this to "false" if you don't want to overwrite metadata fields +-- (title, description, creator, publisher and rights) that are already set +local overwrite = true + +local have_data = false +local rating = 1 +local red = false +local green = false +local yellow = false +local blue = false +local purple = false +local title = "" +local description = "" +local creator = "" +local publisher = "" +local rights = "" +local tags = {} + +local function copy(image) + if not image then + have_data = false + else + have_data = true + rating = image.rating + red = image.red + green = image.green + yellow = image.yellow + blue = image.blue + purple = image.purple + title = image.title + description = image.description + creator = image.creator + publisher = image.publisher + rights = image.rights + tags = {} + for _, tag in ipairs(image:get_tags()) do + if not (string.sub(tag.name, 1, string.len("darktable|")) == "darktable|") then + table.insert(tags, tag) + end + end + end +end + +local function paste(images) + if have_data then + for _, image in ipairs(images) do + image.rating = rating + image.red = red + image.green = green + image.yellow = yellow + image.blue = blue + image.purple = purple + if image.title == "" or overwrite then + image.title = title + end + if image.description == "" or overwrite then + image.description = description + end + if image.creator == "" or overwrite then + image.creator = creator + end + if image.publisher == "" or overwrite then + image.publisher = publisher + end + if image.rights == "" or overwrite then + image.rights = rights + end + for _, tag in ipairs(tags) do + image:attach_tag(tag) + end + end + end +end + +dt.gui.libs.image.register_action( + "copy metadata", + function(event, images) copy(images[1]) end, + "copy metadata of the first selected image" +) + +dt.gui.libs.image.register_action( + "paste metadata", + function(event, images) paste(images) end, + "paste metadata to the selected images" +) + +dt.register_event( + "shortcut", + function(event, shortcut) copy(dt.gui.action_images[1]) end, + "copy metadata" +) + +dt.register_event( + "shortcut", + function(event, shortcut) paste(dt.gui.action_images) end, + "paste metadata" +) From 679ce8b6ab79de9c9b66c95b8702da9c405e5dc8 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 6 Apr 2016 22:21:13 -0400 Subject: [PATCH 084/865] Created gimp.lua to export an image to gimp for editing, then return the result and group it with the original image --- contrib/gimp.lua | 179 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 contrib/gimp.lua diff --git a/contrib/gimp.lua b/contrib/gimp.lua new file mode 100644 index 00000000..2b4720a1 --- /dev/null +++ b/contrib/gimp.lua @@ -0,0 +1,179 @@ +--[[ + + gimp.lua - export and edit with gimp + + Copyright (C) 2016 Bill Ferguson . + + Portions are lifted from hugin.lua and thus are + + Copyright (c) 2014 Wolfgang Goetz + Copyright (c) 2015 Christian Kanzian + Copyright (c) 2015 Tobias Jakobs + + + 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 . +]] +--[[ + gimp - export an image and open with gimp for editing + + This script provides another storage (export target) for darktable. Selected + images are exported in the specified format to temporary storage. Gimp is launched + and opens the files. After editing, the exported images are overwritten to save the + changes. When gimp exits, the exported files are moved into the current collection + and imported into the database. The imported files then show up grouped with the + originally selected images. + + ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT + * gimp - http://www.gimp.org + + USAGE + * require this script from your main lua file + * select an image or images for editing with gimp + * in the export dialog select "Edit with gimp" and select the format and bit depth for the + exported image + * Press "export" + * Edit the image with gimp then save the changes with File->Overwrite.... + * Exit gimp + * The edited image will be imported and grouped with the original image + + CAVEATS + * Developed and tested on Ubuntu 14.04 LTS with darktable 2.0.3 and gimp 2.9.3 (development version with + > 8 bit color) + * There is no provision for dealing with the xcf files generated by gimp, since darktable doesn't deal with + them. You may want to save the xcf file if you intend on doing further edits to the image or need to save + the layers used. Where you save them is up to you. + + BUGS, COMMENTS, SUGGESTIONS + * Send to Bill Ferguson, wpferguson@gmail.com +]] + +local dt = require "darktable" +local gettext = dt.gettext + +dt.configuration.check_version(...,{3,0,0}) + +-- Tell gettext where to find the .mo file translating messages for a particular domain +gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/") + +-- Thanks to http://lua-users.org/wiki/SplitJoin for the split and split_path functions +local function split(str, pat) + local t = {} -- NOTE: use {n = 0} in Lua-5.0 + local fpat = "(.-)" .. pat + local last_end = 1 + local s, e, cap = str:find(fpat, 1) + while s do + if s ~= 1 or cap ~= "" then + table.insert(t,cap) + end + last_end = e+1 + s, e, cap = str:find(fpat, last_end) + end + if last_end <= #str then + cap = str:sub(last_end) + table.insert(t, cap) + end + return t +end + +local function split_path(str) + return split(str,'[\\/]+') +end + +local function get_filename(str) + parts = split_path(str) + return parts[#parts] +end + +local function basename(str) + return string.sub(str,1,-4) +end + +local function _(msgid) + return gettext.dgettext("gimp", msgid) +end + +local function checkIfBinExists(bin) + local handle = io.popen("which "..bin) + local result = handle:read() + local ret + handle:close() + if (result) then + dt.print_error("true checkIfBinExists: "..bin) + ret = true + else + dt.print_error(bin.." not found") + ret = false + end + return ret +end + +local function show_status(storage, image, format, filename, + number, total, high_quality, extra_data) + dt.print("Exporting to gimp "..tostring(number).."/"..tostring(total)) +end + +local function gimp_edit(storage, image_table, extra_data) --finalize + if not checkIfBinExists("gimp") then + dt.print_error(_("gimp not found")) + return + end + + -- list of exported images + local img_list + + -- reset and create image list + img_list = "" + + for _,v in pairs(image_table) do + img_list = img_list ..v.. " " + end + + dt.print(_("Launching gimp...")) + + local gimpStartCommand + gimpStartCommand = "gimp "..img_list + + dt.print_error(gimpStartCommand) + + coroutine.yield("RUN_COMMAND", gimpStartCommand) + + -- for each of the exported images + -- find the matching original image + -- then move the exported image into the directory with the original + -- then import the image into the database which will group it with the original + -- and then copy over any tags other than darktable tags + + for _,v in pairs(image_table) do + local fname = get_filename(v) + for _,w in pairs(dt.gui.action_images) do + if basename(fname) == basename(w.filename) then + os.execute("mv "..v.." "..w.path) + local myimage = dt.database.import(w.path.."/"..fname) + for _,x in pairs(dt.tags.get_tags(w)) do + if not (string.sub(x.name,1,9) == "darktable") then + dt.tags.attach(x,myimage) + end + end + end + end + end + +end + +-- Register +dt.register_storage("module_gimp", _("Edit with gimp"), show_status, gimp_edit) + +-- + + From 4556c9a055addbc5eb8e534e53aefcb73ccacbff Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Thu, 7 Apr 2016 11:59:41 -0400 Subject: [PATCH 085/865] Incorporated comments from supertobi, marking string for translation on line 128 and expanding variable names for lines 157-165 --- contrib/gimp.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/contrib/gimp.lua b/contrib/gimp.lua index 2b4720a1..df1ead8a 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -120,7 +120,7 @@ end local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) - dt.print("Exporting to gimp "..tostring(number).."/"..tostring(total)) + dt.print(string.format(_("Exporting to gimp %i/%i", number, total))) end local function gimp_edit(storage, image_table, extra_data) --finalize @@ -135,8 +135,8 @@ local function gimp_edit(storage, image_table, extra_data) --finalize -- reset and create image list img_list = "" - for _,v in pairs(image_table) do - img_list = img_list ..v.. " " + for _,exp_img in pairs(image_table) do + img_list = img_list ..exp_img.. " " end dt.print(_("Launching gimp...")) @@ -154,15 +154,15 @@ local function gimp_edit(storage, image_table, extra_data) --finalize -- then import the image into the database which will group it with the original -- and then copy over any tags other than darktable tags - for _,v in pairs(image_table) do - local fname = get_filename(v) - for _,w in pairs(dt.gui.action_images) do - if basename(fname) == basename(w.filename) then - os.execute("mv "..v.." "..w.path) - local myimage = dt.database.import(w.path.."/"..fname) - for _,x in pairs(dt.tags.get_tags(w)) do - if not (string.sub(x.name,1,9) == "darktable") then - dt.tags.attach(x,myimage) + for _,exp_img in pairs(image_table) do + local fname = get_filename(exp_img) + for _,orig_img in pairs(dt.gui.action_images) do + if basename(fname) == basename(orig_img.filename) then + os.execute("mv "..exp_img.." "..orig_img.path) + local myimage = dt.database.import(orig_img.path.."/"..fname) + for _,tag in pairs(dt.tags.get_tags(orig_img)) do + if not (string.sub(tag.name,1,9) == "darktable") then + dt.tags.attach(tag,myimage) end end end From 2b577f975556f4152b05c4f7553121dea25c1939 Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 7 Apr 2016 23:29:08 +0200 Subject: [PATCH 086/865] improved the entry and file_chooser_button examples --- examples/moduleExample.lua | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/examples/moduleExample.lua b/examples/moduleExample.lua index f484dff6..91a34f0b 100644 --- a/examples/moduleExample.lua +++ b/examples/moduleExample.lua @@ -37,8 +37,25 @@ dt.configuration.check_version(...,{3,0,0}) -- add a new lib local check_button = dt.new_widget("check_button"){label = "MyCheck_button", value = true} local combobox = dt.new_widget("combobox"){label = "MyCombobox", value = 2, "8", "16", "32"} -local entry = dt.new_widget("entry"){text = "test", placeholder = "placeholder", tooltip = "tooltip"} -local file_chooser_button = dt.new_widget("file_chooser_button"){title = "MyFile_chooser_button"} + +--https://www.darktable.org/lua-api/ar01s02s54.html.php +local entry = dt.new_widget("entry") +{ + text = "test", + placeholder = "placeholder", + is_password = false, + editable = true, + tooltip = "Tooltip Text", + reset_callback = function(self) self.text = "text" end +} + +local file_chooser_button = dt.new_widget("file_chooser_button") +{ + title = "MyFile_chooser_button", -- The title of the window when choosing a file + value = "", -- The currently selected file + is_directory = false -- True if the file chooser button only allows directories to be selecte +} + local label = dt.new_widget("label") label.label = "MyLabel" -- This is an alternative way to the "{}" syntax to set a property From 8224913b0190e52b759f250a8a3d8a59f2d00950 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 9 Apr 2016 01:37:54 -0400 Subject: [PATCH 087/865] replaced string.format in show_status with the string and concatenation since string.format was having problems with the arguments. --- contrib/gimp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/gimp.lua b/contrib/gimp.lua index df1ead8a..e34f77f2 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -120,7 +120,7 @@ end local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) - dt.print(string.format(_("Exporting to gimp %i/%i", number, total))) + dt.print(_("Exporting to gimp "..tostring(number).."/"..tostring(total))) end local function gimp_edit(storage, image_table, extra_data) --finalize From 670915ab363a86879d7ba3f93ca386a1e0fc31d5 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 10 Apr 2016 00:05:34 +0200 Subject: [PATCH 088/865] fixed typo: will will -> will --- official/debug-helpers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/official/debug-helpers.lua b/official/debug-helpers.lua index 202a4113..568a6784 100644 --- a/official/debug-helpers.lua +++ b/official/debug-helpers.lua @@ -55,7 +55,7 @@ This is mainly used to debug callbacks, register_event(event, dhelpers.new_tracepoint("hit callback")) -will will print the following each time the callback is called +will print the following each time the callback is called **** hit callback **** From 9693b017c427ee6df917773fba5c61a0b1e31cb2 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sun, 10 Apr 2016 16:27:49 -0400 Subject: [PATCH 089/865] Changed back to string.format in show_status but coded it correctly this time. --- contrib/gimp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/gimp.lua b/contrib/gimp.lua index e34f77f2..b546e70d 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -120,7 +120,7 @@ end local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) - dt.print(_("Exporting to gimp "..tostring(number).."/"..tostring(total))) + dt.print(string.format(_("Export Image %i/%i"), number, total)) end local function gimp_edit(storage, image_table, extra_data) --finalize From 9dbd1d9bda1622ba0091dc2bd674100a03825a8d Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Thu, 14 Apr 2016 16:34:37 -0400 Subject: [PATCH 090/865] Incorporated supertobi's comments. Changed os.execute to os.rename to handle spaces and special characters. Capitalized GIMP in all print strings. Added de_DE translation. --- contrib/de_DE/LC_MESSAGES/gimp.po | 39 +++++++ gimp.lua | 186 ++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 contrib/de_DE/LC_MESSAGES/gimp.po create mode 100644 gimp.lua diff --git a/contrib/de_DE/LC_MESSAGES/gimp.po b/contrib/de_DE/LC_MESSAGES/gimp.po new file mode 100644 index 00000000..b3b0447c --- /dev/null +++ b/contrib/de_DE/LC_MESSAGES/gimp.po @@ -0,0 +1,39 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: gimp\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-04-13 23:50-0400\n" +"PO-Revision-Date: 2016-04-14 00:11-0500\n" +"Last-Translator: Bill Ferguson \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" +"Language: de_DE\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-KeywordsList: gettext;dgettext:2;dcgettext:2ngettext:1,2;" +"dngettext:2,3\n" +"X-Poedit-Basepath: .\n" + +#: gimp.lua:123 +#, lua-format +msgid "Export Image %i/%i" +msgstr "Exportiere Bild %i/%i" + +#: gimp.lua:129 +msgid "GIMP not found" +msgstr "GIMP nicht gefunden" + +#: gimp.lua:143 +msgid "Launching GIMP..." +msgstr "Starten von GIMP" + +#: gimp.lua:182 +msgid "Edit with GIMP" +msgstr "Bearbeiten mit Gimp" diff --git a/gimp.lua b/gimp.lua new file mode 100644 index 00000000..107a191c --- /dev/null +++ b/gimp.lua @@ -0,0 +1,186 @@ +--[[ + + gimp.lua - export and edit with GIMP + + Copyright (C) 2016 Bill Ferguson . + + Portions are lifted from hugin.lua and thus are + + Copyright (c) 2014 Wolfgang Goetz + Copyright (c) 2015 Christian Kanzian + Copyright (c) 2015 Tobias Jakobs + + + 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 . +]] +--[[ + gimp - export an image and open with GIMP for editing + + This script provides another storage (export target) for darktable. Selected + images are exported in the specified format to temporary storage. GIMP is launched + and opens the files. After editing, the exported images are overwritten to save the + changes. When GIMP exits, the exported files are moved into the current collection + and imported into the database. The imported files then show up grouped with the + originally selected images. + + ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT + * GIMP - http://www.gimp.org + + USAGE + * require this script from your main lua file + * select an image or images for editing with GIMP + * in the export dialog select "Edit with GIMP" and select the format and bit depth for the + exported image + * Press "export" + * Edit the image with GIMP then save the changes with File->Overwrite.... + * Exit GIMP + * The edited image will be imported and grouped with the original image + + CAVEATS + * Developed and tested on Ubuntu 14.04 LTS with darktable 2.0.3 and GIMP 2.9.3 (development version with + > 8 bit color) + * There is no provision for dealing with the xcf files generated by GIMP, since darktable doesn't deal with + them. You may want to save the xcf file if you intend on doing further edits to the image or need to save + the layers used. Where you save them is up to you. + + BUGS, COMMENTS, SUGGESTIONS + * Send to Bill Ferguson, wpferguson@gmail.com +]] + +local dt = require "darktable" +local gettext = dt.gettext + +dt.configuration.check_version(...,{3,0,0}) + +-- Tell gettext where to find the .mo file translating messages for a particular domain +gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/") + +-- Thanks to http://lua-users.org/wiki/SplitJoin for the split and split_path functions +local function split(str, pat) + local t = {} -- NOTE: use {n = 0} in Lua-5.0 + local fpat = "(.-)" .. pat + local last_end = 1 + local s, e, cap = str:find(fpat, 1) + while s do + if s ~= 1 or cap ~= "" then + table.insert(t,cap) + end + last_end = e+1 + s, e, cap = str:find(fpat, last_end) + end + if last_end <= #str then + cap = str:sub(last_end) + table.insert(t, cap) + end + return t +end + +local function split_path(str) + return split(str,'[\\/]+') +end + +local function get_filename(str) + parts = split_path(str) + return parts[#parts] +end + +local function basename(str) + return string.sub(str,1,-4) +end + +local function _(msgid) + return gettext.dgettext("gimp", msgid) +end + +local function checkIfBinExists(bin) + local handle = io.popen("which "..bin) + local result = handle:read() + local ret + handle:close() + if (result) then + dt.print_error("true checkIfBinExists: "..bin) + ret = true + else + dt.print_error(bin.." not found") + ret = false + end + return ret +end + +local function show_status(storage, image, format, filename, + number, total, high_quality, extra_data) + dt.print(string.format(_("Export Image %i/%i"), number, total)) +-- dt.print(_(string.format("Exporting to gimp %i/%i", number, total))) +end + +local function gimp_edit(storage, image_table, extra_data) --finalize + if not checkIfBinExists("gimp") then + dt.print_error(_("GIMP not found")) + return + end + + -- list of exported images + local img_list + + -- reset and create image list + img_list = "" + + for _,exp_img in pairs(image_table) do + img_list = img_list ..exp_img.. " " + end + + dt.print(_("Launching GIMP...")) + + local gimpStartCommand + gimpStartCommand = "gimp "..img_list + + dt.print_error(gimpStartCommand) + + coroutine.yield("RUN_COMMAND", gimpStartCommand) + + -- for each of the exported images + -- find the matching original image + -- then move the exported image into the directory with the original + -- then import the image into the database which will group it with the original + -- and then copy over any tags other than darktable tags + + for _,exp_img in pairs(image_table) do + local fname = get_filename(exp_img) + dt.print_error(fname) + for _,orig_img in pairs(dt.gui.action_images) do + if basename(fname) == basename(orig_img.filename) then + dt.print_error("moving file...") + local myimage_name = orig_img.path .. "/" .. fname + dt.print_error(myimage_name) + result = os.rename(exp_img, myimage_name) + dt.print_error("importing file") + local myimage = dt.database.import(myimage_name) + for _,tag in pairs(dt.tags.get_tags(orig_img)) do + if not (string.sub(tag.name,1,9) == "darktable") then + dt.print_error("attaching tag") + dt.tags.attach(tag,myimage) + end + end + end + end + end + +end + +-- Register +dt.register_storage("module_gimp", _("Edit with GIMP"), show_status, gimp_edit) + +-- + + From 9c40a22c5012a47727dfb76ecae68dce0f3638ff Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Thu, 14 Apr 2016 22:21:32 -0400 Subject: [PATCH 091/865] Removed gimp.lua from the top level --- gimp.lua | 186 ------------------------------------------------------- 1 file changed, 186 deletions(-) delete mode 100644 gimp.lua diff --git a/gimp.lua b/gimp.lua deleted file mode 100644 index 107a191c..00000000 --- a/gimp.lua +++ /dev/null @@ -1,186 +0,0 @@ ---[[ - - gimp.lua - export and edit with GIMP - - Copyright (C) 2016 Bill Ferguson . - - Portions are lifted from hugin.lua and thus are - - Copyright (c) 2014 Wolfgang Goetz - Copyright (c) 2015 Christian Kanzian - Copyright (c) 2015 Tobias Jakobs - - - 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 . -]] ---[[ - gimp - export an image and open with GIMP for editing - - This script provides another storage (export target) for darktable. Selected - images are exported in the specified format to temporary storage. GIMP is launched - and opens the files. After editing, the exported images are overwritten to save the - changes. When GIMP exits, the exported files are moved into the current collection - and imported into the database. The imported files then show up grouped with the - originally selected images. - - ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT - * GIMP - http://www.gimp.org - - USAGE - * require this script from your main lua file - * select an image or images for editing with GIMP - * in the export dialog select "Edit with GIMP" and select the format and bit depth for the - exported image - * Press "export" - * Edit the image with GIMP then save the changes with File->Overwrite.... - * Exit GIMP - * The edited image will be imported and grouped with the original image - - CAVEATS - * Developed and tested on Ubuntu 14.04 LTS with darktable 2.0.3 and GIMP 2.9.3 (development version with - > 8 bit color) - * There is no provision for dealing with the xcf files generated by GIMP, since darktable doesn't deal with - them. You may want to save the xcf file if you intend on doing further edits to the image or need to save - the layers used. Where you save them is up to you. - - BUGS, COMMENTS, SUGGESTIONS - * Send to Bill Ferguson, wpferguson@gmail.com -]] - -local dt = require "darktable" -local gettext = dt.gettext - -dt.configuration.check_version(...,{3,0,0}) - --- Tell gettext where to find the .mo file translating messages for a particular domain -gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/") - --- Thanks to http://lua-users.org/wiki/SplitJoin for the split and split_path functions -local function split(str, pat) - local t = {} -- NOTE: use {n = 0} in Lua-5.0 - local fpat = "(.-)" .. pat - local last_end = 1 - local s, e, cap = str:find(fpat, 1) - while s do - if s ~= 1 or cap ~= "" then - table.insert(t,cap) - end - last_end = e+1 - s, e, cap = str:find(fpat, last_end) - end - if last_end <= #str then - cap = str:sub(last_end) - table.insert(t, cap) - end - return t -end - -local function split_path(str) - return split(str,'[\\/]+') -end - -local function get_filename(str) - parts = split_path(str) - return parts[#parts] -end - -local function basename(str) - return string.sub(str,1,-4) -end - -local function _(msgid) - return gettext.dgettext("gimp", msgid) -end - -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (result) then - dt.print_error("true checkIfBinExists: "..bin) - ret = true - else - dt.print_error(bin.." not found") - ret = false - end - return ret -end - -local function show_status(storage, image, format, filename, - number, total, high_quality, extra_data) - dt.print(string.format(_("Export Image %i/%i"), number, total)) --- dt.print(_(string.format("Exporting to gimp %i/%i", number, total))) -end - -local function gimp_edit(storage, image_table, extra_data) --finalize - if not checkIfBinExists("gimp") then - dt.print_error(_("GIMP not found")) - return - end - - -- list of exported images - local img_list - - -- reset and create image list - img_list = "" - - for _,exp_img in pairs(image_table) do - img_list = img_list ..exp_img.. " " - end - - dt.print(_("Launching GIMP...")) - - local gimpStartCommand - gimpStartCommand = "gimp "..img_list - - dt.print_error(gimpStartCommand) - - coroutine.yield("RUN_COMMAND", gimpStartCommand) - - -- for each of the exported images - -- find the matching original image - -- then move the exported image into the directory with the original - -- then import the image into the database which will group it with the original - -- and then copy over any tags other than darktable tags - - for _,exp_img in pairs(image_table) do - local fname = get_filename(exp_img) - dt.print_error(fname) - for _,orig_img in pairs(dt.gui.action_images) do - if basename(fname) == basename(orig_img.filename) then - dt.print_error("moving file...") - local myimage_name = orig_img.path .. "/" .. fname - dt.print_error(myimage_name) - result = os.rename(exp_img, myimage_name) - dt.print_error("importing file") - local myimage = dt.database.import(myimage_name) - for _,tag in pairs(dt.tags.get_tags(orig_img)) do - if not (string.sub(tag.name,1,9) == "darktable") then - dt.print_error("attaching tag") - dt.tags.attach(tag,myimage) - end - end - end - end - end - -end - --- Register -dt.register_storage("module_gimp", _("Edit with GIMP"), show_status, gimp_edit) - --- - - From 6e5dbc0b83584679d8005cb3fed74a0f08281b65 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 15 Apr 2016 00:38:00 -0400 Subject: [PATCH 092/865] Incorporated supertobi's suggestions. Replaced file and path splitting code with a regular expression (thanks Tobias Jakobs) to ensure filenames were handled correctly. Used the image data in the image table pairs instead of darktable.gui.action_images to ensure there were no mismatches as well as clean up the code nicely. Updated gimp.po to reflect the line number changes due to code refactoring. --- contrib/de_DE/LC_MESSAGES/gimp.po | 8 +-- contrib/gimp.lua | 95 ++++++++++++------------------- 2 files changed, 39 insertions(+), 64 deletions(-) diff --git a/contrib/de_DE/LC_MESSAGES/gimp.po b/contrib/de_DE/LC_MESSAGES/gimp.po index b3b0447c..3df09d1e 100644 --- a/contrib/de_DE/LC_MESSAGES/gimp.po +++ b/contrib/de_DE/LC_MESSAGES/gimp.po @@ -21,19 +21,19 @@ msgstr "" "dngettext:2,3\n" "X-Poedit-Basepath: .\n" -#: gimp.lua:123 +#: gimp.lua:96 #, lua-format msgid "Export Image %i/%i" msgstr "Exportiere Bild %i/%i" -#: gimp.lua:129 +#: gimp.lua:101 msgid "GIMP not found" msgstr "GIMP nicht gefunden" -#: gimp.lua:143 +#: gimp.lua:115 msgid "Launching GIMP..." msgstr "Starten von GIMP" -#: gimp.lua:182 +#: gimp.lua:150 msgid "Edit with GIMP" msgstr "Bearbeiten mit Gimp" diff --git a/contrib/gimp.lua b/contrib/gimp.lua index b546e70d..24be479a 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -1,6 +1,6 @@ --[[ - gimp.lua - export and edit with gimp + gimp.lua - export and edit with GIMP Copyright (C) 2016 Bill Ferguson . @@ -25,32 +25,32 @@ along with this program. If not, see . ]] --[[ - gimp - export an image and open with gimp for editing + gimp - export an image and open with GIMP for editing This script provides another storage (export target) for darktable. Selected - images are exported in the specified format to temporary storage. Gimp is launched + images are exported in the specified format to temporary storage. GIMP is launched and opens the files. After editing, the exported images are overwritten to save the - changes. When gimp exits, the exported files are moved into the current collection + changes. When GIMP exits, the exported files are moved into the current collection and imported into the database. The imported files then show up grouped with the originally selected images. ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT - * gimp - http://www.gimp.org + * GIMP - http://www.gimp.org USAGE * require this script from your main lua file - * select an image or images for editing with gimp - * in the export dialog select "Edit with gimp" and select the format and bit depth for the + * select an image or images for editing with GIMP + * in the export dialog select "Edit with GIMP" and select the format and bit depth for the exported image * Press "export" - * Edit the image with gimp then save the changes with File->Overwrite.... - * Exit gimp + * Edit the image with GIMP then save the changes with File->Overwrite.... + * Exit GIMP * The edited image will be imported and grouped with the original image CAVEATS - * Developed and tested on Ubuntu 14.04 LTS with darktable 2.0.3 and gimp 2.9.3 (development version with + * Developed and tested on Ubuntu 14.04 LTS with darktable 2.0.3 and GIMP 2.9.3 (development version with > 8 bit color) - * There is no provision for dealing with the xcf files generated by gimp, since darktable doesn't deal with + * There is no provision for dealing with the xcf files generated by GIMP, since darktable doesn't deal with them. You may want to save the xcf file if you intend on doing further edits to the image or need to save the layers used. Where you save them is up to you. @@ -66,37 +66,10 @@ dt.configuration.check_version(...,{3,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/") --- Thanks to http://lua-users.org/wiki/SplitJoin for the split and split_path functions -local function split(str, pat) - local t = {} -- NOTE: use {n = 0} in Lua-5.0 - local fpat = "(.-)" .. pat - local last_end = 1 - local s, e, cap = str:find(fpat, 1) - while s do - if s ~= 1 or cap ~= "" then - table.insert(t,cap) - end - last_end = e+1 - s, e, cap = str:find(fpat, last_end) - end - if last_end <= #str then - cap = str:sub(last_end) - table.insert(t, cap) - end - return t -end - -local function split_path(str) - return split(str,'[\\/]+') -end - local function get_filename(str) - parts = split_path(str) - return parts[#parts] -end - -local function basename(str) - return string.sub(str,1,-4) + -- Thanks to Tobias Jakobs for the awesome regular expression + local path, filename, filetype = string.match(str, "(.-)([^\\/]-%.?([^%.\\/]*))$") + return filename end local function _(msgid) @@ -125,7 +98,7 @@ end local function gimp_edit(storage, image_table, extra_data) --finalize if not checkIfBinExists("gimp") then - dt.print_error(_("gimp not found")) + dt.print_error(_("GIMP not found")) return end @@ -139,7 +112,7 @@ local function gimp_edit(storage, image_table, extra_data) --finalize img_list = img_list ..exp_img.. " " end - dt.print(_("Launching gimp...")) + dt.print(_("Launching GIMP...")) local gimpStartCommand gimpStartCommand = "gimp "..img_list @@ -148,23 +121,25 @@ local function gimp_edit(storage, image_table, extra_data) --finalize coroutine.yield("RUN_COMMAND", gimpStartCommand) - -- for each of the exported images - -- find the matching original image - -- then move the exported image into the directory with the original - -- then import the image into the database which will group it with the original - -- and then copy over any tags other than darktable tags + -- for each of the image, exported image pairs + -- move the exported image into the directory with the original + -- then import the image into the database which will group it with the original + -- and then copy over any tags other than darktable tags - for _,exp_img in pairs(image_table) do - local fname = get_filename(exp_img) - for _,orig_img in pairs(dt.gui.action_images) do - if basename(fname) == basename(orig_img.filename) then - os.execute("mv "..exp_img.." "..orig_img.path) - local myimage = dt.database.import(orig_img.path.."/"..fname) - for _,tag in pairs(dt.tags.get_tags(orig_img)) do - if not (string.sub(tag.name,1,9) == "darktable") then - dt.tags.attach(tag,myimage) - end - end + for image,exported_image in pairs(image_table) do + + local myimage_name = image.path .. "/" .. get_filename(exported_image) + + dt.print_error("moving " .. exported_image .. " to " .. myimage_name) + result = os.rename(exported_image, myimage_name) + + dt.print_error("importing file") + local myimage = dt.database.import(myimage_name) + + for _,tag in pairs(dt.tags.get_tags(image)) do + if not (string.sub(tag.name,1,9) == "darktable") then + dt.print_error("attaching tag") + dt.tags.attach(tag,myimage) end end end @@ -172,7 +147,7 @@ local function gimp_edit(storage, image_table, extra_data) --finalize end -- Register -dt.register_storage("module_gimp", _("Edit with gimp"), show_status, gimp_edit) +dt.register_storage("module_gimp", _("Edit with GIMP"), show_status, gimp_edit) -- From 623b506691bdb69d2e2686ce81d1ac403efc20ca Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Fri, 15 Apr 2016 23:58:33 -0400 Subject: [PATCH 093/865] Added check to see if the export would overwrite an existing file. If it would, the filename was incremented with _XX where XX was an increment starting at 01 and ending at 99. gimp.po line numbers adjusted to reflect the changes in code. --- contrib/de_DE/LC_MESSAGES/gimp.po | 8 +-- contrib/gimp.lua | 99 ++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 7 deletions(-) diff --git a/contrib/de_DE/LC_MESSAGES/gimp.po b/contrib/de_DE/LC_MESSAGES/gimp.po index 3df09d1e..46214553 100644 --- a/contrib/de_DE/LC_MESSAGES/gimp.po +++ b/contrib/de_DE/LC_MESSAGES/gimp.po @@ -21,19 +21,19 @@ msgstr "" "dngettext:2,3\n" "X-Poedit-Basepath: .\n" -#: gimp.lua:96 +#: gimp.lua:179 #, lua-format msgid "Export Image %i/%i" msgstr "Exportiere Bild %i/%i" -#: gimp.lua:101 +#: gimp.lua:184 msgid "GIMP not found" msgstr "GIMP nicht gefunden" -#: gimp.lua:115 +#: gimp.lua:198 msgid "Launching GIMP..." msgstr "Starten von GIMP" -#: gimp.lua:150 +#: gimp.lua:243 msgid "Edit with GIMP" msgstr "Bearbeiten mit Gimp" diff --git a/contrib/gimp.lua b/contrib/gimp.lua index 24be479a..6a825a03 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -66,10 +66,31 @@ dt.configuration.check_version(...,{3,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/") +local function split_filepath(str) + local result = {} + -- Thank you Tobias Jakobs for the awesome regular expression, which I tweaked a little + result["path"], result["filename"], result["basename"], result["filetype"] = string.match(str, "(.-)(([^\\/]-)%.?([^%.\\/]*))$") + return result +end + +local function get_path(str) + local parts = split_filepath(str) + return parts["path"] +end + local function get_filename(str) - -- Thanks to Tobias Jakobs for the awesome regular expression - local path, filename, filetype = string.match(str, "(.-)([^\\/]-%.?([^%.\\/]*))$") - return filename + local parts = split_filepath(str) + return parts["filename"] +end + +local function get_basename(str) + local parts = split_filepath(str) + return parts["basename"] +end + +local function get_filetype(str) + local parts = split_filepath(str) + return parts["filetype"] end local function _(msgid) @@ -91,6 +112,68 @@ local function checkIfBinExists(bin) return ret end +local function checkIfFileExists(filepath) + local handle = io.popen("ls "..filepath) + local result = handle:read() + local ret + handle:close() + if (result) then + dt.print_error("true checkIfFileExists: "..filepath) + ret = true + else + dt.print_error(filepath.." not found") + ret = false + end + return ret +end + +local function filename_increment(filepath) + + -- break up the filepath into parts + local path = get_path(filepath) + local basename = get_basename(filepath) + local filetype = get_filetype(filepath) + + -- check to see if we've incremented before + local increment = string.match(basename, "_(%d-)$") + + if increment then + -- we do 2 digit increments so make sure we didn't grab part of the filename + if string.len(increment) > 2 then + -- we got the filename so set the increment to 01 + increment = "01" + else + increment = string.format("%02d", tonumber(increment) + 1) + basename = string.gsub(basename, "_(%d-)$", "") + end + else + increment = "01" + end + local incremented_filepath = path .. basename .. "_" .. increment .. "." .. filetype + + dt.print_error("original file was " .. filepath) + dt.print_error("incremented file is " .. incremented_filepath) + + return incremented_filepath +end + +local function groupIfNotMember(img, new_img) + local image_table = img:get_group_members() + local is_member = false + for _,image in ipairs(image_table) do + dt.print_error(image.filename .. " is a member") + if image.filename == new_img.filename then + is_member = true + dt.print_error("Already in group") + end + end + if not is_member then + dt.print_error("group leader is "..img.group_leader.filename) + new_img:group_with(img.group_leader) + dt.print_error("Added to group") + end +end + local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) dt.print(string.format(_("Export Image %i/%i"), number, total)) @@ -130,12 +213,22 @@ local function gimp_edit(storage, image_table, extra_data) --finalize local myimage_name = image.path .. "/" .. get_filename(exported_image) + while checkIfFileExists(myimage_name) do + myimage_name = filename_increment(myimage_name) + -- limit to 99 more exports of the original export + if string.match(get_basename(myimage_name), "_(d-)$") == "99" then + break + end + end + dt.print_error("moving " .. exported_image .. " to " .. myimage_name) result = os.rename(exported_image, myimage_name) dt.print_error("importing file") local myimage = dt.database.import(myimage_name) + groupIfNotMember(image, myimage) + for _,tag in pairs(dt.tags.get_tags(image)) do if not (string.sub(tag.name,1,9) == "darktable") then dt.print_error("attaching tag") From e3f1ff7d702ed248fa37b519187bac8d402a7bb0 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sat, 16 Apr 2016 23:36:58 +0200 Subject: [PATCH 094/865] Strip accents from the filename, because GoogleEarth can't open them --- contrib/kml_export.lua | 76 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index f69efeda..a3bdcd23 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -84,6 +84,76 @@ local function checkIfBinExists(bin) ret = true return ret end + +-- Strip accents from a string +-- Copied from https://forums.coronalabs.com/topic/43048-remove-special-characters-from-string/ +function string.stripAccents( str ) + local tableAccents = {} + tableAccents["à"] = "a" + tableAccents["á"] = "a" + tableAccents["â"] = "a" + tableAccents["ã"] = "a" + tableAccents["ä"] = "a" + tableAccents["ç"] = "c" + tableAccents["è"] = "e" + tableAccents["é"] = "e" + tableAccents["ê"] = "e" + tableAccents["ë"] = "e" + tableAccents["ì"] = "i" + tableAccents["í"] = "i" + tableAccents["î"] = "i" + tableAccents["ï"] = "i" + tableAccents["ñ"] = "n" + tableAccents["ò"] = "o" + tableAccents["ó"] = "o" + tableAccents["ô"] = "o" + tableAccents["õ"] = "o" + tableAccents["ö"] = "o" + tableAccents["ù"] = "u" + tableAccents["ú"] = "u" + tableAccents["û"] = "u" + tableAccents["ü"] = "u" + tableAccents["ý"] = "y" + tableAccents["ÿ"] = "y" + tableAccents["À"] = "A" + tableAccents["Á"] = "A" + tableAccents["Â"] = "A" + tableAccents["Ã"] = "A" + tableAccents["Ä"] = "A" + tableAccents["Ç"] = "C" + tableAccents["È"] = "E" + tableAccents["É"] = "E" + tableAccents["Ê"] = "E" + tableAccents["Ë"] = "E" + tableAccents["Ì"] = "I" + tableAccents["Í"] = "I" + tableAccents["Î"] = "I" + tableAccents["Ï"] = "I" + tableAccents["Ñ"] = "N" + tableAccents["Ò"] = "O" + tableAccents["Ó"] = "O" + tableAccents["Ô"] = "O" + tableAccents["Õ"] = "O" + tableAccents["Ö"] = "O" + tableAccents["Ù"] = "U" + tableAccents["Ú"] = "U" + tableAccents["Û"] = "U" + tableAccents["Ü"] = "U" + tableAccents["Ý"] = "Y" + + local normalizedString = "" + dt.print_error(str) + for strChar in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do + if tableAccents[strChar] ~= nil then + normalizedString = normalizedString..tableAccents[strChar] + else + normalizedString = normalizedString..strChar + end + end + + return normalizedString + +end local function create_kml_file(storage, image_table, extra_data) @@ -143,9 +213,13 @@ local function create_kml_file(storage, image_table, extra_data) -- delete the original image to not get into the kmz file os.remove(exported_image) - + local pattern = "[/]?([^/]+)$" filmName = string.match(image.film.path, pattern) + + -- Strip accents from the filename, because GoogleEarth can't open them + -- https://github.com/darktable-org/lua-scripts/issues/54 + filmName = string.stripAccents(filmName) end exportKMLFilename = filmName..".kml" From 3dcb08cca3f7c920e478a7e70d4a21391b67439c Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 16 Apr 2016 21:10:58 -0400 Subject: [PATCH 095/865] Replaced checkIfFileExists with supertobi's fix and capitalized GIMP in gimp.po where I missed it. --- contrib/de_DE/LC_MESSAGES/gimp.po | 2 +- contrib/gimp.lua | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/de_DE/LC_MESSAGES/gimp.po b/contrib/de_DE/LC_MESSAGES/gimp.po index 46214553..5c901191 100644 --- a/contrib/de_DE/LC_MESSAGES/gimp.po +++ b/contrib/de_DE/LC_MESSAGES/gimp.po @@ -36,4 +36,4 @@ msgstr "Starten von GIMP" #: gimp.lua:243 msgid "Edit with GIMP" -msgstr "Bearbeiten mit Gimp" +msgstr "Bearbeiten mit GIMP" diff --git a/contrib/gimp.lua b/contrib/gimp.lua index 6a825a03..b66f60f8 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -112,15 +112,15 @@ local function checkIfBinExists(bin) return ret end -local function checkIfFileExists(filepath) - local handle = io.popen("ls "..filepath) - local result = handle:read() +-- Thanks Tobias Jakobs for the idea and the correction +function checkIfFileExists(filepath) + local file = io.open(filepath,"r") local ret - handle:close() - if (result) then + if file ~= nil then + io.close(file) dt.print_error("true checkIfFileExists: "..filepath) ret = true - else + else dt.print_error(filepath.." not found") ret = false end From 457731700c7bbaf19bb90a50ad5903dee4a00a84 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 16 Apr 2016 21:44:24 -0400 Subject: [PATCH 096/865] gimp doesn't like filenames with spaces in them, so added sanitize_filename to escape them. Updated gimp.po to reflect the changed line numbers. --- contrib/de_DE/LC_MESSAGES/gimp.po | 8 ++++---- contrib/gimp.lua | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/contrib/de_DE/LC_MESSAGES/gimp.po b/contrib/de_DE/LC_MESSAGES/gimp.po index 5c901191..8b6dcbf7 100644 --- a/contrib/de_DE/LC_MESSAGES/gimp.po +++ b/contrib/de_DE/LC_MESSAGES/gimp.po @@ -21,19 +21,19 @@ msgstr "" "dngettext:2,3\n" "X-Poedit-Basepath: .\n" -#: gimp.lua:179 +#: gimp.lua:189 #, lua-format msgid "Export Image %i/%i" msgstr "Exportiere Bild %i/%i" -#: gimp.lua:184 +#: gimp.lua:194 msgid "GIMP not found" msgstr "GIMP nicht gefunden" -#: gimp.lua:198 +#: gimp.lua:209 msgid "Launching GIMP..." msgstr "Starten von GIMP" -#: gimp.lua:243 +#: gimp.lua:254 msgid "Edit with GIMP" msgstr "Bearbeiten mit GIMP" diff --git a/contrib/gimp.lua b/contrib/gimp.lua index b66f60f8..896fec3d 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -174,6 +174,16 @@ local function groupIfNotMember(img, new_img) end end +local function sanitize_filename(filepath) + local path = get_path(filepath) + local basename = get_basename(filepath) + local filetype = get_filetype(filepath) + + local sanitized = string.gsub(basename, " ", "\\ ") + + return path .. sanitized .. "." .. filetype +end + local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) dt.print(string.format(_("Export Image %i/%i"), number, total)) @@ -192,6 +202,7 @@ local function gimp_edit(storage, image_table, extra_data) --finalize img_list = "" for _,exp_img in pairs(image_table) do + exp_img = sanitize_filename(exp_img) img_list = img_list ..exp_img.. " " end From 204868d73369673a5c7e992aa27926e463d349b3 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sun, 17 Apr 2016 12:33:39 +0200 Subject: [PATCH 097/865] Use a file list instead of * to zip the images kml_export - packs to kmz all files from dt.configuration.tmp_dir #53 https://github.com/darktable-org/lua-scripts/issues/53 --- contrib/kml_export.lua | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index a3bdcd23..eeee8f51 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -142,7 +142,7 @@ function string.stripAccents( str ) tableAccents["Ý"] = "Y" local normalizedString = "" - dt.print_error(str) + for strChar in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do if tableAccents[strChar] ~= nil then normalizedString = normalizedString..tableAccents[strChar] @@ -177,6 +177,7 @@ local function create_kml_file(storage, image_table, extra_data) if not checkIfBinExists("zip") then return end + exportDirectory = dt.configuration.tmp_dir imageFoldername = "" else @@ -208,6 +209,7 @@ local function create_kml_file(storage, image_table, extra_data) -- USE coroutine.yield. It does not block the UI coroutine.yield("RUN_COMMAND", convertToThumbCommand) local concertCommand = "convert -size 438x438 "..exported_image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" + coroutine.yield("RUN_COMMAND", concertCommand) end @@ -320,9 +322,22 @@ local function create_kml_file(storage, image_table, extra_data) if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") -- USE coroutine.yield. It does not block the UI + local createKMZCommand = "zip --test --move --junk-paths " - createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" " - createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" \""..dt.configuration.tmp_dir.."/"..imageFoldername.."\"*" + createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" " -- KMZ filename + createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" " -- KML file + + for image,exported_image in pairs(image_table) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + local filename = string.upper(string.gsub(image.filename,"%.", "_")) + + createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..imageFoldername.."thumb_"..filename..".jpg\" " -- thumbnails + createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..imageFoldername..filename..".jpg\" " -- images + end + end + coroutine.yield("RUN_COMMAND", createKMZCommand) end From 783194e25330cd0fec6e91d82d06f08b0a03e9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rosen?= Date: Sun, 17 Apr 2016 20:46:32 +0200 Subject: [PATCH 098/865] update to newest API change in master --- contrib/autostyle.lua | 3 +-- contrib/cr2hdr.lua | 2 +- contrib/geoJSON_export.lua | 9 ++++----- contrib/geo_uri.lua | 2 +- contrib/gimp.lua | 2 +- contrib/hugin.lua | 6 +++--- contrib/kml_export.lua | 12 +++++------- contrib/slideshowMusic.lua | 4 ++-- contrib/video_mencoder.lua | 6 ++---- official/enfuse.lua | 2 +- official/generate_image_txt.lua | 2 +- official/selection_to_pdf.lua | 4 ++-- 12 files changed, 24 insertions(+), 30 deletions(-) diff --git a/contrib/autostyle.lua b/contrib/autostyle.lua index c8dafafb..9d026ab0 100644 --- a/contrib/autostyle.lua +++ b/contrib/autostyle.lua @@ -118,8 +118,7 @@ end function get_stdout(cmd) -- Open the command, for reading local fd = assert(io.popen(cmd, 'r')) - -- yield to other lua threads until data is ready to be read - coroutine.yield("FILE_READABLE",fd) + dt.control.read(fd) -- slurp the whole file local data = assert(fd:read('*a')) diff --git a/contrib/cr2hdr.lua b/contrib/cr2hdr.lua index d57e9126..9b21e3c0 100644 --- a/contrib/cr2hdr.lua +++ b/contrib/cr2hdr.lua @@ -60,7 +60,7 @@ end local function convert_image(image) if string.sub(image.filename, -3) == "CR2" then local filename = image.path .. "/" .. image.filename - local result = coroutine.yield("RUN_COMMAND", "cr2hdr " .. filename) + local result = dt.control.execute( "cr2hdr " .. filename) local out_filename = string.gsub(filename, ".CR2", ".DNG") local file = io.open(out_filename) if file then diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index c5fc0b7c..74629d6d 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -106,7 +106,7 @@ local function create_geoJSON_file(storage, image_table, extra_data) -- Creates dir if not exsists local imageFoldername = "files/" local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername - coroutine.yield("RUN_COMMAND", mkdirCommand) + dt.control.execute( mkdirCommand) -- Create the thumbnails for image,exported_image in pairs(image_table) do @@ -124,10 +124,9 @@ local function create_geoJSON_file(storage, image_table, extra_data) -- profiles that might be present in the input and aren't needed in the thumbnail. local convertToThumbCommand = "convert -size 96x96 "..exported_image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" - -- USE coroutine.yield. It does not block the UI - coroutine.yield("RUN_COMMAND", convertToThumbCommand) + dt.control.execute( convertToThumbCommand) local concertCommand = "convert -size 438x438 "..exported_image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" - coroutine.yield("RUN_COMMAND", concertCommand) + dt.control.execute( concertCommand) end -- delete the original image to not get into the kmz file @@ -280,7 +279,7 @@ local function create_geoJSON_file(storage, image_table, extra_data) if ( dt.preferences.read("geoJSON_export","OpengeoJSONFile","bool") == true ) then local geoJSONFileOpenCommand geoJSONFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportgeoJSONFilename.."\"" - coroutine.yield("RUN_COMMAND", geoJSONFileOpenCommand) + dt.control.execute( geoJSONFileOpenCommand) end diff --git a/contrib/geo_uri.lua b/contrib/geo_uri.lua index 04ad553c..d86018cb 100644 --- a/contrib/geo_uri.lua +++ b/contrib/geo_uri.lua @@ -77,7 +77,7 @@ local function openLocationInGnomeMaps() startCommand = "gnome-maps \"geo:" .. lat1 .. "," .. lon1 .."\"" dt.print_error(startCommand) - if coroutine.yield("RUN_COMMAND", startCommand) then + if dt.control.execute( startCommand) then dt.print(_("Command failed ...")) end diff --git a/contrib/gimp.lua b/contrib/gimp.lua index 896fec3d..a15ca6b6 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -213,7 +213,7 @@ local function gimp_edit(storage, image_table, extra_data) --finalize dt.print_error(gimpStartCommand) - coroutine.yield("RUN_COMMAND", gimpStartCommand) + dt.control.execute( gimpStartCommand) -- for each of the image, exported image pairs -- move the exported image into the directory with the original diff --git a/contrib/hugin.lua b/contrib/hugin.lua index d6f66220..8d806295 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -100,11 +100,11 @@ local function create_panorama(storage, image_table, extra_data) --finalize if (hugin_executor) then huginStartCommand = "pto_gen "..img_list.." -o "..dt.configuration.tmp_dir.."/project.pto" dt.print(_("Creating pto file")) - coroutine.yield("RUN_COMMAND", huginStartCommand) + dt.control.execute( huginStartCommand) dt.print(_("Running Assistent")) huginStartCommand = "hugin_executor --assistant "..dt.configuration.tmp_dir.."/project.pto" - coroutine.yield("RUN_COMMAND", huginStartCommand) + dt.control.execute( huginStartCommand) huginStartCommand = "hugin "..dt.configuration.tmp_dir.."/project.pto" else @@ -113,7 +113,7 @@ local function create_panorama(storage, image_table, extra_data) --finalize dt.print_error(huginStartCommand) - if coroutine.yield("RUN_COMMAND", huginStartCommand) + if dt.control.execute( huginStartCommand) then dt.print(_("Command hugin failed ...")) end diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index eeee8f51..79602873 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -186,7 +186,7 @@ local function create_kml_file(storage, image_table, extra_data) -- Creates dir if not exsists imageFoldername = "files/" local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername - coroutine.yield("RUN_COMMAND", mkdirCommand) + dt.control.execute( mkdirCommand) end @@ -206,11 +206,10 @@ local function create_kml_file(storage, image_table, extra_data) -- profiles that might be present in the input and aren't needed in the thumbnail. local convertToThumbCommand = "convert -size 96x96 "..exported_image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" - -- USE coroutine.yield. It does not block the UI - coroutine.yield("RUN_COMMAND", convertToThumbCommand) + dt.control.execute( convertToThumbCommand) local concertCommand = "convert -size 438x438 "..exported_image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" - coroutine.yield("RUN_COMMAND", concertCommand) + dt.control.execute( concertCommand) end -- delete the original image to not get into the kmz file @@ -321,7 +320,6 @@ local function create_kml_file(storage, image_table, extra_data) -- Compress the files to create a KMZ file if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") - -- USE coroutine.yield. It does not block the UI local createKMZCommand = "zip --test --move --junk-paths " createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" " -- KMZ filename @@ -338,7 +336,7 @@ local function create_kml_file(storage, image_table, extra_data) end end - coroutine.yield("RUN_COMMAND", createKMZCommand) + dt.control.execute( createKMZCommand) end -- Open the file with the standard programm @@ -350,7 +348,7 @@ local function create_kml_file(storage, image_table, extra_data) else kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMLFilename.."\"" end - coroutine.yield("RUN_COMMAND", kmlFileOpenCommand) + dt.control.execute( kmlFileOpenCommand) end diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index 776c71e2..fdece6ac 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -65,12 +65,12 @@ local function playSlideshowMusic(_, old_view, new_view) playCommand = 'rhythmbox-client --play-uri="'..filename..'"' --dt.print_error(playCommand) - coroutine.yield("RUN_COMMAND", playCommand) + dt.control.execute( playCommand) else if (old_view and old_view.id == "slideshow") then stopCommand = "rhythmbox-client --pause" --dt.print_error(stopCommand) - coroutine.yield("RUN_COMMAND", stopCommand) + dt.control.execute( stopCommand) end end end diff --git a/contrib/video_mencoder.lua b/contrib/video_mencoder.lua index 81987805..e65adaa8 100644 --- a/contrib/video_mencoder.lua +++ b/contrib/video_mencoder.lua @@ -92,15 +92,13 @@ local function create_video_mencoder(storage, image_table, extra_data) end dt.print_error("this is the command: "..command) - -- USE coroutine.yield. It does not block the UI - coroutine.yield("RUN_COMMAND", command) + dt.control.execute( command) dt.print("Video created in "..exportDirectory) if ( dt.preferences.read("video_mencoder","OpenVideo","bool") == true ) then - -- USE coroutine.yield. It does not block the UI local playVideoCommand = "xdg-open "..exportDirectory.."/"..exportFilename - coroutine.yield("RUN_COMMAND", playVideoCommand) + dt.control.execute( playVideoCommand) end end diff --git a/official/enfuse.lua b/official/enfuse.lua index 3a0ac593..829a9696 100644 --- a/official/enfuse.lua +++ b/official/enfuse.lua @@ -147,7 +147,7 @@ dt.register_lib( local output_image = target_dir.."/enfuse.tiff" local command = "enfuse --depth "..depth.value.." --exposure-mu "..ugly_decimal_point_hack .." -o \""..output_image.."\" \"@"..response_file.."\"" - if coroutine.yield("RUN_COMMAND", command) > 0 then + if dt.control.execute( command) > 0 then dt.print("enfuse failed, see terminal output for details") os.remove(response_file) return diff --git a/official/generate_image_txt.lua b/official/generate_image_txt.lua index 416a8cef..b650de1d 100644 --- a/official/generate_image_txt.lua +++ b/official/generate_image_txt.lua @@ -97,7 +97,7 @@ dt.register_event("mouse-over-image-changed", function(event, img) local command = command_setting:gsub("%$%(FILE_NAME%)", '"'..img_filename..'"')..' > "'..txt_filename..'"' -- finally, run it - coroutine.yield("RUN_COMMAND", command) + dt.control.execute( command) end ) diff --git a/official/selection_to_pdf.lua b/official/selection_to_pdf.lua index 8444e8e8..f6bf8902 100644 --- a/official/selection_to_pdf.lua +++ b/official/selection_to_pdf.lua @@ -128,7 +128,7 @@ dt.register_storage("export_pdf","Export thumbnails to pdf", local dir=string.gsub(filename, "(.*/)(.*)", "%1") local locfile=string.gsub(filename, "(.*/)(.*)", "%2") local command = "pdflatex -halt-on-error -output-directory "..dir.." "..locfile - local result = coroutine.yield("RUN_COMMAND",command) + local result = dt.control.execute(command) if result ~= 0 then dt.print("Problem running pdflatex") -- this one is probably usefull to the user error("Problem running "..command) @@ -138,7 +138,7 @@ dt.register_storage("export_pdf","Export thumbnails to pdf", local pdffile=string.gsub(filename, ".tex", ".pdf") command = dt.preferences.read("selection_to_pdf","Open with","string") command = command.." "..pdffile - local result = coroutine.yield("RUN_COMMAND",command) + local result = dt.control.execute(command) if result ~= 0 then dt.print("Problem running pdf viewer") -- this one is probably usefull to the user error("Problem running "..command) From 200ef9a45ea725ab9c7197adb42ac6aa705bb88f Mon Sep 17 00:00:00 2001 From: chrik5 Date: Thu, 21 Apr 2016 15:54:59 +0200 Subject: [PATCH 099/865] Tagging added new function replace and a modul --- contrib/copy_attach_detach_tags.lua | 86 +++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 12 deletions(-) diff --git a/contrib/copy_attach_detach_tags.lua b/contrib/copy_attach_detach_tags.lua index 50817329..ee820d8d 100644 --- a/contrib/copy_attach_detach_tags.lua +++ b/contrib/copy_attach_detach_tags.lua @@ -1,6 +1,6 @@ --[[ This file is part of darktable, - copyright 2014-2015 by Christian Kanzian. + copyright 2014-2016 by Christian Kanzian. 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 @@ -17,8 +17,8 @@ ]] --[[ - (MULTI-)COPY ATTACH DETACH TAG - A simple script that will create three shortcuts to copy, attach and detach image tags. + (MULTI-)COPY ATTACH DETACH REPLACE TAGS + This script that will create four shortcuts and add a modul in lighttable mode to copy, paste, replace and remove tags from images. INSTALATION * copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory @@ -27,17 +27,22 @@ INSTALATION USAGE * set the shortcuts for copy, attach and detach in the preferences dialog * copy will create a list of tags from all selected images - * attaches copied tags to selected images, whereby + * paste copied tags to selected images, whereby darktable internal tags starting with 'darktable|' will not be touched - * detach removes all expect darktable internal tags from selected images + * removes all expect darktable internal tags from selected images + * replaces all tags expect darktable internals ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,0},{3,0,0}) +dt.configuration.check_version(...,{3,0,0},{4,0,0}) local image_tags = {} + +local taglist_label = dt.new_widget("label"){selectable = true, ellipsize = "middle", halign = "start"} +taglist_label.label = "" + local function mcopy_tags() local sel_images = dt.gui.action_images local tag_list_tmp = {} @@ -66,7 +71,21 @@ local function mcopy_tags() end dt.print("Image tags copied ...") - return(image_tags) + + --create UI tag list + local taglist = "" + + for _,tag in ipairs(image_tags) do + if taglist == "" then + taglist = tostring(tag) + else + taglist = taglist.."\n"..tostring(tag) + end + end + + taglist_label.label = taglist + + return(image_tags) end -- attach copied tags to all selected images @@ -99,9 +118,6 @@ local function attach_tags() dt.print("Tags attached ...") end - - - local function detach_tags() local sel_images = dt.gui.action_images @@ -118,6 +134,48 @@ local function detach_tags() dt.print("Tags removed from image(s).") end +local function replace_tags() + detach_tags() + attach_tags() + dt.print("Tags replaced") +end + +-- create modul Tagging addons +taglist_label.reset_callback = mcopy_tags + +dt.register_lib("tagging_addon","Tagging addon",true,false,{ + [dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER",500} + }, + dt.new_widget("box") + { + orientation = "vertical", + dt.new_widget("button") + { + label = "multi copy", + clicked_callback = mcopy_tags + }, + dt.new_widget("button") + { + label = "paste tags", + clicked_callback = attach_tags + }, + dt.new_widget("button") + { + label = "replace tags", + clicked_callback = replace_tags + }, + dt.new_widget("button") + { + label = "remove all tags", + clicked_callback = detach_tags + }, + taglist_label + }, + nil, + nil + ) + + -- shortcut for copy dt.register_event("shortcut", mcopy_tags, @@ -126,13 +184,17 @@ dt.register_event("shortcut", -- shortcut for attach dt.register_event("shortcut", attach_tags, - "attach tags to selected image(s)") + "paste tags to selected image(s)") -- shortcut for detaching tags dt.register_event("shortcut", detach_tags, - "detach tags to selected image(s)") + "remove tags to selected image(s)") + -- shortcut for replace tags +dt.register_event("shortcut", + replace_tags, + "replace tags from selected image(s)") -- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua -- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; From e22df23bc9122718b41ba476b6aff85dd1da7f4d Mon Sep 17 00:00:00 2001 From: chrik5 Date: Thu, 21 Apr 2016 17:08:44 +0200 Subject: [PATCH 100/865] Tagging add label before clipboard list and make small enhancements --- contrib/copy_attach_detach_tags.lua | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/contrib/copy_attach_detach_tags.lua b/contrib/copy_attach_detach_tags.lua index ee820d8d..9a89a2ea 100644 --- a/contrib/copy_attach_detach_tags.lua +++ b/contrib/copy_attach_detach_tags.lua @@ -18,7 +18,8 @@ --[[ (MULTI-)COPY ATTACH DETACH REPLACE TAGS - This script that will create four shortcuts and add a modul in lighttable mode to copy, paste, replace and remove tags from images. + This script that will create four shortcuts and add a modul in lighttable mode to copy, + paste, replace and remove tags from images. INSTALATION * copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory @@ -151,7 +152,7 @@ dt.register_lib("tagging_addon","Tagging addon",true,false,{ orientation = "vertical", dt.new_widget("button") { - label = "multi copy", + label = "multi copy tags", clicked_callback = mcopy_tags }, dt.new_widget("button") @@ -169,6 +170,14 @@ dt.register_lib("tagging_addon","Tagging addon",true,false,{ label = "remove all tags", clicked_callback = detach_tags }, + dt.new_widget("label") + { + label = "tag clipboard", + selectable = false, + ellipsize = "middle", + halign = "start" + }, + dt.new_widget("separator"){}, taglist_label }, nil, @@ -189,7 +198,7 @@ dt.register_event("shortcut", -- shortcut for detaching tags dt.register_event("shortcut", detach_tags, - "remove tags to selected image(s)") + "remove tags from selected image(s)") -- shortcut for replace tags dt.register_event("shortcut", From d2762fae735b426bfa40a37bf35cc40bfec56b40 Mon Sep 17 00:00:00 2001 From: elman Date: Wed, 27 Apr 2016 19:25:03 +0200 Subject: [PATCH 101/865] Fixed issue with exporting RAW images --- contrib/kml_export.lua | 66 +++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 79602873..1589a4ac 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -30,6 +30,7 @@ This script is only tested with Linux USAGE * require this script from your main Lua file +* when choosing file format, pick JPEG or PNG as Google Earth doesn't support other formats ]] @@ -155,6 +156,19 @@ function string.stripAccents( str ) end +-- Escape XML characters +-- https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents +function string.escapeXmlCharacters( str ) + + str = string.gsub(str,"&", "&") + str = string.gsub(str,"\"", """) + str = string.gsub(str,"'", "'") + str = string.gsub(str,"<", "<") + str = string.gsub(str,">", ">") + + return str +end + local function create_kml_file(storage, image_table, extra_data) if not checkIfBinExists("mkdir") then @@ -186,7 +200,7 @@ local function create_kml_file(storage, image_table, extra_data) -- Creates dir if not exsists imageFoldername = "files/" local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername - dt.control.execute( mkdirCommand) + coroutine.yield("RUN_COMMAND", mkdirCommand) end @@ -196,8 +210,8 @@ local function create_kml_file(storage, image_table, extra_data) (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then local path, filename, filetype = string.match(exported_image, "(.-)([^\\/]-%.?([^%.\\/]*))$") - filename = string.upper(string.gsub(filename,"%.", "_")) - + filename = string.upper(string.gsub(filename,"%.%w*", "")) + -- convert -size 92x92 filename.jpg -resize 92x92 +profile "*" thumbnail.jpg -- In this example, '-size 120x120' gives a hint to the JPEG decoder that the image is going to be downscaled to -- 120x120, allowing it to run faster by avoiding returning full-resolution images to GraphicsMagick for the @@ -206,21 +220,16 @@ local function create_kml_file(storage, image_table, extra_data) -- profiles that might be present in the input and aren't needed in the thumbnail. local convertToThumbCommand = "convert -size 96x96 "..exported_image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" - dt.control.execute( convertToThumbCommand) - local concertCommand = "convert -size 438x438 "..exported_image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" - - dt.control.execute( concertCommand) + -- USE coroutine.yield. It does not block the UI + coroutine.yield("RUN_COMMAND", convertToThumbCommand) end - -- delete the original image to not get into the kmz file - os.remove(exported_image) - local pattern = "[/]?([^/]+)$" filmName = string.match(image.film.path, pattern) - - -- Strip accents from the filename, because GoogleEarth can't open them - -- https://github.com/darktable-org/lua-scripts/issues/54 - filmName = string.stripAccents(filmName) + + -- Strip accents from the filename, because GoogleEarth can't open them + -- https://github.com/darktable-org/lua-scripts/issues/54 + filmName = string.stripAccents(filmName) end exportKMLFilename = filmName..".kml" @@ -236,20 +245,24 @@ local function create_kml_file(storage, image_table, extra_data) kml_file = kml_file.." Exported from darktable\n" for image,exported_image in pairs(image_table) do - filename = string.upper(string.gsub(image.filename,"%.", "_")) + filename = string.upper(string.gsub(image.filename,"%.%w*", "")) + extension = string.match(exported_image,"%.%w*$") if ((image.longitude and image.latitude) and (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then kml_file = kml_file.." \n" - if (image.title and image.title ~= "") then - kml_file = kml_file.." "..image.title.."\n" + + local image_title, image_description + if (image.title and image.title ~= "") then + image_title = string.escapeXmlCharacters(image.title) else - kml_file = kml_file.." "..image.filename.."\n" + image_title = image.filename end - - kml_file = kml_file.." "..image.description.."\n" - + image_description = string.escapeXmlCharacters(image.description) + + kml_file = kml_file.." "..image_title.."\n" + kml_file = kml_file.." "..image_description.."\n" kml_file = kml_file.." \n" kml_file = kml_file.." \n" kml_file = kml_file.." \n" - + for image,exported_image in spairs(image_table, function(t,a,b) return t[b] < t[a] end) do - if ((image.longitude and image.latitude) and + if ((image.longitude and image.latitude) and (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then local altitude = 0; @@ -349,7 +349,7 @@ local function create_kml_file(storage, image_table, extra_data) createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" " -- KML file for image,exported_image in pairs(image_table) do - if ((image.longitude and image.latitude) and + if ((image.longitude and image.latitude) and (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then local filename = string.upper(string.gsub(image.filename,"%.%w*", "")) @@ -362,7 +362,7 @@ local function create_kml_file(storage, image_table, extra_data) dt.control.execute(createKMZCommand) end --- Open the file with the standard programm +-- Open the file with the standard programm if ( dt.preferences.read("kml_export","OpenKmlFile","bool") == true ) then local kmlFileOpenCommand @@ -371,7 +371,7 @@ local function create_kml_file(storage, image_table, extra_data) else kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMLFilename.."\"" end - dt.control.execute(kmlFileOpenCommand) + dt.control.execute(kmlFileOpenCommand) end @@ -406,7 +406,7 @@ dt.preferences.register("kml_export", "bool", _("KML export: Create KMZ file"), _("Compress all imeges to one KMZ file"), - true ) + true ) -- Register dt.register_storage("kml_export", _("KML/KMZ Export"), nil, create_kml_file) diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index bf7c4b33..fff276c6 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -23,7 +23,7 @@ You need rhythmbox-client installed to use this script USAGE * require this script from your main lua file ]] - + local dt = require "darktable" require "official/yield" @@ -65,14 +65,14 @@ local function playSlideshowMusic(_, old_view, new_view) if (new_view.id == "slideshow") then playCommand = 'rhythmbox-client --play-uri="'..filename..'"' - + --dt.print_error(playCommand) - dt.control.execute( playCommand) + dt.control.execute( playCommand) else if (old_view and old_view.id == "slideshow") then stopCommand = "rhythmbox-client --pause" --dt.print_error(stopCommand) - dt.control.execute( stopCommand) + dt.control.execute( stopCommand) end end end @@ -80,7 +80,7 @@ end -- Preferences dt.preferences.register("slideshowMusic", "SlideshowMusic", "file", _("Slideshow background music file"), "", "") -dt.preferences.register("slideshowMusic", +dt.preferences.register("slideshowMusic", "PlaySlideshowMusic", "bool", _("Play slideshow background music"), From d271f6d46da8a19ccb1474211717b90a375fe707 Mon Sep 17 00:00:00 2001 From: Pascal Obry Date: Mon, 10 Apr 2017 16:59:46 +0200 Subject: [PATCH 184/865] Add french translation for pdf_slideshow plugin. --- locale/fr_FR/LC_MESSAGES/pdf_slideshow.po | 70 +++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 locale/fr_FR/LC_MESSAGES/pdf_slideshow.po diff --git a/locale/fr_FR/LC_MESSAGES/pdf_slideshow.po b/locale/fr_FR/LC_MESSAGES/pdf_slideshow.po new file mode 100644 index 00000000..48c1e79c --- /dev/null +++ b/locale/fr_FR/LC_MESSAGES/pdf_slideshow.po @@ -0,0 +1,70 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-04-10 09:30+0200\n" +"PO-Revision-Date: 2017-04-10 09:48+0200\n" +"Language: fr_FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: Pascal Obry \n" +"Language-Team: \n" +"X-Generator: Poedit 1.8.11\n" + +#: pdf_slideshow.lua:55 +msgid "pdflatex not found" +msgstr "pdflatex non trouvé" + +#: pdf_slideshow.lua:63 +msgid "a pdf viewer" +msgstr "lecteur pdf" + +#: pdf_slideshow.lua:64 +msgid "can be an absolute pathname or the tool may be in the PATH" +msgstr "peut être un chemin absolu où l'outil peut être dans le chemin par défaut" + +#: pdf_slideshow.lua:68 pdf_slideshow.lua:95 +msgid "slideshow title" +msgstr "titre du diaporama" + +#: pdf_slideshow.lua:72 +msgid "transition delay (s)" +msgstr "temporisation (s) entre diapositives" + +#: pdf_slideshow.lua:83 +msgid "include image title" +msgstr "inclus le titre de l'image" + +#: pdf_slideshow.lua:85 +msgid "whether to include the image title (if defined) into the slide" +msgstr "indique si le titre de l'image (si défini) doit être inclus dans la diapositive" + +#: pdf_slideshow.lua:89 +msgid "include image author" +msgstr "inclus l'auteur de l'image" + +#: pdf_slideshow.lua:91 +msgid "whether to include the image author (if defined) into the slide" +msgstr "indique si l'auteur de l'image (si défini) doit être inclus dans la diapositive" + +#: pdf_slideshow.lua:167 +msgid "pdf slideshow" +msgstr "diaporama pdf" + +#: pdf_slideshow.lua:220 +msgid "problem running pdflatex" +msgstr "impossible d'exécuter pdflatex" + +#: pdf_slideshow.lua:221 pdf_slideshow.lua:231 +msgid "problem running " +msgstr "impossible d'exécuter " + +#: pdf_slideshow.lua:230 +msgid "problem running pdf viewer" +msgstr "impossible d'exécuter le lecteur pdf" From c7ac974ab92a90671e5ab17884a0a640f812c6c8 Mon Sep 17 00:00:00 2001 From: Pascal Obry Date: Sat, 15 Apr 2017 15:35:09 +0200 Subject: [PATCH 185/865] Ensure that a dot is used for decimal numbers. This unbreak the slide show for acrobat reader. --- contrib/pdf_slideshow.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/pdf_slideshow.lua b/contrib/pdf_slideshow.lua index 07c27570..d5a71d40 100644 --- a/contrib/pdf_slideshow.lua +++ b/contrib/pdf_slideshow.lua @@ -183,7 +183,7 @@ dt.register_storage("pdf_slideshow",_("pdf slideshow"), \color{white} \geometry{a4paper,landscape,left=2mm,right=2mm, top=2mm, bottom=2mm} \mode - \transduration{]]..delay_widget.value..[[} + \transduration{]]..string.gsub(delay_widget.value, ",", ".")..[[} \setbeamertemplate{footline}{} \setbeamertemplate{headline}{} \setbeamertemplate{frametitle}{} From 39ae92a0fa805f82d0053e6fcf18690b785ed5e1 Mon Sep 17 00:00:00 2001 From: supertobi Date: Tue, 18 Apr 2017 22:31:49 +0200 Subject: [PATCH 186/865] Update geoToolbox.lua fix open with gnome-maps --- contrib/geoToolbox.lua | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/contrib/geoToolbox.lua b/contrib/geoToolbox.lua index e6e02fb5..4b484319 100644 --- a/contrib/geoToolbox.lua +++ b/contrib/geoToolbox.lua @@ -27,6 +27,7 @@ require "geoToolbox" local dt = require "darktable" local df = require "lib/dtutils.file" +require "official/yield" local gettext = dt.gettext dt.configuration.check_version(...,{3,0,0},{4,0,0}) @@ -326,20 +327,17 @@ local function open_location_in_gnome_maps() if ((image.longitude and image.latitude) and (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then - lat1 = image.latitude; - lon1 = image.longitude; + lat1 = string.gsub(image.latitude, ",", "."); + lon1 = string.gsub(image.longitude, ",", "."); break end + end - local startCommand - startCommand = "gnome-maps \"geo:" .. lat1 .. "," .. lon1 .."\"" - dt.print_error(startCommand) - - if coroutine.yield("RUN_COMMAND", startCommand) then - dt.print(_("Command failed ...")) - end + local startCommand + startCommand = "gnome-maps \"geo:" .. lat1 .. "," .. lon1 .."\"" + dt.print_error(startCommand) - end + dt.control.execute(startCommand) end From 91758b61c3bf988578df38f6186084cf9404d10b Mon Sep 17 00:00:00 2001 From: khampf Date: Fri, 21 Apr 2017 13:51:40 +0300 Subject: [PATCH 187/865] ISO 19794-5/ICAO 9303 clipping guide as contrib/passport_guide.lua --- contrib/passport_guide.lua | 73 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 contrib/passport_guide.lua diff --git a/contrib/passport_guide.lua b/contrib/passport_guide.lua new file mode 100644 index 00000000..0e894f27 --- /dev/null +++ b/contrib/passport_guide.lua @@ -0,0 +1,73 @@ +--[[ +PASSPORT CROPPING GUIDE +guides for cropping passport photos based on documents from the Finnish police +(https://www.poliisi.fi/instancedata/prime_product_julkaisu/intermin/embeds/poliisiwwwstructure/38462_Passikuvaohje_EN.pdf) describing passport photo dimensions of 47x36 mm and 500x653 px for digital biometric data stored in passports. They use ISO 19794-5 standard based on ICAO 9303 regulations which should also be compliant for all of Europe. + +AUTHOR +Kåre Hampf (k.hampf@gmail.com) + +INSTALLATION +* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory +* add the following line in the file $CONFIGDIR/luarc + require "passport_guide" +* (optional) add the line: + "plugins/darkroom/clipping/extra_aspect_ratios/passport 36x47mm=47:36" + to $CONFIGDIR/darktablerc + +USAGE +* when using the cropping tool, select "passport" as guide and if you added the line in yout rc + select "passport 36x47mm" as aspect + +LICENSE +GPLv2 + +]] + +local dt = require "darktable" +dt.configuration.check_version(...,{2,0,0},{3,0,0},{4,0,0}) + +dt.guides.register_guide("passport", +-- draw +function(cr, x, y, w, h, zoom_scale) + local _w, _h + + -- get the max 36x47 rectangle + local aspect_ratio = 47 / 36 + if w * aspect_ratio > h then + _w = h / aspect_ratio + _h = h + else + _w = w + _h = w * aspect_ratio + end + + cr:save() + + cr:translate(x + (w - _w) / 2, y + (h - _h) / 2) + cr:scale(_w / 36, _h / 47) + + -- the outer rectangle + cr:rectangle( 0, 0, 36, 47) + + -- vertical bars + cr:draw_line(16.5, 8, 16.5, 36) + cr:draw_line(19.5, 8, 19.5, 36) + + -- long horisontal bars + cr:draw_line(6, 4, 30, 4) + cr:draw_line(6, 40, 30, 40) + + -- short horisontal bars + cr:draw_line(9, 6, 27, 6) + cr:draw_line(9, 38, 27, 38) + + cr:restore() +end, +-- gui +function() + return dt.new_widget("label"){label = "ISO 19794-5/ICAO 9309 passport", halign = "start"} +end +) + +-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; hl Lua; +-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua From 50668817dbf915d46fc66e6d23ae2ba032112692 Mon Sep 17 00:00:00 2001 From: khampf Date: Fri, 21 Apr 2017 21:43:02 +0300 Subject: [PATCH 188/865] added API 5 to version check --- contrib/passport_guide.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/passport_guide.lua b/contrib/passport_guide.lua index 0e894f27..ea9b04f4 100644 --- a/contrib/passport_guide.lua +++ b/contrib/passport_guide.lua @@ -24,7 +24,7 @@ GPLv2 ]] local dt = require "darktable" -dt.configuration.check_version(...,{2,0,0},{3,0,0},{4,0,0}) +dt.configuration.check_version(...,{2,0,0},{3,0,0},{4,0,0},{5,0,0}) dt.guides.register_guide("passport", -- draw From c8d5e9d9d2b9537865dc5c43f41033a4e793e7be Mon Sep 17 00:00:00 2001 From: khampf Date: Sat, 22 Apr 2017 22:06:55 +0300 Subject: [PATCH 189/865] Longer version of GPL text --- contrib/passport_guide.lua | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/contrib/passport_guide.lua b/contrib/passport_guide.lua index ea9b04f4..ef68b13b 100644 --- a/contrib/passport_guide.lua +++ b/contrib/passport_guide.lua @@ -1,3 +1,22 @@ +--[[ + Passport cropping guide for darktable + + copyright (c) 2017 Kåre Hampf + + 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 . +]] + --[[ PASSPORT CROPPING GUIDE guides for cropping passport photos based on documents from the Finnish police @@ -17,10 +36,6 @@ INSTALLATION USAGE * when using the cropping tool, select "passport" as guide and if you added the line in yout rc select "passport 36x47mm" as aspect - -LICENSE -GPLv2 - ]] local dt = require "darktable" From 693c9858c2f0cd9d7cd02b6b33621c1867a2efac Mon Sep 17 00:00:00 2001 From: khampf Date: Sat, 22 Apr 2017 23:24:43 +0300 Subject: [PATCH 190/865] variables renamed for clarity (local functions tested without success) --- contrib/passport_guide.lua | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/contrib/passport_guide.lua b/contrib/passport_guide.lua index ef68b13b..6f00b2b3 100644 --- a/contrib/passport_guide.lua +++ b/contrib/passport_guide.lua @@ -43,40 +43,40 @@ dt.configuration.check_version(...,{2,0,0},{3,0,0},{4,0,0},{5,0,0}) dt.guides.register_guide("passport", -- draw -function(cr, x, y, w, h, zoom_scale) - local _w, _h +function(cairo, x, y, width, height, zoom_scale) + local _width, _height -- get the max 36x47 rectangle local aspect_ratio = 47 / 36 - if w * aspect_ratio > h then - _w = h / aspect_ratio - _h = h + if width * aspect_ratio > height then + _width = height / aspect_ratio + _height = height else - _w = w - _h = w * aspect_ratio + _width = width + _height = width * aspect_ratio end - cr:save() + cairo:save() - cr:translate(x + (w - _w) / 2, y + (h - _h) / 2) - cr:scale(_w / 36, _h / 47) + cairo:translate(x + (width - _width) / 2, y + (height - _height) / 2) + cairo:scale(_width / 36, _height / 47) -- the outer rectangle - cr:rectangle( 0, 0, 36, 47) + cairo:rectangle( 0, 0, 36, 47) -- vertical bars - cr:draw_line(16.5, 8, 16.5, 36) - cr:draw_line(19.5, 8, 19.5, 36) + cairo:draw_line(16.5, 8, 16.5, 36) + cairo:draw_line(19.5, 8, 19.5, 36) -- long horisontal bars - cr:draw_line(6, 4, 30, 4) - cr:draw_line(6, 40, 30, 40) + cairo:draw_line(6, 4, 30, 4) + cairo:draw_line(6, 40, 30, 40) -- short horisontal bars - cr:draw_line(9, 6, 27, 6) - cr:draw_line(9, 38, 27, 38) + cairo:draw_line(9, 6, 27, 6) + cairo:draw_line(9, 38, 27, 38) - cr:restore() + cairo:restore() end, -- gui function() From f52292e8d11f428c59e049d4cfd136e9f30478d7 Mon Sep 17 00:00:00 2001 From: khampf Date: Sat, 22 Apr 2017 23:34:55 +0300 Subject: [PATCH 191/865] Translatable by using gettext --- contrib/passport_guide.lua | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/contrib/passport_guide.lua b/contrib/passport_guide.lua index 6f00b2b3..48ae64f6 100644 --- a/contrib/passport_guide.lua +++ b/contrib/passport_guide.lua @@ -22,9 +22,6 @@ PASSPORT CROPPING GUIDE guides for cropping passport photos based on documents from the Finnish police (https://www.poliisi.fi/instancedata/prime_product_julkaisu/intermin/embeds/poliisiwwwstructure/38462_Passikuvaohje_EN.pdf) describing passport photo dimensions of 47x36 mm and 500x653 px for digital biometric data stored in passports. They use ISO 19794-5 standard based on ICAO 9303 regulations which should also be compliant for all of Europe. -AUTHOR -Kåre Hampf (k.hampf@gmail.com) - INSTALLATION * copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory * add the following line in the file $CONFIGDIR/luarc @@ -39,8 +36,17 @@ USAGE ]] local dt = require "darktable" +local gettext = dt.gettext + dt.configuration.check_version(...,{2,0,0},{3,0,0},{4,0,0},{5,0,0}) +-- Tell gettext where to find the .mo file translating messages for a particular domain +gettext.bindtextdomain("passport_guide",dt.configuration.config_dir.."/lua/locale/") + +local function _(msgid) + return gettext.dgettext("passport_guide", msgid) +end + dt.guides.register_guide("passport", -- draw function(cairo, x, y, width, height, zoom_scale) @@ -80,7 +86,7 @@ function(cairo, x, y, width, height, zoom_scale) end, -- gui function() - return dt.new_widget("label"){label = "ISO 19794-5/ICAO 9309 passport", halign = "start"} + return dt.new_widget("label"){label = _("ISO 19794-5/ICAO 9309 passport"), halign = "start"} end ) From ef46cd9b455600acf7e993bad0502a8097d5bf6d Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 27 Apr 2017 20:20:29 +0200 Subject: [PATCH 192/865] Update geoToolbox.lua reverse geocodeing start --- contrib/geoToolbox.lua | 78 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/contrib/geoToolbox.lua b/contrib/geoToolbox.lua index 4b484319..3bcae3b1 100644 --- a/contrib/geoToolbox.lua +++ b/contrib/geoToolbox.lua @@ -341,6 +341,68 @@ local function open_location_in_gnome_maps() end +-- Trim Funktion from: http://lua-users.org/wiki/StringTrim +local function trim12(s) + local from = s:match"^%s*()" + return from > #s and "" or s:match(".*%S", from) +end + +local function reverse_geocode() + + if not df.check_if_bin_exists("curl") then + dt.print_error(_("curl not found")) + return + end + + if not df.check_if_bin_exists("jq") then + dt.print_error(_("jq not found")) + return + end + + local sel_images = dt.gui.selection() --action_images + + local lat1 = 0; + local lon1 = 0; + local i = 0; + + -- Use the first image with geo information + for _,image in ipairs(sel_images) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + lat1 = string.gsub(image.latitude, ",", "."); + lon1 = string.gsub(image.longitude, ",", "."); + break + end + end + + local startCommand + + local tokan = dt.preferences.read("geoToolbox","mapBoxKey","string") + local types = "country"; + local types = "region"; + local types = "place"; + local types = "poi"; + + -- MapBox documentation + -- https://www.mapbox.com/api-documentation/#retrieve-places-near-a-location + -- curl -s, --silent Silent mode (don't output anything) + -- jq could be replaced with a Lua JSON parser + startCommand = string.format("curl --silent \"https://api.mapbox.com/geocoding/v5/mapbox.places/%s,%s.json?types=%s&access_token=%s\" | jq '.features | .[0] | '.text''", lon1, lat1, types, tokan) + + local handle = io.popen(startCommand) + local result = trim12(handle:read("*a")) + handle:close() + + -- Errorhandling would be nice + --dt.print_error("startCommand: "..startCommand) + --dt.print_error("result: '"..result.."'") + + if (result ~= "null") then + dt.print(string.sub(result, 2, string.len(result)-2)) + end + +end -- I used code from here: -- http://stackoverflow.com/questions/27928/how-do-i-calculate-distance-between-two-latitude-longitude-points @@ -433,6 +495,7 @@ local altitude_file_chooser_button = dt.new_widget("file_chooser_button") value = "", -- The currently selected file is_directory = true -- True if the file chooser button only allows directories to be selecte } + local altitude_filename = dt.new_widget("entry") { text = "altitude.csv", @@ -513,6 +576,7 @@ local separator = dt.new_widget("separator"){} local separator2 = dt.new_widget("separator"){} local separator3 = dt.new_widget("separator"){} local separator4 = dt.new_widget("separator"){} +local separator5 = dt.new_widget("separator"){} dt.register_lib( "geoToolbox", -- Module name @@ -582,6 +646,13 @@ dt.register_lib( clicked_callback = open_location_in_gnome_maps }, separator4,-------------------------------------------------------- + dt.new_widget("button") + { + label = _("reverse geocode"), + tooltip = _("This just shows the name of the location, but doesn't add it as tag"), + clicked_callback = reverse_geocode + }, + separator5,-------------------------------------------------------- dt.new_widget("label"){label = _("altitude CSV export")}, altitude_file_chooser_button, altitude_filename, @@ -597,6 +668,13 @@ dt.register_lib( nil -- view_leave ) +-- Preferences +dt.preferences.register("geoToolbox", + "mapBoxKey", + "string", + _("geoToolbox export: MapBox Key"), + _("https://www.mapbox.com/studio/account/tokens"), + '' ) -- Register dt.register_event("shortcut", print_calc_distance, _("Calculate the distance from latitude and longitude in km")) From 01fc339da531cb120741acea5ff5d3ec3de16778 Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 27 Apr 2017 21:46:30 +0200 Subject: [PATCH 193/865] Update video_mencoder.lua use "lib/dtutils.file" and gettext --- contrib/video_mencoder.lua | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/contrib/video_mencoder.lua b/contrib/video_mencoder.lua index db095b58..e834f67f 100644 --- a/contrib/video_mencoder.lua +++ b/contrib/video_mencoder.lua @@ -31,38 +31,34 @@ USAGE ]] local dt = require "darktable" +local df = require "lib/dtutils.file" require "official/yield" +local gettext = dt.gettext dt.configuration.check_version(...,{2,0,1},{3,0,0},{4,0,0}) -local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) - dt.print("Export Image "..tostring(number).."/"..tostring(total)) +-- Tell gettext where to find the .mo file translating messages for a particular domain +gettext.bindtextdomain("video_mencoder",dt.configuration.config_dir.."/lua/locale/") + +local function _(msgid) + return gettext.dgettext("video_mencoder", msgid) end -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (result) then - --dt.print_error("true checkIfBinExists: "..bin) - ret = true - else - dt.print_error(bin.." not found") - ret = false - end - - return ret +local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) + dt.print("Export Image "..tostring(number).."/"..tostring(total)) end local function create_video_mencoder(storage, image_table, extra_data) - if not checkIfBinExists("mencoder") then + if not df.check_if_bin_exists("mencoder") then + dt.print_error(_("mencoder not found")) return end - if not checkIfBinExists("xdg-open") then + if not df.check_if_bin_exists("xdg-open") then + dt.print_error(_("xdg-open not found")) return end - if not checkIfBinExists("xdg-user-dir") then + if not df.check_if_bin_exists("xdg-user-dir") then + dt.print_error(_("xdg-user-dir not found")) return end From dee7ee1dde0058ff492c80382b23901da227d333 Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 27 Apr 2017 21:51:29 +0200 Subject: [PATCH 194/865] Update hugin.lua use "lib/dtutils.file" --- contrib/hugin.lua | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/contrib/hugin.lua b/contrib/hugin.lua index 5099b100..6ae1d12c 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -33,11 +33,11 @@ USAGE This plugin will add a new storage option and calls hugin after export. ]] +local gettext = dt.gettext local dt = require "darktable" +local df = require "lib/dtutils.file" require "official/yield" -local gettext = dt.gettext - -- works with darktable API version from 2.0.0 to 5.0.0 dt.configuration.check_version(...,{2,0,0},{3,0,0},{4,0,0},{5,0,0}) @@ -48,30 +48,13 @@ local function _(msgid) return gettext.dgettext("hugin", msgid) end -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (result) then - dt.print_error("true checkIfBinExists: "..bin) - ret = true - else - dt.print_error(bin.." not found") - ret = false - end - - - return ret -end - local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) dt.print("Export to Hugin "..tostring(number).."/"..tostring(total)) end local function create_panorama(storage, image_table, extra_data) --finalize - if not checkIfBinExists("hugin") then + if not df.check_if_bin_exists("hugin") then dt.print_error(_("hugin not found")) return end @@ -82,7 +65,7 @@ local function create_panorama(storage, image_table, extra_data) --finalize -- http://hugin.sourceforge.net/docs/manual/Pto_gen.html local hugin_executor = false - if (checkIfBinExists("hugin_executor") and checkIfBinExists("pto_gen")) then + if (df.check_if_bin_exists("hugin_executor") and df.check_if_bin_exists("pto_gen")) then hugin_executor = true end From d46b7e4aafcaeaec6e9c0eb47323e4f266274933 Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 27 Apr 2017 21:55:19 +0200 Subject: [PATCH 195/865] Update slideshowMusic.lua use "lib/dtutils.file" --- contrib/slideshowMusic.lua | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/contrib/slideshowMusic.lua b/contrib/slideshowMusic.lua index fff276c6..f96383d2 100644 --- a/contrib/slideshowMusic.lua +++ b/contrib/slideshowMusic.lua @@ -25,9 +25,10 @@ USAGE ]] local dt = require "darktable" +local df = require "lib/dtutils.file" require "official/yield" - local gettext = dt.gettext + dt.configuration.check_version(...,{2,0,2},{3,0,0},{4,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain @@ -37,26 +38,14 @@ local function _(msgid) return gettext.dgettext("slideshowMusic", msgid) end -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (not result) then - dt.print_error(bin.." not found") - ret = false - end - ret = true - return ret -end - local function playSlideshowMusic(_, old_view, new_view) local filename, playMusic filename = dt.preferences.read("slideshowMusic","SlideshowMusic","string") playMusic = dt.preferences.read("slideshowMusic","PlaySlideshowMusic","bool") - if not checkIfBinExists("rhythmbox-client") then + if not df.check_if_bin_exists("rhythmbox-client") then + dt.print_error(_("rhythmbox-client not found")) return end From 2562a218a08b5c6feece123ae85f21575cf7dab2 Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 27 Apr 2017 22:04:15 +0200 Subject: [PATCH 196/865] Update kml_export.lua use "lib/dtutils.file" --- contrib/kml_export.lua | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 569bc4d1..f9e92f8b 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -37,9 +37,10 @@ USAGE ]] local dt = require "darktable" +local df = require "lib/dtutils.file" require "official/yield" - local gettext = dt.gettext + dt.configuration.check_version(...,{3,0,0},{4,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain @@ -77,19 +78,6 @@ local function show_status(storage, image, format, filename, number, total, high dt.print(string.format(_("Export Image %i/%i"), number, total)) end -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (not result) then - dt.print_error(bin.." not found") - ret = false - end - ret = true - return ret -end - -- Strip accents from a string -- Copied from https://forums.coronalabs.com/topic/43048-remove-special-characters-from-string/ function string.stripAccents( str ) @@ -176,16 +164,20 @@ end local function create_kml_file(storage, image_table, extra_data) - if not checkIfBinExists("mkdir") then + if not df.check_if_bin_exists("mkdir") then + dt.print_error(_("mkdir not found")) return end - if not checkIfBinExists("convert") then + if not df.check_if_bin_exists("convert") then + dt.print_error(_("convert not found")) return end - if not checkIfBinExists("xdg-open") then + if not df.check_if_bin_exists("xdg-open"") then + dt.print_error(_("xdg-open" not found")) return end - if not checkIfBinExists("xdg-user-dir") then + if not df.check_if_bin_exists("xdg-user-dir") then + dt.print_error(_("xdg-user-dir not found")) return end @@ -193,7 +185,8 @@ local function create_kml_file(storage, image_table, extra_data) local imageFoldername if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then - if not checkIfBinExists("zip") then + if not df.check_if_bin_exists("zip") then + dt.print_error(_("zip not found")) return end From bff2df018bf5fc95f05ecd3705609c723525c2aa Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 27 Apr 2017 22:07:23 +0200 Subject: [PATCH 197/865] Update enfuse.lua use "lib/dtutils.file" --- official/enfuse.lua | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/official/enfuse.lua b/official/enfuse.lua index 61b8c695..d6ded05f 100644 --- a/official/enfuse.lua +++ b/official/enfuse.lua @@ -33,30 +33,22 @@ TODO ]] local dt = require "darktable" +local df = require "lib/dtutils.file" require "official/yield" - +local gettext = dt.gettext dt.configuration.check_version(...,{3,0,0},{4,0,0}) --- thanks Tobias Jakobs for this function (taken from contrib/hugin.lua) -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (result) then - dt.print_error("true checkIfBinExists: "..bin) - ret = true - else - dt.print_error(bin.." not found") - ret = false - end - return ret +-- Tell gettext where to find the .mo file translating messages for a particular domain +gettext.bindtextdomain("enfuse",dt.configuration.config_dir.."/lua/locale/") + +local function _(msgid) + return gettext.dgettext("enfuse", msgid) end -- add a new lib -- is enfuse installed? -local enfuse_installed = checkIfBinExists("enfuse") +local enfuse_installed = df.check_if_bin_exists("enfuse") -- initialize exposure_mu value and depth setting in config to sane defaults (would be 0 otherwise) if dt.preferences.read("enfuse", "depth", "integer") == 0 then From 79511d9b42b7f25982435360d3d89f3c400d5c8d Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 27 Apr 2017 22:12:34 +0200 Subject: [PATCH 198/865] Update geoJSON_export.lua use "lib/dtutils.file" --- contrib/geoJSON_export.lua | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index 7ae81598..90bb16f8 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -33,9 +33,10 @@ USAGE ]] local dt = require "darktable" +local df = require "lib/dtutils.file" require "official/yield" - local gettext = dt.gettext + dt.configuration.check_version(...,{3,0,0},{4,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain @@ -73,31 +74,21 @@ local function show_status(storage, image, format, filename, number, total, high dt.print(string.format(_("Export Image %i/%i"), number, total)) end -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (not result) then - dt.print_error(bin.." not found") - ret = false - end - ret = true - return ret -end - local function create_geoJSON_file(storage, image_table, extra_data) - - if not checkIfBinExists("mkdir") then + if not df.check_if_bin_exists("mkdir") then + dt.print_error(_("mkdir not found")) return end - if not checkIfBinExists("convert") then + if not df.check_if_bin_exists("convert") then + dt.print_error(_("convert not found")) return end - if not checkIfBinExists("xdg-open") then + if not df.check_if_bin_exists("xdg-open") then + dt.print_error(_("xdg-open not found")) return end - if not checkIfBinExists("xdg-user-dir") then + if not df.check_if_bin_exists("xdg-user-dir") then + dt.print_error(_("xdg-user-dir not found")) return end From 356756286e07f369147904492b9f16b9df7045c6 Mon Sep 17 00:00:00 2001 From: supertobi Date: Thu, 27 Apr 2017 22:19:00 +0200 Subject: [PATCH 199/865] Update gimp.lua use "lib/dtutils.file" --- contrib/gimp.lua | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/contrib/gimp.lua b/contrib/gimp.lua index 13a31c6b..f8472c75 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -64,8 +64,8 @@ ]] local dt = require "darktable" +local df = require "lib/dtutils.file" require "official/yield" - local gettext = dt.gettext dt.configuration.check_version(...,{3,0,0},{4,0,0},{5,0,0}) @@ -104,21 +104,6 @@ local function _(msgid) return gettext.dgettext("gimp", msgid) end -local function checkIfBinExists(bin) - local handle = io.popen("which "..bin) - local result = handle:read() - local ret - handle:close() - if (result) then - dt.print_error("true checkIfBinExists: "..bin) - ret = true - else - dt.print_error(bin.." not found") - ret = false - end - return ret -end - -- Thanks Tobias Jakobs for the idea and the correction function checkIfFileExists(filepath) local file = io.open(filepath,"r") @@ -199,7 +184,7 @@ end local function fileCopy(fromFile, toFile) local result = nil -- if cp exists, use it - if checkIfBinExists("cp") then + if df.check_if_bin_exists("cp") then result = os.execute("cp '" .. fromFile .. "' '" .. toFile .. "'") end -- if cp was not present, or if cp failed, then a pure lua solution @@ -230,7 +215,7 @@ local function fileMove(fromFile, toFile) local success = os.rename(fromFile, toFile) if not success then -- an error occurred, so let's try using the operating system function - if checkIfBinExists("mv") then + if df.check_if_bin_exists("mv") then success = os.execute("mv '" .. fromFile .. "' '" .. toFile .. "'") end -- if the mv didn't exist or succeed, then... @@ -249,7 +234,7 @@ local function fileMove(fromFile, toFile) end local function gimp_edit(storage, image_table, extra_data) --finalize - if not checkIfBinExists("gimp") then + if not df.check_if_bin_exists("gimp") then dt.print_error(_("GIMP not found")) return end From dcc205ec4fa3c57c9491cb160fa7e85efbbd622c Mon Sep 17 00:00:00 2001 From: supertobi Date: Sat, 29 Apr 2017 08:05:19 +0200 Subject: [PATCH 200/865] Update kml_export.lua check_version 5 --- contrib/kml_export.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index f9e92f8b..1684d209 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -41,7 +41,7 @@ local df = require "lib/dtutils.file" require "official/yield" local gettext = dt.gettext -dt.configuration.check_version(...,{3,0,0},{4,0,0}) +dt.configuration.check_version(...,{3,0,0},{4,0,0},{5,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain gettext.bindtextdomain("kml_export",dt.configuration.config_dir.."/lua/locale/") From 750d70bfffc88ad48d587e7c0bd30270b924b440 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sat, 29 Apr 2017 08:06:15 +0200 Subject: [PATCH 201/865] Update geoJSON_export.lua check_version 5 --- contrib/geoJSON_export.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index 90bb16f8..95b39763 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -37,7 +37,7 @@ local df = require "lib/dtutils.file" require "official/yield" local gettext = dt.gettext -dt.configuration.check_version(...,{3,0,0},{4,0,0}) +dt.configuration.check_version(...,{3,0,0},{4,0,0},{5,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain gettext.bindtextdomain("geoJSON_export",dt.configuration.config_dir.."/lua/locale/") From d555cb2c94770936d4887513f1db83e47ebdc904 Mon Sep 17 00:00:00 2001 From: supertobi Date: Sat, 29 Apr 2017 09:03:43 +0200 Subject: [PATCH 202/865] Update geoJSON_export.lua cleanup --- contrib/geoJSON_export.lua | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/contrib/geoJSON_export.lua b/contrib/geoJSON_export.lua index 95b39763..38f4be08 100644 --- a/contrib/geoJSON_export.lua +++ b/contrib/geoJSON_export.lua @@ -94,7 +94,7 @@ local function create_geoJSON_file(storage, image_table, extra_data) dt.print_error("Will try to export geoJSON file now") - local xportDirectory = dt.preferences.read("geoJSON_export","ExportDirectory","string") + local exportDirectory = dt.preferences.read("geoJSON_export","ExportDirectory","string") -- Creates dir if not exsists local imageFoldername = "files/" @@ -106,8 +106,8 @@ local function create_geoJSON_file(storage, image_table, extra_data) if ((image.longitude and image.latitude) and (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then - local path, filename, filetype = string.match(image, "(.-)([^\\/]-%.?([^%.\\/]*))$") - filename = string.upper(string.gsub(filename,"%.", "_")) + local path, filename, filetype = string.match(exported_image, "(.-)([^\\/]-%.?([^%.\\/]*))$") + filename = string.upper(string.gsub(filename,"%.%w*", "")) -- convert -size 92x92 filename.jpg -resize 92x92 +profile "*" thumbnail.jpg -- In this example, '-size 120x120' gives a hint to the JPEG decoder that the image is going to be downscaled to @@ -123,7 +123,7 @@ local function create_geoJSON_file(storage, image_table, extra_data) end -- delete the original image to not get into the kmz file - os.remove(image) + os.remove(exported_image) local pattern = "[/]?([^/]+)$" filmName = string.match(image.film.path, pattern) @@ -140,11 +140,24 @@ local function create_geoJSON_file(storage, image_table, extra_data) ]] for image,exported_image in pairs(image_table) do - filename = string.upper(string.gsub(image.filename,"%.", "_")) + --filename = string.upper(string.gsub(image.filename,"%.", "_")) + -- Extract filename, e.g DSC9784.ARW -> DSC9784 + filename = string.upper(string.gsub(image.filename,"%.%w*", "")) + -- Extract extension from exported image (user can choose JPG or PNG), e.g DSC9784.JPG -> .JPG + extension = string.match(exported_image,"%.%w*$") if ((image.longitude and image.latitude) and (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data ) then + + local image_title, image_description + if (image.title and image.title ~= "") then + image_title = image.title + else + image_title = image.filename + end + image_description = image.description + geoJSON_file = geoJSON_file.. [[ { "type": "Feature", @@ -155,8 +168,8 @@ local function create_geoJSON_file(storage, image_table, extra_data) geoJSON_file = geoJSON_file.. [[ }, "properties": { - "title": "]]..image.title..[[", - "description": "]]..image.description..[[", + "title": "]]..image_title..[[", + "description": "]]..image_description..[[", "image": "]]..imageFoldername..filename..[[.jpg", "icon": { "iconUrl": "]]..imageFoldername.."thumb_"..filename..[[.jpg", @@ -187,7 +200,7 @@ local function create_geoJSON_file(storage, image_table, extra_data) - 2014-05-31 Rieselfelder + ]]..filmName..[[ \n" - - kml_file = kml_file.." \n" - kml_file = kml_file.." \n" - - for image,exported_image in spairs(image_table, function(t,a,b) return b.exif_datetime_taken > a.exif_datetime_taken end) do - if ((image.longitude and image.latitude) and - (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data - ) then - local altitude = 0; - if (image.elevation) then - altitude = image.elevation; - end - kml_file = kml_file.." "..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".")..",altitude\n" - end - end - kml_file = kml_file.." \n" - kml_file = kml_file.." \n" - - kml_file = kml_file.." \n" + kml_file = kml_file.." \n" + kml_file = kml_file.." Path\n" -- ToDo: I think a better name would be nice + --kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + kml_file = kml_file.." \n" + + for image,exported_image in spairs(image_table, function(t,a,b) return b.exif_datetime_taken > a.exif_datetime_taken end) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + local altitude = 0; + if (image.elevation) then + altitude = image.elevation; + end + + kml_file = kml_file.." "..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".")..",altitude\n" + end + end + + kml_file = kml_file.." \n" + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" end kml_file = kml_file.."\n" @@ -399,77 +399,79 @@ local function create_kml_file(storage, image_table, extra_data) dt.print("KML file created in "..exportDirectory) --- Compress the files to create a KMZ file + -- Compress the files to create a KMZ file if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then - exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") + exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") local createKMZCommand = "zip --test --move --junk-paths " createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" " -- KMZ filename createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" " -- KML file for image,exported_image in pairs(image_table) do - if ((image.longitude and image.latitude) and - (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data - ) then - local filename = string.upper(string.gsub(image.filename,"%.%w*", "")) - -- Handle duplicates - filename = addDuplicateIndex( image.duplicate_index, filename ) - createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..imageFoldername.."thumb_"..filename..".jpg\" " -- thumbnails - createKMZCommand = createKMZCommand .."\""..exported_image.."\" " -- images - end + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + local filename = string.upper(string.gsub(image.filename,"%.%w*", "")) + -- Handle duplicates + filename = addDuplicateIndex( image.duplicate_index, filename ) + + createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..imageFoldername.."thumb_"..filename..".jpg\" " -- thumbnails + createKMZCommand = createKMZCommand .."\""..exported_image.."\" " -- images + end end - dt.control.execute(createKMZCommand) + dt.control.execute(createKMZCommand) end --- Open the file with the standard programm + -- Open the file with the standard programm if ( dt.preferences.read("kml_export","OpenKmlFile","bool") == true ) then - local kmlFileOpenCommand + local kmlFileOpenCommand if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMZFilename.."\"" else kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMLFilename.."\"" - end + end dt.control.execute(kmlFileOpenCommand) end - end -- Preferences dt.preferences.register("kml_export", - "OpenKmlFile", - "bool", - _("KML export: Open KML/KMZ file after export"), - _("Opens the KML file after the export with the standard program for KML files"), - false ) + "OpenKmlFile", + "bool", + _("KML export: Open KML/KMZ file after export"), + _("Opens the KML file after the export with the standard program for KML files"), + false ) local handle = io.popen("xdg-user-dir DESKTOP") local result = handle:read() if (result == nil) then - result = "" + result = "" end handle:close() + dt.preferences.register("kml_export", - "ExportDirectory", - "directory", - _("KML export: Export directory"), - _("A directory that will be used to export the KML/KMZ files"), - result ) + "ExportDirectory", + "directory", + _("KML export: Export directory"), + _("A directory that will be used to export the KML/KMZ files"), + result ) dt.preferences.register("kml_export", - "CreatePath", - "bool", - _("KML export: Connect images with path"), - _("connect all images with a path"), - false ) + "CreatePath", + "bool", + _("KML export: Connect images with path"), + _("connect all images with a path"), + false ) + dt.preferences.register("kml_export", - "CreateKMZ", - "bool", - _("KML export: Create KMZ file"), - _("Compress all imeges to one KMZ file"), - true ) + "CreateKMZ", + "bool", + _("KML export: Create KMZ file"), + _("Compress all imeges to one KMZ file"), + true ) -- Register dt.register_storage("kml_export", _("KML/KMZ Export"), nil, create_kml_file) From f86b16735b3d4aa3d1a283dc0028f795832af994 Mon Sep 17 00:00:00 2001 From: Elman Date: Mon, 15 Jan 2018 22:54:22 +0100 Subject: [PATCH 254/865] Formatted code to follow project settings --- contrib/kml_export.lua | 739 +++++++++++++++++++++-------------------- 1 file changed, 371 insertions(+), 368 deletions(-) diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua index 58e0a15a..070a02fa 100644 --- a/contrib/kml_export.lua +++ b/contrib/kml_export.lua @@ -1,20 +1,20 @@ --[[ - This file is part of darktable, - Copyright 2018 by Tobias Jakobs. - Copyright 2018 by Erik Augustin. - - 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 . + This file is part of darktable, + Copyright 2018 by Tobias Jakobs. + Copyright 2018 by Erik Augustin. + + 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 . ]] --[[ darktable KML export script @@ -47,155 +47,155 @@ dt.configuration.check_version(...,{3,0,0},{4,0,0},{5,0,0}) gettext.bindtextdomain("kml_export",dt.configuration.config_dir.."/lua/locale/") local function _(msgid) - return gettext.dgettext("kml_export", msgid) + return gettext.dgettext("kml_export", msgid) end -- Sort a table local function spairs(_table, order) -- Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua - -- collect the keys - local keys = {} - for _key in pairs(_table) do keys[#keys + 1] = _key end - - -- if order function given, sort by it by passing the table and keys a, b, - -- otherwise just sort the keys - if order then - table.sort(keys, function(a,b) return order(_table, a, b) end) - else - table.sort(keys) - end - - -- return the iterator function - local i = 0 - return function() - i = i + 1 - if keys[i] then - return keys[i], _table[keys[i]] - end + -- collect the keys + local keys = {} + for _key in pairs(_table) do keys[#keys + 1] = _key end + + -- if order function given, sort by it by passing the table and keys a, b, + -- otherwise just sort the keys + if order then + table.sort(keys, function(a,b) return order(_table, a, b) end) + else + table.sort(keys) + end + + -- return the iterator function + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], _table[keys[i]] end + end end local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) - dt.print(string.format(_("Export Image %i/%i"), number, total)) + dt.print(string.format(_("Export Image %i/%i"), number, total)) end -- Strip accents from a string -- Copied from https://forums.coronalabs.com/topic/43048-remove-special-characters-from-string/ function string.stripAccents( str ) - local tableAccents = {} - -- A - tableAccents["à"] = "a" - tableAccents["À"] = "A" - tableAccents["á"] = "a" - tableAccents["Á"] = "A" - tableAccents["â"] = "a" - tableAccents["Â"] = "A" - tableAccents["ã"] = "a" - tableAccents["Ã"] = "A" - tableAccents["ä"] = "a" - tableAccents["Ä"] = "A" - -- B - -- C - tableAccents["ç"] = "c" - tableAccents["Ç"] = "C" - tableAccents["č"] = "c" - tableAccents["Č"] = "C" - -- D - tableAccents["ď"] = "d" - tableAccents["Ď"] = "d" - -- E - tableAccents["è"] = "e" - tableAccents["È"] = "E" - tableAccents["é"] = "e" - tableAccents["É"] = "E" - tableAccents["ê"] = "e" - tableAccents["Ê"] = "E" - tableAccents["ë"] = "e" - tableAccents["Ë"] = "E" - tableAccents["ě"] = "e" - tableAccents["Ě"] = "E" - -- F - -- G - -- H - -- I - tableAccents["ì"] = "i" - tableAccents["Ì"] = "I" - tableAccents["í"] = "i" - tableAccents["Í"] = "I" - tableAccents["î"] = "i" - tableAccents["Î"] = "I" - tableAccents["ï"] = "i" - tableAccents["Ï"] = "I" - -- J - -- K - -- L - tableAccents["ĺ"] = "l" - tableAccents["Ĺ"] = "L" - tableAccents["ľ"] = "l" - tableAccents["Ľ"] = "L" - -- M - -- N - tableAccents["ñ"] = "n" - tableAccents["Ñ"] = "N" - tableAccents["ň"] = "n" - tableAccents["Ň"] = "N" - -- O - tableAccents["ò"] = "o" - tableAccents["Ò"] = "O" - tableAccents["ó"] = "o" - tableAccents["Ó"] = "O" - tableAccents["ô"] = "o" - tableAccents["Ô"] = "O" - tableAccents["õ"] = "o" - tableAccents["Õ"] = "O" - tableAccents["ö"] = "o" - tableAccents["Ö"] = "O" - -- P - -- Q - -- R - tableAccents["ŕ"] = "r" - tableAccents["Ŕ"] = "R" - tableAccents["ř"] = "r" - tableAccents["Ř"] = "R" - -- S - tableAccents["š"] = "s" - tableAccents["Š"] = "S" - -- T - tableAccents["ť"] = "t" - tableAccents["Ť"] = "T" - -- U - tableAccents["ù"] = "u" - tableAccents["Ù"] = "U" - tableAccents["ú"] = "u" - tableAccents["Ú"] = "U" - tableAccents["û"] = "u" - tableAccents["Û"] = "U" - tableAccents["ü"] = "u" - tableAccents["Ü"] = "U" - tableAccents["ů"] = "u" - tableAccents["Ů"] = "U" - -- V - -- W - -- X - -- Y - tableAccents["ý"] = "y" - tableAccents["Ý"] = "Y" - tableAccents["ÿ"] = "y" - tableAccents["Ÿ"] = "Y" - -- Z - tableAccents["ž"] = "z" - tableAccents["Ž"] = "Z" - - local normalizedString = "" - - for strChar in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do - if tableAccents[strChar] ~= nil then - normalizedString = normalizedString..tableAccents[strChar] - else - normalizedString = normalizedString..strChar - end + local tableAccents = {} + -- A + tableAccents["à"] = "a" + tableAccents["À"] = "A" + tableAccents["á"] = "a" + tableAccents["Á"] = "A" + tableAccents["â"] = "a" + tableAccents["Â"] = "A" + tableAccents["ã"] = "a" + tableAccents["Ã"] = "A" + tableAccents["ä"] = "a" + tableAccents["Ä"] = "A" + -- B + -- C + tableAccents["ç"] = "c" + tableAccents["Ç"] = "C" + tableAccents["č"] = "c" + tableAccents["Č"] = "C" + -- D + tableAccents["ď"] = "d" + tableAccents["Ď"] = "d" + -- E + tableAccents["è"] = "e" + tableAccents["È"] = "E" + tableAccents["é"] = "e" + tableAccents["É"] = "E" + tableAccents["ê"] = "e" + tableAccents["Ê"] = "E" + tableAccents["ë"] = "e" + tableAccents["Ë"] = "E" + tableAccents["ě"] = "e" + tableAccents["Ě"] = "E" + -- F + -- G + -- H + -- I + tableAccents["ì"] = "i" + tableAccents["Ì"] = "I" + tableAccents["í"] = "i" + tableAccents["Í"] = "I" + tableAccents["î"] = "i" + tableAccents["Î"] = "I" + tableAccents["ï"] = "i" + tableAccents["Ï"] = "I" + -- J + -- K + -- L + tableAccents["ĺ"] = "l" + tableAccents["Ĺ"] = "L" + tableAccents["ľ"] = "l" + tableAccents["Ľ"] = "L" + -- M + -- N + tableAccents["ñ"] = "n" + tableAccents["Ñ"] = "N" + tableAccents["ň"] = "n" + tableAccents["Ň"] = "N" + -- O + tableAccents["ò"] = "o" + tableAccents["Ò"] = "O" + tableAccents["ó"] = "o" + tableAccents["Ó"] = "O" + tableAccents["ô"] = "o" + tableAccents["Ô"] = "O" + tableAccents["õ"] = "o" + tableAccents["Õ"] = "O" + tableAccents["ö"] = "o" + tableAccents["Ö"] = "O" + -- P + -- Q + -- R + tableAccents["ŕ"] = "r" + tableAccents["Ŕ"] = "R" + tableAccents["ř"] = "r" + tableAccents["Ř"] = "R" + -- S + tableAccents["š"] = "s" + tableAccents["Š"] = "S" + -- T + tableAccents["ť"] = "t" + tableAccents["Ť"] = "T" + -- U + tableAccents["ù"] = "u" + tableAccents["Ù"] = "U" + tableAccents["ú"] = "u" + tableAccents["Ú"] = "U" + tableAccents["û"] = "u" + tableAccents["Û"] = "U" + tableAccents["ü"] = "u" + tableAccents["Ü"] = "U" + tableAccents["ů"] = "u" + tableAccents["Ů"] = "U" + -- V + -- W + -- X + -- Y + tableAccents["ý"] = "y" + tableAccents["Ý"] = "Y" + tableAccents["ÿ"] = "y" + tableAccents["Ÿ"] = "Y" + -- Z + tableAccents["ž"] = "z" + tableAccents["Ž"] = "Z" + + local normalizedString = "" + + for strChar in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do + if tableAccents[strChar] ~= nil then + normalizedString = normalizedString..tableAccents[strChar] + else + normalizedString = normalizedString..strChar end + end - return normalizedString + return normalizedString end -- Escape XML characters @@ -203,275 +203,278 @@ end -- https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents function string.escapeXmlCharacters( str ) - str = string.gsub(str,"&", "&") - str = string.gsub(str,"\"", """) - str = string.gsub(str,"'", "'") - str = string.gsub(str,"<", "<") - str = string.gsub(str,">", ">") + str = string.gsub(str,"&", "&") + str = string.gsub(str,"\"", """) + str = string.gsub(str,"'", "'") + str = string.gsub(str,"<", "<") + str = string.gsub(str,">", ">") - return str + return str end -- Add duplicate index to filename -- image.filename does not have index, exported_image has index function addDuplicateIndex( index, filename ) - if index > 0 then - filename = filename.."_" - if index < 10 then - filename = filename.."0" - end - filename = filename..index + if index > 0 then + filename = filename.."_" + if index < 10 then + filename = filename.."0" end + filename = filename..index + end - return filename + return filename end local function create_kml_file(storage, image_table, extra_data) - if not df.check_if_bin_exists("mkdir") then - dt.print_error(_("mkdir not found")) - return - end - if not df.check_if_bin_exists("convert") then - dt.print_error(_("convert not found")) - return - end - if not df.check_if_bin_exists("xdg-open") then - dt.print_error(_("xdg-open not found")) - return - end - if not df.check_if_bin_exists("xdg-user-dir") then - dt.print_error(_("xdg-user-dir not found")) - return + if not df.check_if_bin_exists("mkdir") then + dt.print_error(_("mkdir not found")) + return + end + if not df.check_if_bin_exists("convert") then + dt.print_error(_("convert not found")) + return + end + if not df.check_if_bin_exists("xdg-open") then + dt.print_error(_("xdg-open not found")) + return + end + if not df.check_if_bin_exists("xdg-user-dir") then + dt.print_error(_("xdg-user-dir not found")) + return + end + + dt.print_error("Will try to export KML file now") + + local imageFoldername + if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then + if not df.check_if_bin_exists("zip") then + dt.print_error(_("zip not found")) + return end - dt.print_log("Will try to export KML file now") + exportDirectory = dt.configuration.tmp_dir + imageFoldername = "" + else + exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") + + -- Creates dir if not exsists + imageFoldername = "files/" + local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername + dt.control.execute(mkdirCommand) + end + + -- Create the thumbnails + for image,exported_image in pairs(image_table) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + local path, filename, filetype = string.match(exported_image, "(.-)([^\\/]-%.?([^%.\\/]*))$") + filename = string.upper(string.gsub(filename,"%.%w*", "")) + + -- convert -size 92x92 filename.jpg -resize 92x92 +profile "*" thumbnail.jpg + -- In this example, '-size 120x120' gives a hint to the JPEG decoder that the image is going to be downscaled to + -- 120x120, allowing it to run faster by avoiding returning full-resolution images to GraphicsMagick for the + -- subsequent resizing operation. The '-resize 120x120' specifies the desired dimensions of the output image. It + -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other + -- profiles that might be present in the input and aren't needed in the thumbnail. + + local convertToThumbCommand = "convert -size 96x96 "..exported_image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" + dt.control.execute(convertToThumbCommand) + else + -- Remove exported image if it has no GPS data + os.remove(exported_image) + end - local imageFoldername - if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then - if not df.check_if_bin_exists("zip") then - dt.print_error(_("zip not found")) - return + local pattern = "[/]?([^/]+)$" + filmName = string.match(image.film.path, pattern) + + -- Strip accents from the filename, because GoogleEarth can't open them + -- https://github.com/darktable-org/lua-scripts/issues/54 + filmName = string.stripAccents(filmName) + end + + exportKMLFilename = filmName..".kml" + exportKMZFilename = filmName..".kmz" + + -- Create the KML file + local kml_file = "\n" + kml_file = kml_file.."\n" + kml_file = kml_file.."\n" + + --image_table = dt.gui.selection(); + kml_file = kml_file..""..filmName.."\n" + kml_file = kml_file.." Exported from darktable\n" + + for image,exported_image in pairs(image_table) do + -- Extract filename, e.g DSC9784.ARW -> DSC9784 + filename = string.upper(string.gsub(image.filename,"%.%w*", "")) + -- Handle duplicates + filename = addDuplicateIndex( image.duplicate_index, filename ) + -- Extract extension from exported image (user can choose JPG or PNG), e.g DSC9784.JPG -> .JPG + extension = string.match(exported_image,"%.%w*$") + + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + kml_file = kml_file.." \n" + + local image_title, image_description + if (image.title and image.title ~= "") then + image_title = string.escapeXmlCharacters(image.title) + else + image_title = filename..extension + end + -- Characters should not be escaped in CDATA, but we are using HTML fragment, so we must escape them + image_description = string.escapeXmlCharacters(image.description) + + kml_file = kml_file.." "..image_title.."\n" + kml_file = kml_file.." "..image_description.."\n" + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + kml_file = kml_file.." 1\n" + kml_file = kml_file.." "..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".")..",0\n" + kml_file = kml_file.." \n" + kml_file = kml_file.." "..string.gsub(image.exif_datetime_taken," ", "T").."Z".."\n" + kml_file = kml_file.." \n" + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + end + end + + -- Connects all images with an path + if ( dt.preferences.read("kml_export","CreatePath","bool") == true ) then + kml_file = kml_file.." \n" + kml_file = kml_file.." Path\n" -- ToDo: I think a better name would be nice + --kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + kml_file = kml_file.." \n" + + for image,exported_image in spairs(image_table, function(t,a,b) return b.exif_datetime_taken > a.exif_datetime_taken end) do + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + local altitude = 0; + if (image.elevation) then + altitude = image.elevation; end - exportDirectory = dt.configuration.tmp_dir - imageFoldername = "" - else - exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") - - -- Creates dir if not exsists - imageFoldername = "files/" - local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername - dt.control.execute(mkdirCommand) + kml_file = kml_file.." "..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".")..",altitude\n" + end end - -- Create the thumbnails - for image,exported_image in pairs(image_table) do - if ((image.longitude and image.latitude) and - (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data - ) then - local path, filename, filetype = string.match(exported_image, "(.-)([^\\/]-%.?([^%.\\/]*))$") - filename = string.upper(string.gsub(filename,"%.%w*", "")) - - -- convert -size 92x92 filename.jpg -resize 92x92 +profile "*" thumbnail.jpg - -- In this example, '-size 120x120' gives a hint to the JPEG decoder that the image is going to be downscaled to - -- 120x120, allowing it to run faster by avoiding returning full-resolution images to GraphicsMagick for the - -- subsequent resizing operation. The '-resize 120x120' specifies the desired dimensions of the output image. It - -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other - -- profiles that might be present in the input and aren't needed in the thumbnail. - - local convertToThumbCommand = "convert -size 96x96 "..exported_image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" - dt.control.execute(convertToThumbCommand) - else - -- Remove exported image if it has no GPS data - os.remove(exported_image) - end + kml_file = kml_file.." \n" + kml_file = kml_file.." \n" - local pattern = "[/]?([^/]+)$" - filmName = string.match(image.film.path, pattern) + kml_file = kml_file.." \n" + end - -- Strip accents from the filename, because GoogleEarth can't open them - -- https://github.com/darktable-org/lua-scripts/issues/54 - filmName = string.stripAccents(filmName) - end + kml_file = kml_file.."\n" + kml_file = kml_file.."" + + local file = io.open(exportDirectory.."/"..exportKMLFilename, "w") + file:write(kml_file) + file:close() - exportKMLFilename = filmName..".kml" - exportKMZFilename = filmName..".kmz" + dt.print("KML file created in "..exportDirectory) - -- Create the KML file - local kml_file = "\n" - kml_file = kml_file.."\n" - kml_file = kml_file.."\n" + -- Compress the files to create a KMZ file + if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then + exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") - --image_table = dt.gui.selection(); - kml_file = kml_file..""..filmName.."\n" - kml_file = kml_file.." Exported from darktable\n" + local createKMZCommand = "zip --test --move --junk-paths " + createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" " -- KMZ filename + createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" " -- KML file for image,exported_image in pairs(image_table) do - -- Extract filename, e.g DSC9784.ARW -> DSC9784 - filename = string.upper(string.gsub(image.filename,"%.%w*", "")) + if ((image.longitude and image.latitude) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + local filename = string.upper(string.gsub(image.filename,"%.%w*", "")) -- Handle duplicates filename = addDuplicateIndex( image.duplicate_index, filename ) - -- Extract extension from exported image (user can choose JPG or PNG), e.g DSC9784.JPG -> .JPG - extension = string.match(exported_image,"%.%w*$") - - if ((image.longitude and image.latitude) and - (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data - ) then - kml_file = kml_file.." \n" - - local image_title, image_description - if (image.title and image.title ~= "") then - image_title = string.escapeXmlCharacters(image.title) - else - image_title = filename..extension - end - -- Characters should not be escaped in CDATA, but we are using HTML fragment, so we must escape them - image_description = string.escapeXmlCharacters(image.description) - - kml_file = kml_file.." "..image_title.."\n" - kml_file = kml_file.." "..image_description.."\n" - kml_file = kml_file.." \n" - - kml_file = kml_file.." \n" - kml_file = kml_file.." 1\n" - kml_file = kml_file.." "..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".")..",0\n" - kml_file = kml_file.." \n" - kml_file = kml_file.." "..string.gsub(image.exif_datetime_taken," ", "T").."Z".."\n" - kml_file = kml_file.." \n" - kml_file = kml_file.." \n" - - kml_file = kml_file.." \n" - end - end - -- Connects all images with an path - if ( dt.preferences.read("kml_export","CreatePath","bool") == true ) then - kml_file = kml_file.." \n" - kml_file = kml_file.." Path\n" -- ToDo: I think a better name would be nice - --kml_file = kml_file.." \n" - - kml_file = kml_file.." \n" - - kml_file = kml_file.." \n" - kml_file = kml_file.." \n" - - for image,exported_image in spairs(image_table, function(t,a,b) return b.exif_datetime_taken > a.exif_datetime_taken end) do - if ((image.longitude and image.latitude) and - (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data - ) then - local altitude = 0; - if (image.elevation) then - altitude = image.elevation; - end - - kml_file = kml_file.." "..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".")..",altitude\n" - end - end - - kml_file = kml_file.." \n" - kml_file = kml_file.." \n" - - kml_file = kml_file.." \n" + createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..imageFoldername.."thumb_"..filename..".jpg\" " -- thumbnails + createKMZCommand = createKMZCommand .."\""..exported_image.."\" " -- images + end end - kml_file = kml_file.."\n" - kml_file = kml_file.."" - - local file = io.open(exportDirectory.."/"..exportKMLFilename, "w") - file:write(kml_file) - file:close() + dt.control.execute(createKMZCommand) + end - dt.print("KML file created in "..exportDirectory) + -- Open the file with the standard programm + if ( dt.preferences.read("kml_export","OpenKmlFile","bool") == true ) then + local kmlFileOpenCommand - -- Compress the files to create a KMZ file if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then - exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") - - local createKMZCommand = "zip --test --move --junk-paths " - createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" " -- KMZ filename - createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" " -- KML file - - for image,exported_image in pairs(image_table) do - if ((image.longitude and image.latitude) and - (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data - ) then - local filename = string.upper(string.gsub(image.filename,"%.%w*", "")) - -- Handle duplicates - filename = addDuplicateIndex( image.duplicate_index, filename ) - - createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..imageFoldername.."thumb_"..filename..".jpg\" " -- thumbnails - createKMZCommand = createKMZCommand .."\""..exported_image.."\" " -- images - end - end - - dt.control.execute(createKMZCommand) - end - - -- Open the file with the standard programm - if ( dt.preferences.read("kml_export","OpenKmlFile","bool") == true ) then - local kmlFileOpenCommand - - if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then - kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMZFilename.."\"" - else - kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMLFilename.."\"" - end - dt.control.execute(kmlFileOpenCommand) + kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMZFilename.."\"" + else + kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMLFilename.."\"" end + dt.control.execute(kmlFileOpenCommand) + end end -- Preferences dt.preferences.register("kml_export", - "OpenKmlFile", - "bool", - _("KML export: Open KML/KMZ file after export"), - _("Opens the KML file after the export with the standard program for KML files"), - false ) + "OpenKmlFile", + "bool", + _("KML export: Open KML/KMZ file after export"), + _("Opens the KML file after the export with the standard program for KML files"), + false ) local handle = io.popen("xdg-user-dir DESKTOP") local result = handle:read() if (result == nil) then - result = "" + result = "" end handle:close() dt.preferences.register("kml_export", - "ExportDirectory", - "directory", - _("KML export: Export directory"), - _("A directory that will be used to export the KML/KMZ files"), - result ) + "ExportDirectory", + "directory", + _("KML export: Export directory"), + _("A directory that will be used to export the KML/KMZ files"), + result ) dt.preferences.register("kml_export", - "CreatePath", - "bool", - _("KML export: Connect images with path"), - _("connect all images with a path"), - false ) + "CreatePath", + "bool", + _("KML export: Connect images with path"), + _("connect all images with a path"), + false ) dt.preferences.register("kml_export", - "CreateKMZ", - "bool", - _("KML export: Create KMZ file"), - _("Compress all imeges to one KMZ file"), - true ) + "CreateKMZ", + "bool", + _("KML export: Create KMZ file"), + _("Compress all imeges to one KMZ file"), + true ) -- Register dt.register_storage("kml_export", _("KML/KMZ Export"), nil, create_kml_file) + +-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua +-- kate: hl Lua; From 493dcc7ef7131b2b75111011a4e0060edf4f9c77 Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Wed, 17 Jan 2018 10:41:55 +0100 Subject: [PATCH 255/865] Don't delete tags while iterating --- official/delete_long_tags.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/official/delete_long_tags.lua b/official/delete_long_tags.lua index 3e2378b7..5a2da73c 100644 --- a/official/delete_long_tags.lua +++ b/official/delete_long_tags.lua @@ -1,6 +1,6 @@ --[[ This file is part of darktable, - copyright (c) 2014 Tobias Ellinghaus + copyright (c) 2014--2018 Tobias Ellinghaus darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ ]] --[[ DELETE LONG TAGS -A simple script that will automatically delete all tag longer than a set length +A simple script that will automatically delete all tags longer than a set length USAGE * require this script from your main lua file @@ -38,10 +38,18 @@ dt.preferences.register("delete_long_tags", "length", "integer", local max_length = dt.preferences.read("delete_long_tags", "length", "integer") +-- deleting while iterating the tags list seems to break the iterator! +local long_tags = {} + for _,t in ipairs(dt.tags) do local len = #t.name if len > max_length then print("deleting tag `"..t.name.."' (length: "..len..")") - t:delete() + table.insert(long_tags, t.name) end end + +for _,name in pairs(long_tags) do + tag = dt.tags.find(name) + tag:delete() +end From 95077f639b0345f35f8fb810190202b86c55e88b Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Wed, 17 Jan 2018 10:42:44 +0100 Subject: [PATCH 256/865] New script to delete unused tags on startup --- official/delete_unused_tags.lua | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 official/delete_unused_tags.lua diff --git a/official/delete_unused_tags.lua b/official/delete_unused_tags.lua new file mode 100644 index 00000000..337f5f64 --- /dev/null +++ b/official/delete_unused_tags.lua @@ -0,0 +1,46 @@ +--[[ + This file is part of darktable, + copyright (c) 2018 Tobias Ellinghaus + + 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 . +]] +--[[ +DELETE UNUSED TAGS +A simple script that will automatically delete all tags that are not attached to any images + +USAGE +* require this script from your main lua file +* restart darktable + +all tags that are not used will be automatically deleted at every restart +]] + +local dt = require "darktable" + +dt.configuration.check_version(...,{5,0,0}) + +-- deleting while iterating the tags list seems to break the iterator! +local unused_tags = {} + +for _, t in ipairs(dt.tags) do + if #t == 0 then + table.insert(unused_tags, t.name) + end +end + +for _,name in pairs(unused_tags) do + print("deleting tag `" .. name .. "'") + tag = dt.tags.find(name) + tag:delete() +end From 54572de8d9dfb4b618ee39ebde358b09b9714878 Mon Sep 17 00:00:00 2001 From: Tobias Ellinghaus Date: Tue, 23 Jan 2018 11:28:45 +0100 Subject: [PATCH 257/865] Fix LabelsToTags for Lua 5.3 Fixes #106 --- contrib/LabelsToTags.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/LabelsToTags.lua b/contrib/LabelsToTags.lua index 1135a96b..431760e5 100644 --- a/contrib/LabelsToTags.lua +++ b/contrib/LabelsToTags.lua @@ -43,9 +43,13 @@ LGPLv2+ ]] + local darktable = require("darktable") darktable.configuration.check_version(...,{3,0,0},{4,0,0},{5,0,0}) +-- Lua 5.3 no longer has "unpack" but "table.unpack" +unpack = unpack or table.unpack + local LIB_ID = "LabelsToTags" -- Helper functions: BEGIN @@ -151,7 +155,7 @@ local function doTagging(selfC) local job = darktable.gui.create_job(string.format("labels to tags (%d image" .. (#(darktable.gui.action_images) == 1 and "" or "s") .. ")",#(darktable.gui.action_images)),true) job.percent = 0.0 local pctIncrement = 1.0 / #(darktable.gui.action_images) - + local availableMappings = getAvailableMappings() local memoizedTags = {} for _,img in ipairs(darktable.gui.action_images) do From 5d57347730a1278f89bfabba2c7acec96e2e208b Mon Sep 17 00:00:00 2001 From: Andy Chien Date: Thu, 22 Feb 2018 16:01:54 -0800 Subject: [PATCH 258/865] fixed a couple dtutils_file functions for windows platform --- lib/dtutils/file.lua | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/dtutils/file.lua b/lib/dtutils/file.lua index 617234b5..bc215e3c 100644 --- a/lib/dtutils/file.lua +++ b/lib/dtutils/file.lua @@ -51,7 +51,13 @@ dtutils_file.libdoc.functions["check_if_bin_exists"] = { } function dtutils_file.check_if_bin_exists(bin) - local result = os.execute("which " .. bin) + local cmd + if package.config:sub(1,1) == '/' then + cmd = 'which ' + else + cmd = 'where ' + end + local result = os.execute(cmd .. bin) if not result then result = false end @@ -194,10 +200,13 @@ dtutils_file.libdoc.functions["check_if_file_exists"] = { } function dtutils_file.check_if_file_exists(filepath) - local result = os.execute("test -e " .. filepath) - if not result then - result = false + local file = io.open(filepath, "r") + local result = false + if file then + result = true + file:close() end + return result end @@ -384,7 +393,7 @@ function dtutils_file.create_unique_filename(filepath) while dtutils_file.check_if_file_exists(filepath) do filepath = dtutils_file.filename_increment(filepath) -- limit to 99 more exports of the original export - if string.match(dtfileutils.get_basename(filepath), "_(d-)$") == "99" then + if string.match(dtutils_file.get_basename(filepath), "_(d-)$") == "99" then break end end From 4ad9e77a7e0a0c86a9837e1212c7fd6ecdfe4787 Mon Sep 17 00:00:00 2001 From: Andy Chien Date: Thu, 22 Feb 2018 16:07:28 -0800 Subject: [PATCH 259/865] improved a few aspects of the hugin script: * handle stiching all from hugin_executor without the gui * automatically create the panorama file name based on first selected file plus _pano * automatically detects if output file exists, if so use an unique name * delete temporarily exported file --- contrib/hugin.lua | 51 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/contrib/hugin.lua b/contrib/hugin.lua index d69a8ad7..9008b157 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -71,38 +71,59 @@ local function create_panorama(storage, image_table, extra_data) --finalize -- list of exported images local img_list + local img_set = {} -- reset and create image list img_list = "" - - for _,v in pairs(image_table) do + for k,v in pairs(image_table) do img_list = img_list ..v.. " " + table.insert(img_set, k) end - dt.print(_("Will try to stitch now")) + -- use first file as basename + table.sort(img_set, function(a,b) return a.filename Date: Fri, 23 Feb 2018 18:14:24 -0800 Subject: [PATCH 260/865] platform dependent implementation of check_if_bin_exists and check_if_file_exists --- lib/dtutils/file.lua | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/dtutils/file.lua b/lib/dtutils/file.lua index bc215e3c..22cd5e56 100644 --- a/lib/dtutils/file.lua +++ b/lib/dtutils/file.lua @@ -51,16 +51,17 @@ dtutils_file.libdoc.functions["check_if_bin_exists"] = { } function dtutils_file.check_if_bin_exists(bin) - local cmd - if package.config:sub(1,1) == '/' then - cmd = 'which ' + local result + if (dt.configuration.running_os == 'linux') then + result = os.execute("which "..bin) else - cmd = 'where ' + result = dtutils_file.check_if_file_exists(bin) end - local result = os.execute(cmd .. bin) + if not result then result = false end + return result end @@ -200,11 +201,26 @@ dtutils_file.libdoc.functions["check_if_file_exists"] = { } function dtutils_file.check_if_file_exists(filepath) - local file = io.open(filepath, "r") - local result = false - if file then - result = true - file:close() + local result + if (dt.configuration.running_os == 'windows') then + filepath = string.gsub(filepath, '[\\/]+', '\\') + result = os.execute('if exist "'..filepath..'" (cmd /c exit 0) else (cmd /c exit 1)') + if not result then + result = false + end + elseif (dt.configuration.running_os == "linux") then + result = os.execute('test -e ' .. filepath) + if not result then + result = false + end + else + local file = io.open(filepath, "r") + if file then + result = true + file:close() + else + result = false + end end return result @@ -400,4 +416,4 @@ function dtutils_file.create_unique_filename(filepath) return filepath end -return dtutils_file +return dtutils_file \ No newline at end of file From fe942100a40691d3b2250b5125b9984e3231dca5 Mon Sep 17 00:00:00 2001 From: Andy Chien Date: Fri, 23 Feb 2018 10:07:45 -0800 Subject: [PATCH 261/865] hugin plugin improvements * added preference requiring user to specify the paths for hugin, hugin_executor and pto_gen needed for this plguin * added preference to allow user to choose to launch hugin in GUI mode * minor fix to the way files are handled; due to some versions of hugin_executor not writing out to the path specified in --prefix, assume we are working in the tmp directory and then move the file afterwards --- contrib/hugin.lua | 111 ++++++++++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 42 deletions(-) diff --git a/contrib/hugin.lua b/contrib/hugin.lua index 9008b157..477e5060 100644 --- a/contrib/hugin.lua +++ b/contrib/hugin.lua @@ -28,7 +28,9 @@ ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT * hugin USAGE -* require this file from your main luarc config file. +* require this file from your main luarc config file +* set the hugin tool paths in preferences +* if hugin gui mode is used, save the final result in the tmp directory with the first file name and _pano as suffix for the image to be automatically imported to DT afterwards This plugin will add a new storage option and calls hugin after export. ]] @@ -37,6 +39,7 @@ local dt = require "darktable" local df = require "lib/dtutils.file" require "official/yield" local gettext = dt.gettext +local namespace = 'module_hugin' -- works with darktable API version from 2.0.0 to 5.0.0 dt.configuration.check_version(...,{2,0,0},{3,0,0},{4,0,0},{5,0,0}) @@ -45,28 +48,33 @@ dt.configuration.check_version(...,{2,0,0},{3,0,0},{4,0,0},{5,0,0}) gettext.bindtextdomain("hugin",dt.configuration.config_dir.."/lua/locale/") local function _(msgid) - return gettext.dgettext("hugin", msgid) + return gettext.dgettext("hugin", msgid) end local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) - dt.print("Export to Hugin "..tostring(number).."/"..tostring(total)) + dt.print("exporting to Hugin: "..tostring(number).."/"..tostring(total)) end local function create_panorama(storage, image_table, extra_data) --finalize - if not df.check_if_bin_exists("hugin") then - dt.print_error(_("hugin not found")) - return - end - -- Since Hugin 2015.0.0 hugin provides a command line tool to start the assistant -- http://wiki.panotools.org/Hugin_executor -- We need pto_gen to create pto file for hugin_executor -- http://hugin.sourceforge.net/docs/manual/Pto_gen.html - local hugin_executor = false - if (df.check_if_bin_exists("hugin_executor") and df.check_if_bin_exists("pto_gen")) then - hugin_executor = true + local hugin = '"'..dt.preferences.read(namespace, "hugin", "file")..'"' + local hugin_executor = '"'..dt.preferences.read(namespace, "hugin_executor", "file")..'"' + local pto_gen = '"'..dt.preferences.read(namespace, "pto_gen", "file")..'"' + local user_prefer_gui = dt.preferences.read(namespace, "hugin_prefer_gui", "bool") + + local cmd_line_available = false + if df.check_if_bin_exists(hugin_executor) and df.check_if_bin_exists(pto_gen) then + cmd_line_available = true + end + + local gui_available = false + if df.check_if_bin_exists(hugin) then + gui_available = true end -- list of exported images @@ -76,58 +84,77 @@ local function create_panorama(storage, image_table, extra_data) --finalize -- reset and create image list img_list = "" for k,v in pairs(image_table) do - img_list = img_list ..v.. " " - table.insert(img_set, k) + img_list = img_list..v..' ' + table.insert(img_set, k) end - -- use first file as basename + -- use first file as basename for output file table.sort(img_set, function(a,b) return a.filename Date: Fri, 2 Mar 2018 14:07:29 -0500 Subject: [PATCH 262/865] Added windows and macOS external executable compatibility. Added functions set_executable_path_preference(), get_executable_path_preference(), and executable_path_widget() to lib/dtutils/file.lua to get, set and retrieve the location of executables on windows and macOS systems. Modified check_if_bin_exists to use the path preferences so executables can be found on windows and macOS systems as well as linux. Modified contrib/gimp.lua to use the new functions, thus making it usable on windows and macOS too. --- contrib/gimp.lua | 177 ++++++++----------------------------------- lib/dtutils/file.lua | 133 +++++++++++++++++++++++++++++--- 2 files changed, 153 insertions(+), 157 deletions(-) diff --git a/contrib/gimp.lua b/contrib/gimp.lua index f8472c75..c0fba7ec 100644 --- a/contrib/gimp.lua +++ b/contrib/gimp.lua @@ -67,109 +67,38 @@ local dt = require "darktable" local df = require "lib/dtutils.file" require "official/yield" local gettext = dt.gettext +local gimp_widget = nil -dt.configuration.check_version(...,{3,0,0},{4,0,0},{5,0,0}) +dt.configuration.check_version(...,{5,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/locale/") -local function split_filepath(str) - local result = {} - -- Thank you Tobias Jakobs for the awesome regular expression, which I tweaked a little - result["path"], result["filename"], result["basename"], result["filetype"] = string.match(str, "(.-)(([^\\/]-)%.?([^%.\\/]*))$") - return result -end - -local function get_path(str) - local parts = split_filepath(str) - return parts["path"] -end - -local function get_filename(str) - local parts = split_filepath(str) - return parts["filename"] -end - -local function get_basename(str) - local parts = split_filepath(str) - return parts["basename"] -end - -local function get_filetype(str) - local parts = split_filepath(str) - return parts["filetype"] -end - local function _(msgid) return gettext.dgettext("gimp", msgid) end --- Thanks Tobias Jakobs for the idea and the correction -function checkIfFileExists(filepath) - local file = io.open(filepath,"r") - local ret - if file ~= nil then - io.close(file) - dt.print_error("true checkIfFileExists: "..filepath) - ret = true - else - dt.print_error(filepath.." not found") - ret = false - end - return ret -end - -local function filename_increment(filepath) - - -- break up the filepath into parts - local path = get_path(filepath) - local basename = get_basename(filepath) - local filetype = get_filetype(filepath) - - -- check to see if we've incremented before - local increment = string.match(basename, "_(%d-)$") - - if increment then - -- we do 2 digit increments so make sure we didn't grab part of the filename - if string.len(increment) > 2 then - -- we got the filename so set the increment to 01 - increment = "01" - else - increment = string.format("%02d", tonumber(increment) + 1) - basename = string.gsub(basename, "_(%d-)$", "") - end - else - increment = "01" - end - local incremented_filepath = path .. basename .. "_" .. increment .. "." .. filetype - - dt.print_error("original file was " .. filepath) - dt.print_error("incremented file is " .. incremented_filepath) - - return incremented_filepath -end - -local function groupIfNotMember(img, new_img) +local function group_if_not_member(img, new_img) local image_table = img:get_group_members() local is_member = false for _,image in ipairs(image_table) do - dt.print_error(image.filename .. " is a member") + dt.print_log(image.filename .. " is a member") if image.filename == new_img.filename then is_member = true - dt.print_error("Already in group") + dt.print_log("Already in group") end end if not is_member then - dt.print_error("group leader is "..img.group_leader.filename) + dt.print_log("group leader is "..img.group_leader.filename) new_img:group_with(img.group_leader) - dt.print_error("Added to group") + dt.print_log("Added to group") end end local function sanitize_filename(filepath) - local path = get_path(filepath) - local basename = get_basename(filepath) - local filetype = get_filetype(filepath) + local path = df.get_path(filepath) + local basename = df.get_basename(filepath) + local filetype = df.get_filetype(filepath) local sanitized = string.gsub(basename, " ", "\\ ") @@ -181,60 +110,11 @@ local function show_status(storage, image, format, filename, dt.print(string.format(_("Export Image %i/%i"), number, total)) end -local function fileCopy(fromFile, toFile) - local result = nil - -- if cp exists, use it - if df.check_if_bin_exists("cp") then - result = os.execute("cp '" .. fromFile .. "' '" .. toFile .. "'") - end - -- if cp was not present, or if cp failed, then a pure lua solution - if not result then - local fileIn, err = io.open(fromFile, 'rb') - if fileIn then - local fileOut, errr = io.open(toFile, 'w') - if fileOut then - local content = fileIn:read(4096) - while content do - fileOut:write(content) - content = fileIn:read(4096) - end - result = true - fileIn:close() - fileOut:close() - else - dt.print_error("fileCopy Error: " .. errr) - end - else - dt.print_error("fileCopy Error: " .. err) - end - end - return result -end +local function gimp_edit(storage, image_table, extra_data) --finalize -local function fileMove(fromFile, toFile) - local success = os.rename(fromFile, toFile) - if not success then - -- an error occurred, so let's try using the operating system function - if df.check_if_bin_exists("mv") then - success = os.execute("mv '" .. fromFile .. "' '" .. toFile .. "'") - end - -- if the mv didn't exist or succeed, then... - if not success then - -- pure lua solution - success = fileCopy(fromFile, toFile) - if success then - os.remove(fromFile) - else - dt.print_error("fileMove Error: Unable to move " .. fromFile .. " to " .. toFile .. ". Leaving " .. fromFile .. " in place.") - dt.print(string.format(_("Unable to move edited file into collection. Leaving it as %s"), fromFile)) - end - end - end - return success -- nil on error, some value if success -end + local gimp_executable = df.check_if_bin_exists("gimp") -local function gimp_edit(storage, image_table, extra_data) --finalize - if not df.check_if_bin_exists("gimp") then + if not gimp_executable then dt.print_error(_("GIMP not found")) return end @@ -253,9 +133,9 @@ local function gimp_edit(storage, image_table, extra_data) --finalize dt.print(_("Launching GIMP...")) local gimpStartCommand - gimpStartCommand = "gimp "..img_list + gimpStartCommand = gimp_executable .. " " .. img_list - dt.print_error(gimpStartCommand) + dt.print_log(gimpStartCommand) dt.control.execute( gimpStartCommand) @@ -266,28 +146,28 @@ local function gimp_edit(storage, image_table, extra_data) --finalize for image,exported_image in pairs(image_table) do - local myimage_name = image.path .. "/" .. get_filename(exported_image) + local myimage_name = image.path .. "/" .. df.get_filename(exported_image) - while checkIfFileExists(myimage_name) do - myimage_name = filename_increment(myimage_name) + while df.check_if_file_exists(myimage_name) do + myimage_name = df.filename_increment(myimage_name) -- limit to 99 more exports of the original export - if string.match(get_basename(myimage_name), "_(d-)$") == "99" then + if string.match(df.get_basename(myimage_name), "_(d-)$") == "99" then break end end - dt.print_error("moving " .. exported_image .. " to " .. myimage_name) - local result = fileMove(exported_image, myimage_name) + dt.print_log("moving " .. exported_image .. " to " .. myimage_name) + local result = df.file_move(exported_image, myimage_name) if result then - dt.print_error("importing file") + dt.print_log("importing file") local myimage = dt.database.import(myimage_name) - groupIfNotMember(image, myimage) + group_if_not_member(image, myimage) for _,tag in pairs(dt.tags.get_tags(image)) do if not (string.sub(tag.name,1,9) == "darktable") then - dt.print_error("attaching tag") + dt.print_log("attaching tag") dt.tags.attach(tag,myimage) end end @@ -297,6 +177,13 @@ local function gimp_edit(storage, image_table, extra_data) --finalize end -- Register -dt.register_storage("module_gimp", _("Edit with GIMP"), show_status, gimp_edit) + +local executables = {"gimp"} + +if dt.configuration.running_os ~= "linux" then + gimp_widget = df.executable_path_widget(executables) +end + +dt.register_storage("module_gimp", _("Edit with GIMP"), show_status, gimp_edit, nil, nil, gimp_widget) -- diff --git a/lib/dtutils/file.lua b/lib/dtutils/file.lua index 22cd5e56..696cdbc6 100644 --- a/lib/dtutils/file.lua +++ b/lib/dtutils/file.lua @@ -23,7 +23,7 @@ dtutils_file.libdoc = { local gettext = dt.gettext -dt.configuration.check_version(...,{3,0,0},{4,0,0},{5,0,0}) +dt.configuration.check_version(...,{5,0,0}) -- Tell gettext where to find the .mo file translating messages for a particular domain gettext.bindtextdomain("dtutils.file",dt.configuration.config_dir.."/lua/locale/") @@ -34,14 +34,18 @@ end dtutils_file.libdoc.functions["check_if_bin_exists"] = { Name = [[check_if_bin_exists]], - Synopsis = [[check if an executable is in the path]], + Synopsis = [[check if an executable exists]], Usage = [[local df = require "lib/dtutils.file" local result = df.check_if_bin_exists(bin) bin - string - the binary to check for]], - Description = [[check_if_bin_exists checks to see if the specified binary executable is - in the path.]], - Return_Value = [[result - boolean - true if the executable was found, false if not]], + Description = [[check_if_bin_exists checks to see if the specified binary exists. + check_if_bin_exists first checks to see if a preference for the binary has been + registered and uses that if found. The presence of the file is verified, then + quoted and returned. If no preference is specified and the operating system is + linux then the which command is used to check for a binary in the path. If found + that path is returned. If no binary is found, false is returned.]], + Return_Value = [[result - string - the path of the binary, false if not found]], Limitations = [[]], Example = [[]], See_Also = [[]], @@ -51,17 +55,27 @@ dtutils_file.libdoc.functions["check_if_bin_exists"] = { } function dtutils_file.check_if_bin_exists(bin) - local result - if (dt.configuration.running_os == 'linux') then - result = os.execute("which "..bin) + local result = false + local path = nil + + if string.match(bin, "/") or string.match(bin, "\\") then + path = bin else - result = dtutils_file.check_if_file_exists(bin) + path = dtutils_file.get_executable_path_preference(bin) end - if not result then - result = false + if string.len(path) > 0 then + if dtutils_file.check_if_file_exists(path) then + result = "\"" .. path .. "\"" + end + elseif dt.configuration.running_os == "linux" then + local p = io.popen("which " .. bin) + local output = p:read("*a") + p:close() + if string.len(output) > 0 then + result = output:sub(1,-2) + end end - return result end @@ -416,4 +430,99 @@ function dtutils_file.create_unique_filename(filepath) return filepath end + +dtutils_file.libdoc.functions["set_executable_path_preference"] = { + Name = [[set_executable_path_preference]], + Synopsis = [[set a preference for the path to an executable]], + Usage = [[local df = require "lib/dtutils.file" + + df.set_executable_path_preference(executable, path) + executable - string - the name of the executable to set the path for + path - string - the path to the binary]], + Description = [[set_executable_path_preference takes an executable name and path to the + executable and registers the preference for later use.]], + Return_Value = [[]], + Limitations = [[]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_file.set_executable_path_preference(executable, path) + dt.preferences.write("executable_paths", executable, "string", path) +end + + +dtutils_file.libdoc.functions["get_executable_path_preference"] = { + Name = [[get_executable_path_preference]], + Synopsis = [[return the path to an executable from a preference]], + Usage = [[local df = require "lib/dtutils.file" + + local result = df.get_executable_path_preference(executable) + executable - string - the name of the executable to get the path for]], + Description = [[get_executable_path_preference returns the path preference to + the requested executable.]], + Return_Value = [[result - string - path to the executable]], + Limitations = [[executable should be the basename of the executable without extensions]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_file.get_executable_path_preference(executable) + return dt.preferences.read("executable_paths", executable, "string") +end + + +dtutils_file.libdoc.functions["executable_path_widget"] = { + Name = [[executable_path_widget]], + Synopsis = [[create a widget to get executable path preferences]], + Usage = [[local df = require "lib/dtutils.file" + + local widget = df.executable_path_widget(executables) + executables - table - a table of strings that are executable names]], + Description = [[executable_path_widget takes a table of executable names + and builds a set of file selector widgets to get the path to the executable. + The resulting widgets are wrapped in a box widget and returned.]], + Return_Value = [[widget - widget - a widget containing a file selector widget for + each executable.]], + Limitations = [[]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_file.executable_path_widget(executables) + local box_widgets = {} + table.insert(box_widgets, dt.new_widget("section_label"){label = "select executable(s)"}) + for _, executable in pairs(executables) do + table.insert(box_widgets, dt.new_widget("label"){label = "select " .. executable .. " executable"}) + local path = dtutils_file.get_executable_path_preference(executable) + if not path then + path = "" + end + table.insert(box_widgets, dt.new_widget("file_chooser_button"){ + title = "select " .. executable .. " executable", + value = path, + is_directory = false, + changed_callback = function(self) + if dtutils_file.check_if_bin_exists(self.value) then + dtutils_file.set_executable_path_preference(executable, self.value) + end + end} + ) + end + local box = dt.new_widget("box"){ + orientation = "vertical", + table.unpack(box_widgets) + } + return box +end + return dtutils_file \ No newline at end of file From c073ecf0dd10f05b26b904e2d56d22e8fa845126 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Sat, 3 Mar 2018 20:22:47 -0500 Subject: [PATCH 263/865] Added check_os to lib/dtutils.lua so that scripts can check compatibility with the current operating system --- lib/dtutils.lua | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/dtutils.lua b/lib/dtutils.lua index 02888a8e..abe51d64 100644 --- a/lib/dtutils.lua +++ b/lib/dtutils.lua @@ -32,7 +32,7 @@ local dt = require "darktable" local log = require "lib/dtutils.log" -dt.configuration.check_version(...,{3,0,0},{4,0,0},{5,0,0}) +dt.configuration.check_version(...,{5,0,0}) dtutils.libdoc.functions["split"] = { Name = [[split]], @@ -215,4 +215,37 @@ function dtutils.spairs(_table, order) -- Code copied from http://stackoverflow. end end +dtutils.libdoc.functions["check_os"] = { + Name = [[check_os]], + Synopsis = [[check that the operating system is supported]], + Usage = [[local du = require "lib/dtutils" + + local result = du.check_os(operating_systems) + operating_systems - a table of operating system names such as {"windows","linux","macos","unix"}]], + Description = [[check_os checks a supplied table of operating systems against the operating system the + script is running on and returns true if the OS is in the list, otherwise false]], + Return_Value = [[result - boolean - true if the operating system is supported, false if not.]], + Limitations = [[]], + Example = [[local du = require "lib/dtutils" + if du.check_os({"windows"}) then + -- run the script + else + dt.print("Script