--[[ Export image for blog, duplicate and set it LOCKED ]] local script_path = debug.getinfo(1, "S").source:sub(2):match("(.*/)") package.path = script_path .. "?.lua;" .. package.path local config = require("config") email_1 = config.email_1 email_2 = config.email_2 email_3 = config.email_3 local image_max_x = 2500 local image_max_y = 2500 -- local jpg_quality_str = '92' -- module name local MODULE_NAME = "mail2blog" local df = require "lib/dtutils.file" local dt = require "darktable" local du = require "lib/dtutils" local log = require 'lib/dtutils.log' local dtsys = require "lib/dtutils.system" local cjson = require "cjson" local function quote(text) return '"' .. text .. '"' end local charset = {} do -- [0-9a-zA-Z] for c = 48, 57 do table.insert(charset, string.char(c)) end for c = 65, 90 do table.insert(charset, string.char(c)) end for c = 97, 122 do table.insert(charset, string.char(c)) end end -- - - - - - - - - - - - - - - - - - - - - - - - -- V E R S I O N C H E C K -- - - - - - - - - - - - - - - - - - - - - - - - du.check_min_api_version("5.0.2", MODULE_NAME) -- darktable 3.0 -- script_manager integration to allow a script to be removed -- without restarting darktable local function destroy() -- nothing to destroy end -- - - - - - - - - - - - - - - - - - - - - - - - -- C O N S T A N T S -- - - - - - - - - - - - - - - - - - - - - - - - local PS = dt.configuration.running_os == "windows" and "\\" or "/" -- - - - - - - - - - - - - - - - - - - - - - - - -- T R A N S L A T I O N S -- - - - - - - - - - - - - - - - - - - - - - - - local gettext = dt.gettext gettext.bindtextdomain(MODULE_NAME, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS) local function _(msgid) return gettext.dgettext(MODULE_NAME, msgid) end -- - - - - - - - - - - - - - - - - - - - - - - - -- M A I N -- - - - - - - - - - - - - - - - - - - - - - - - -- alias dt.control.sleep to sleep local sleep = dt.control.sleep --------------------------------------------------------------- -- some helper methods to log information messages log.log_level(log.info) -- log.info or log.warn or log.debug local LogCurrentStep = '' local LogMajorNr = 0 local LogMajorMax = 0 local LogSummaryMessages = {} local function GetLogInfoText(text) return '[' .. LogMajorNr .. '/' .. LogMajorMax .. '] ' .. LogCurrentStep .. ': ' .. text end local function LogInfo(text) log.msg(log.info, GetLogInfoText(text)) end local function LogScreen(text) log.msg(log.screen, text) end local function LogSummaryClear() for k, v in pairs(LogSummaryMessages) do LogSummaryMessages[k] = nil end end local function LogSummaryMessage(text) table.insert(LogSummaryMessages, GetLogInfoText(text)) end -- ---------------------------------------------------- local function set_published_tag ( email, image ) if email == 'postie_markus_spring.info@markus-spring.de' then local tagnr = dt.tags.find('photography|published|blog') dt.tags.attach(tagnr,image) elseif email == 'postie_vhs_fotogruppe_reichenhall@markus-spring.de' then local tagnr = dt.tags.find('photography|published|vhs-fotogruppe') dt.tags.attach(tagnr,image) -- else -- local tagnr = dt.tags.find('photography|published|instagram') -- dt.tags.attach(tagnr,image) end local tagnr = dt.tags.find('LOCKED') dt.tags.attach(tagnr,image) end local function getPureFilename(path) return string.match(path, "([^/\\]+)$") end local function set_metadata_note ( tmp_exported, image ) if image then local current_notes = image.notes or "" -- Retrieve existing notes or set as empty if current_notes ~= "" then current_notes = current_notes .. "; " end image.notes = current_notes .. 'published as ' .. getPureFilename(tmp_exported) end end local function set_rating_min_2 ( image ) if image.rating < 2 then image.rating = 2 end end local function get_executable( binaryname, binarystring ) local binary = dt.preferences.read(MODULE_NAME, binaryname, "string") if binary == "" then dt.print(_( binarystring .. " executable not configured")) return end binary = df.sanitize_filename(binary) return binary end local function run_exiftool ( file, tmp_exported, flags ) local exiftoolbinary = get_executable("exiftoolbinary", "exiftool") run_cmd = exiftoolbinary..' -TagsFromFile '..file..' '..flags..' '..tmp_exported -- LogInfo(string.format("Running %s", run_cmd)) local job = dt.gui.create_job(string.format("Running %s", run_cmd), true, stop_job) resp = dtsys.external_command(run_cmd) job.valid = false end local function isempty(s) return s == nil or s == '' end local function remove_unneeded_exif_values ( jpeg_file ) local tags_to_remove = { "ModifyDate", "DateTimeOriginal", "CreateDate", "DateCreated", "TimeCreated", "GPSTimeStamp", "GPSDateStamp", "GPSDateTime", "IFD0:*", "IFD1:*" } local args = {"-overwrite_original"} for _, tag in ipairs(tags_to_remove) do table.insert(args, "-" .. tag .. "=") end -- table.insert(args, "-FileModifyDateOSM)#", platz or "", ort or "", lat or "", lon or "", lat or "", lon or "" ) -- Generate tags, extract the last part of each string and format it local function subject_tags(t) local result = {} for _, str in ipairs(t) do -- Find the last part of the string after the last '|' local lastPart = str:match(".*|([^|]+)$") -- Add it to the result table, wrapped in brackets table.insert(result, "[" .. lastPart .. "]") end -- Concatenate all elements into a single string return table.concat(result, " ") end tags = subject_tags(h_subject_list) title = tags .. " " .. title return filtered_subject, title, caption end local publication_button = dt.new_widget("button") { label = "Publish!", clicked_callback = function () for i_, i in ipairs(dt.gui.action_images) do if isempty(i.title) then local job = dt.gui.create_job("FEHLER: Das Bild " .. i.filename .. " hat keinen Titel.", true, stop_job) os.execute("sleep " .. 3) job.valid = false else set_rating_min_2( i ) -- create duplicate local newimg = i.duplicate_with_history(i) local jpeg_exporter = dt.new_format("jpeg") jpeg_exporter.max_height = image_max_y jpeg_exporter.max_width = image_max_x -- local tmp_exported = os.tmpname()..".jpg" local tempname = os.tmpname() os.remove(tempname) os.execute("mkdir " .. tempname) local tmp_exported = tempname .. '/' .. create_safe_filename(i.title) .. '.jpg' local job = dt.gui.create_job(string.format(_("Converting raw file '%s' to jpeg..."), i.filename), true, stop_job) jpeg_exporter:write_image(i, tmp_exported, false) -- copy exif data from original file run_exiftool( df.sanitize_filename(i.path..PS..i.filename), tmp_exported, '-exif:all --subifd:all --Orientation -overwrite_original' ) -- copy exif data from xmp file run_exiftool( df.sanitize_filename(i.sidecar) , tmp_exported, '-xmp:all -exif:all --subifd:all -overwrite_original' ) local h_subject, title, caption = process_image(tmp_exported) remove_unneeded_exif_values(tmp_exported) run_cmd = "thunderbird -compose \"to=".. select_publication_target.value ..",subject='" .. title .."',body='" .. caption .. "',attachment='file://" .. tmp_exported .."'\"" job = false local job = dt.gui.create_job("Running " .. run_cmd, true, stop_job) os.execute(run_cmd) set_published_tag ( select_publication_target.value, i ) job = false set_metadata_note ( tmp_exported, i ) LogScreen("Done") end end end } local lib_widgets = {} table.insert(lib_widgets, select_publication_target) table.insert(lib_widgets, publication_button) -- ... and tell dt about it all dt.register_lib( MODULE_NAME, -- plugin name MODULE_NAME, -- name true, -- expandable false, -- resetable {[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100}}, -- containers dt.new_widget("box") -- widget { orientation = "vertical", -- sensitive = enfuse_installed, table.unpack(lib_widgets) }, nil,-- view_enter nil -- view_leave ) -- end -- -- register the new preferences ----------------------------------------------- dt.preferences.register(MODULE_NAME, "exiftoolbinary", "file", _(MODULE_NAME .. ": executable for exiftool"), _("select executable for exiftool command line version") , "") dt.preferences.register(MODULE_NAME, "spring2lifescript", "file", _(MODULE_NAME .. ": executable for mail2spring2life script"), _("select executable for mail2spring2life script") , "") -- ---------------------------------------------------------------------------------- -- set the destroy routine so that script_manager can call it when -- it's time to destroy the script and then return the data to -- script_manager local script_data = {} script_data.destroy = destroy return script_data