-- Fork of the autogroup plugin but only comparing pictures with the same timestamp local dt = require "darktable" local du = require "lib/dtutils" local df = require "lib/dtutils.file" du.check_min_api_version("7.0.0", "AutoGroupInstant") local MOD = 'autogroupinstant' -- return data structure for script_manager local script_data = {} script_data.destroy = nil -- function to destory the script script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again script_data.show = nil -- only required for libs since the destroy_method only hides them local gettext = dt.gettext -- Tell gettext where to find the .mo file translating messages for a particular domain gettext.bindtextdomain("AutoGroupInstant",dt.configuration.config_dir.."/lua/locale/") local function _(msgid) return gettext.dgettext("AutoGroupInstant", msgid) end local Ag = {} Ag.module_installed = false Ag.event_registered = false local GUI = { gap = {}, selected = {}, collection = {} } 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 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 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} 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) 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 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 local curr_image = image if GetTimeDiff(curr_image, prev_image) == 0 then images[i]:group_with(images[i-1]) for _, member in ipairs(images[i]:get_group_members()) do local ext = string.lower(df.get_filetype(member.filename)) if ext == "rw2" or ext == "arw" then member:make_group_leader() end end end prev_image = curr_image end end end local function install_module() if not Ag.module_installed then dt.print_log("installing module") dt.register_lib( MOD, -- Module name _('Group identical Timestamps'), -- name true, -- expandable true, -- resetable {[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 99}}, -- containers dt.new_widget("box"){ orientation = "vertical", GUI.selected, GUI.collection } ) Ag.module_installed = true dt.print_log("module installed") dt.print_log("styles module visibility is " .. tostring(dt.gui.libs["styles"].visible)) end end local function destroy() dt.gui.libs[MOD].visible = false end local function restart() dt.gui.libs[MOD].visible = true end -- GUI -- GUI.selected = dt.new_widget("button"){ 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 } if dt.gui.current_view().id == "lighttable" then install_module() else if not Ag.event_registered then dt.register_event( "AutoGroupInstant", "view-changed", function(event, old_view, new_view) if new_view.name == "lighttable" and old_view.name == "darkroom" then install_module() end end ) Ag.event_registered = true end end script_data.destroy = destroy script_data.destroy_method = "hide" script_data.restart = restart script_data.show = restart return script_data