Skip to content

Commit 4d54b5e

Browse files
authored
Merge pull request #606 from wpferguson/add_official_regenerate_thumbnails
official/regenerate_thumbnails - add a script to fix skull thumbnails
2 parents 447980d + dbf0c5d commit 4d54b5e

File tree

1 file changed

+267
-0
lines changed

1 file changed

+267
-0
lines changed

official/regenerate_thumbnails.lua

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
--[[
2+
3+
regenerate_thumbnails.lua - regenerate mipmap cache for selected images
4+
5+
Copyright (C) 2025 Bill Ferguson <wpferguson@gmail.com>.
6+
7+
This program is free software: you can redistribute it and/or modify
8+
it under the terms of the GNU General Public License as published by
9+
the Free Software Foundation; either version 3 of the License, or
10+
(at your option) any later version.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
]]
20+
--[[
21+
regenerate_thumbnails - regenerate mipmap cache for selected images
22+
23+
regenerate_thumbnails drops the cached thumbnail for each selected image
24+
and generates a new thumbnail.
25+
26+
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
27+
None
28+
29+
USAGE
30+
* enable the script in script_manager
31+
* assign a shortcut, if desired, to apply the script by hovering
32+
over a skull and using the shortcut to regenerate the thumbnail
33+
34+
BUGS, COMMENTS, SUGGESTIONS
35+
Bill Ferguson <wpferguson@gmail.com>
36+
37+
CHANGES
38+
]]
39+
40+
local dt = require "darktable"
41+
local du = require "lib/dtutils"
42+
-- local df = require "lib/dtutils.file"
43+
-- local ds = require "lib/dtutils.string"
44+
-- local dtsys = require "lib/dtutils.system"
45+
local log = require "lib/dtutils.log"
46+
-- local debug = require "darktable.debug"
47+
48+
49+
-- - - - - - - - - - - - - - - - - - - - - - - -
50+
-- A P I C H E C K
51+
-- - - - - - - - - - - - - - - - - - - - - - - -
52+
53+
du.check_min_api_version("7.0.0", MODULE) -- choose the minimum version that contains the features you need
54+
55+
56+
-- - - - - - - - - - - - - - - - - - - - - - - - - -
57+
-- I 1 8 N
58+
-- - - - - - - - - - - - - - - - - - - - - - - - - -
59+
60+
local gettext = dt.gettext.gettext
61+
62+
local function _(msgid)
63+
return gettext(msgid)
64+
end
65+
66+
67+
-- - - - - - - - - - - - - - - - - - - - - - - - - -
68+
-- S C R I P T M A N A G E R I N T E G R A T I O N
69+
-- - - - - - - - - - - - - - - - - - - - - - - - - -
70+
71+
local script_data = {}
72+
73+
script_data.destroy = nil -- function to destory the script
74+
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet
75+
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
76+
script_data.show = nil -- only required for libs since the destroy_method only hides them
77+
78+
script_data.metadata = {
79+
name = _("regenerate_thumbnails"), -- visible name of script
80+
purpose = _("regenerate mipmap cache for selected images"), -- purpose of script
81+
author = "Bill Ferguson <wpferguson@gmail.com>", -- your name and optionally e-mail address
82+
help = "https://docs.darktable.org/lua/development/lua.scripts.manual/scripts/official/regenerate_thumbnails" -- URL to help/documentation
83+
}
84+
85+
86+
-- - - - - - - - - - - - - - - - - - - - - - - -
87+
-- C O N S T A N T S
88+
-- - - - - - - - - - - - - - - - - - - - - - - -
89+
90+
local MODULE <const> = "regenerate_thumbnails"
91+
local DEFAULT_LOG_LEVEL <const> = log.info
92+
local TMP_DIR <const> = dt.configuration.tmp_dir
93+
94+
-- path separator
95+
local PS <const> = dt.configuration.running_os == "windows" and "\\" or "/"
96+
97+
-- command separator
98+
local CS <const> = dt.configuration.running_os == "windows" and "&" or ";"
99+
100+
-- - - - - - - - - - - - - - - - - - - - - - - -
101+
-- L O G L E V E L
102+
-- - - - - - - - - - - - - - - - - - - - - - - -
103+
104+
log.log_level(DEFAULT_LOG_LEVEL)
105+
106+
-- - - - - - - - - - - - - - - - - - - - - - - -
107+
-- N A M E S P A C E
108+
-- - - - - - - - - - - - - - - - - - - - - - - -
109+
110+
local regenerate_thumbnails = {}
111+
112+
-- - - - - - - - - - - - - - - - - - - - - - - -
113+
-- G L O B A L V A R I A B L E S
114+
-- - - - - - - - - - - - - - - - - - - - - - - -
115+
116+
-- - - - - - - - - - - - - - - - - - - - - - - -
117+
-- P R E F E R E N C E S
118+
-- - - - - - - - - - - - - - - - - - - - - - - -
119+
120+
-- - - - - - - - - - - - - - - - - - - - - - - -
121+
-- A L I A S E S
122+
-- - - - - - - - - - - - - - - - - - - - - - - -
123+
124+
local namespace = regenerate_thumbnails
125+
local rt = regenerate_thumbnails
126+
127+
-- - - - - - - - - - - - - - - - - - - - - - - -
128+
-- F U N C T I O N S
129+
-- - - - - - - - - - - - - - - - - - - - - - - -
130+
131+
-------------------
132+
-- helper functions
133+
-------------------
134+
135+
local function set_log_level(level)
136+
local old_log_level = log.log_level()
137+
log.log_level(level)
138+
return old_log_level
139+
end
140+
141+
local function restore_log_level(level)
142+
log.log_level(level)
143+
end
144+
145+
local function pref_read(name, pref_type)
146+
local old_log_level = set_log_level(sm.log_level)
147+
148+
log.msg(log.debug, "name is " .. name .. " and type is " .. pref_type)
149+
150+
local val = dt.preferences.read(MODULE, name, pref_type)
151+
152+
log.msg(log.debug, "read value " .. tostring(val))
153+
154+
restore_log_level(old_log_level)
155+
return val
156+
end
157+
158+
local function pref_write(name, pref_type, value)
159+
local old_log_level = set_log_level(sm.log_level)
160+
161+
log.msg(log.debug, "writing value " .. tostring(value) .. " for name " .. name)
162+
163+
dt.preferences.write(MODULE, name, pref_type, value)
164+
165+
restore_log_level(old_log_level)
166+
end
167+
168+
local function stop_job()
169+
rt.job.valid = false
170+
end
171+
172+
local function generate_thumbnails(images)
173+
local has_job = false
174+
175+
if #images > 50 then
176+
rt.job = dt.gui.create_job("regenerating thumbnails", true, stop_job)
177+
has_job = true
178+
end
179+
180+
for count, image in ipairs(images) do
181+
image:drop_cache()
182+
image:generate_cache(true, 1, 3)
183+
if has_job then
184+
if not rt.job.valid then
185+
return
186+
end
187+
if count % 10 == 0 then
188+
rt.job.percent = count / #images
189+
end
190+
end
191+
end
192+
if has_job then
193+
rt.job.valid = false
194+
end
195+
end
196+
197+
local function update_button_sensitivity()
198+
if #dt.gui.action_images > 0 then
199+
dt.gui.libs.image.set_sensitive(MODULE, true)
200+
else
201+
dt.gui.libs.image.set_sensitive(MODULE, false)
202+
end
203+
end
204+
205+
-- - - - - - - - - - - - - - - - - - - - - - - -
206+
-- M A I N P R O G R A M
207+
-- - - - - - - - - - - - - - - - - - - - - - - -
208+
209+
-- - - - - - - - - - - - - - - - - - - - - - - -
210+
-- U S E R I N T E R F A C E
211+
-- - - - - - - - - - - - - - - - - - - - - - - -
212+
213+
dt.gui.libs.image.register_action(
214+
MODULE,
215+
_("generate thumbnails"),
216+
function(event, images)
217+
generate_thumbnails(images)
218+
end,
219+
_("generate thumbnails")
220+
)
221+
222+
update_button_sensitivity()
223+
224+
-- - - - - - - - - - - - - - - - - - - - - - - -
225+
-- D A R K T A B L E I N T E G R A T I O N
226+
-- - - - - - - - - - - - - - - - - - - - - - - -
227+
228+
local function destroy()
229+
dt.destroy_event(MODULE, "selection-changed")
230+
dt.destroy_event(MODULE, "mouse-over-image-changed")
231+
dt.gui.libs.image.destroy_action(MODULE, "regenerate thumbnails")
232+
end
233+
234+
script_data.destroy = destroy
235+
236+
-- - - - - - - - - - - - - - - - - - - - - - - -
237+
-- E V E N T S
238+
-- - - - - - - - - - - - - - - - - - - - - - - -
239+
240+
dt.register_event(MODULE, "shortcut",
241+
function(event, shortcut)
242+
local images = dt.gui.action_images
243+
if images then
244+
generate_thumbnails(images)
245+
end
246+
end, "regenerate thumbnails"
247+
)
248+
249+
dt.register_event(MODULE, "selection-changed",
250+
function(event)
251+
update_button_sensitivity()
252+
end
253+
)
254+
255+
dt.register_event(MODULE, "mouse-over-image-changed",
256+
function(event, image)
257+
if #dt.gui.selection() < 1 then
258+
if image then
259+
dt.gui.libs.image.set_sensitive(MODULE, true)
260+
else
261+
dt.gui.libs.image.set_sensitive(MODULE, false)
262+
end
263+
end
264+
end
265+
)
266+
267+
return script_data

0 commit comments

Comments
 (0)