Skip to content

Commit dac6e5f

Browse files
committed
new plugin: harmonize group ratings
This allows one to process a subset of a library, find and fix images that are in a group but don't share the same rating. This is a draft. It still needs a usage, some better docs, and a thorough review. Rationale in: https://discuss.pixls.us/t/batch-copying-ratings-in-group/48874
1 parent a9191cf commit dac6e5f

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

contrib/harmonize_group_rating.lua

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
--[[
2+
Harmonize group rating:
3+
4+
Copy the rating among a group of images. Run darktable with `-d
5+
lua` to log modified images.
6+
7+
Installation: deploy in ~/.config/darktable/lua. Set a keybinding
8+
(e.g. "shift f").
9+
10+
Usage: select images without ratings you suspect should have
11+
some. Hit the keybinding, wait for the processing to complete. It
12+
should show a message at the start and end of the processing,
13+
including how many images were rated.
14+
15+
Author: anarcat
16+
License: GPLv2
17+
18+
--]]
19+
20+
local dt = require "darktable"
21+
local du = require "lib/dtutils"
22+
23+
local _ = dt.gettext.gettext
24+
25+
-- not sure we need this
26+
du.check_min_api_version("7.0.0", "harmonize_group_rating")
27+
28+
local script_data = {}
29+
30+
script_data.metadata = {
31+
name = _("harmonize group rating"),
32+
purpose = _("copy rating within a group"),
33+
author = "anarcat",
34+
help = "TODO"
35+
}
36+
37+
script_data.destroy = nil -- function to destory the script
38+
script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
39+
script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
40+
script_data.show = nil -- only required for libs since the destroy_method only hides them
41+
42+
local function harmonize_rating(shortcut)
43+
local images = dt.gui.action_images
44+
dt.print_log("harmonizing ratings on " .. #images .. " selected images...")
45+
dt.print("harmonizing ratings on " .. #images .. " selected images...")
46+
local modified = 0
47+
local singles = 0
48+
local unrated_groups = 0
49+
local modified_groups = 0
50+
local rated_groups = 0
51+
for _, img in ipairs(images) do
52+
-- image rating is -1 for rejected or 1-5. zero is unset.
53+
local rating = 0
54+
local missing = 0
55+
local members = img:get_group_members()
56+
if #members <= 1 then
57+
dt.print_log("skipping single image " .. img.id .. " path " .. img.filename)
58+
singles = singles + 1
59+
else
60+
dt.print_log("checking image " .. img.id .. " named " .. img.filename .. " member count: " .. #members)
61+
for _, member in ipairs(members) do
62+
dt.print_log("member " .. member.id .. " path " .. member.filename .. " rating " .. member.rating)
63+
if (member.rating ~= 0) then
64+
if rating == 0 then
65+
-- only record rating if not already set
66+
rating = member.rating
67+
end
68+
else
69+
missing = missing + 1
70+
end
71+
end
72+
if rating == 0 then
73+
unrated_groups = unrated_groups + 1
74+
dt.print_log("no rating found in group, skipping")
75+
elseif missing > 0 then
76+
modified_groups = modified_groups + 1
77+
dt.print_log("rating found in group, missing from " .. missing .. " image, fixing")
78+
for _, member in ipairs(members) do
79+
if member.rating == 0 then
80+
dt.print_log("applying rating " .. rating .. " to image " .. member.id .. " in " .. img.filename .. ", previously: " .. member.rating)
81+
member.rating = rating
82+
modified = modified + 1
83+
end
84+
end
85+
else
86+
rated_groups = rated_groups + 1
87+
dt.print_log("all members rated in group, skipping")
88+
end
89+
end
90+
end
91+
dt.print("processed " .. #images .. " images, modified ratings on " .. modified)
92+
dt.print_log("processed " .. #images .. " images, modified ratings on " .. modified)
93+
dt.print_log("modified groups: " .. modified_groups)
94+
dt.print_log("singles (skipped): " .. singles)
95+
dt.print_log("unrated groups (skipped): " .. unrated_groups)
96+
dt.print_log("fully rated groups (skipped): " .. rated_groups)
97+
end
98+
99+
local function destroy()
100+
dt.destroy_event("hgr_harmonize", "shortcut")
101+
end
102+
103+
dt.register_event("hgr_harmonize", "shortcut", harmonize_rating, "harmonize group rating")
104+
105+
dt.print_log("harmonize_group_rating loaded")
106+
107+
script_data.destroy = destroy
108+
109+
return script_data

0 commit comments

Comments
 (0)