diff --git a/contrib/AutoGrouper.lua b/contrib/AutoGrouper.lua index 3125363..0d92915 100644 --- a/contrib/AutoGrouper.lua +++ b/contrib/AutoGrouper.lua @@ -37,7 +37,7 @@ selected images, the other button performs grouping on the entire active collect ]] local dt = require "darktable" -local mod = 'autogroup' +local MOD = 'autogrouper' local gettext = dt.gettext -- Tell gettext where to find the .mo file translating messages for a particular domain gettext.bindtextdomain("AutoGrouper",dt.configuration.config_dir.."/lua/locale/") @@ -46,110 +46,113 @@ local function _(msgid) end local function InRange(test, low, high) --tests if test value is within range of low and high (inclusive) - if test >= low and test <= high then - return true - else - return false - end + if test >= low and test <= high then + return true + else + return false + end end local function CompTime(first, second) --compares the timestamps and returns true if first was taken before second - first_time = first.exif_datetime_taken - if string.match(first_time, '[0-9]') == nil then first_time = '9999:99:99 99:99:99' end - first_time = tonumber(string.gsub(first_time, '[^0-9]*','')) - second_time = second.exif_datetime_taken - if string.match(second_time, '[0-9]') == nil then second_time = '9999:99:99 99:99:99' end - second_time = tonumber(string.gsub(second_time, '[^0-9]*','')) - return first_time < second_time + first_time = first.exif_datetime_taken + if string.match(first_time, '[0-9]') == nil then first_time = '9999:99:99 99:99:99' end + first_time = tonumber(string.gsub(first_time, '[^0-9]*','')) + second_time = second.exif_datetime_taken + if string.match(second_time, '[0-9]') == nil then second_time = '9999:99:99 99:99:99' end + second_time = tonumber(string.gsub(second_time, '[^0-9]*','')) + return first_time < second_time end local function SeperateTime(str) --seperates the timestamp into individual components for used with OS.time operations - local cleaned = string.gsub(str, '[^%d]',':') - cleaned = string.gsub(cleaned, '::*',':') --YYYY:MM:DD:hh:mm:ss - local year = string.sub(cleaned,1,4) - local month = string.sub(cleaned,6,7) - local day = string.sub(cleaned,9,10) - local hour = string.sub(cleaned,12,13) - local min = string.sub(cleaned,15,16) - local sec = string.sub(cleaned,18,19) - return {year = year, month = month, day = day, hour = hour, min = min, sec = sec} + local cleaned = string.gsub(str, '[^%d]',':') + cleaned = string.gsub(cleaned, '::*',':') --YYYY:MM:DD:hh:mm:ss + local year = string.sub(cleaned,1,4) + local month = string.sub(cleaned,6,7) + local day = string.sub(cleaned,9,10) + local hour = string.sub(cleaned,12,13) + local min = string.sub(cleaned,15,16) + local sec = string.sub(cleaned,18,19) + return {year = year, month = month, day = day, hour = hour, min = min, sec = sec} end local function GetTimeDiff(curr_image, prev_image) --returns the time difference (in sec.) from current image and the previous image - local curr_time = SeperateTime(curr_image.exif_datetime_taken) - local prev_time = SeperateTime(prev_image.exif_datetime_taken) - return os.time(curr_time)-os.time(prev_time) + local curr_time = SeperateTime(curr_image.exif_datetime_taken) + local prev_time = SeperateTime(prev_image.exif_datetime_taken) + return os.time(curr_time)-os.time(prev_time) end local function main(on_collection) - local images = {} - if on_collection then - local col_images = dt.collection - for i,image in ipairs(col_images) do --copy images to a standard table, table.sort barfs on type dt_lua_singleton_image_collection - table.insert(images,i,image) - end - else - images = dt.gui.selection() - end - dt.preferences.write(mod, 'active_gap', 'integer', GUI.gap.value) - if #images < 2 then return end - table.sort(images, function(first, second) return CompTime(first,second) end) --sort images by timestamp - - for i, image in ipairs(images) do - if i == 1 then - prev_image = image - elseif string.match(image.exif_datetime_taken, '[%d]') ~= nil then --make sure current image has a timestamp, if so check if it is within the user specified gap value and add to group - local curr_image = image - if GetTimeDiff(curr_image, prev_image) <= GUI.gap.value then - images[i]:group_with(images[i-1]) - end - prev_image = curr_image - end - end + local images = {} + if on_collection then + local col_images = dt.collection + for i,image in ipairs(col_images) do --copy images to a standard table, table.sort barfs on type dt_lua_singleton_image_collection + table.insert(images,i,image) + end + else + images = dt.gui.selection() + end + dt.preferences.write(MOD, 'active_gap', 'integer', GUI.gap.value) + if #images < 2 then + dt.print('please select at least 2 images') + return + end + table.sort(images, function(first, second) return CompTime(first,second) end) --sort images by timestamp + + for i, image in ipairs(images) do + if i == 1 then + prev_image = image + elseif string.match(image.exif_datetime_taken, '[%d]') ~= nil then --make sure current image has a timestamp, if so check if it is within the user specified gap value and add to group + local curr_image = image + if GetTimeDiff(curr_image, prev_image) <= GUI.gap.value then + images[i]:group_with(images[i-1]) + end + prev_image = curr_image + end + end end -- GUI -- GUI = { - gap = {}, - selected = {}, - collection = {} + gap = {}, + selected = {}, + collection = {} } -temp = dt.preferences.read(mod, 'active_gap', 'integer') -if not InRange(temp, 1, 3600) then temp = 3 end +temp = dt.preferences.read(MOD, 'active_gap', 'integer') +if not InRange(temp, 1, 86400) then temp = 3 end GUI.gap = dt.new_widget('slider'){ - label = _('group gap [sec.]'), - tooltip = _('minimum gap, in seconds, between groups'), - soft_min = 1, - soft_max = 30, - hard_min = 1, - hard_max = 3600, - step = 1, - digits = 0, - value = temp, - reset_callback = function(self) - self.value = 3 - end + label = _('group gap [sec.]'), + tooltip = _('minimum gap, in seconds, between groups'), + soft_min = 1, + soft_max = 60, + hard_min = 1, + hard_max = 86400, + step = 1, + digits = 0, + value = temp, + reset_callback = function(self) + self.value = 3 + end } GUI.selected = dt.new_widget("button"){ - label = _('auto group: selected'), - tooltip =_('auto group selected images'), - clicked_callback = function() main(false) end + label = _('auto group: selected'), + tooltip =_('auto group selected images'), + clicked_callback = function() main(false) end } GUI.collection = dt.new_widget("button"){ - label = _('auto group: collection'), - tooltip =_('auto group the entire collection'), - clicked_callback = function() main(true) end + label = _('auto group: collection'), + tooltip =_('auto group the entire collection'), + clicked_callback = function() main(true) end } dt.register_lib( - "AutoGroup_Lib", -- Module name - _("Auto Group"), -- name - true, -- expandable - true, -- resetable - {[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 99}}, -- containers - dt.new_widget("box"){ - orientation = "vertical", - GUI.gap, - GUI.selected, - GUI.collection - } + 'AutoGroup_Lib', -- Module name + _('auto group'), -- name + true, -- expandable + true, -- resetable + {[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 99}}, -- containers + dt.new_widget("box"){ + orientation = "vertical", + GUI.gap, + GUI.selected, + GUI.collection + } )