export_to_lightgallery.lua 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. local dt = require "darktable"
  2. local du = require "lib/dtutils"
  3. du.check_min_api_version("7.0.0", "lightgallery_export_module")
  4. local gettext = dt.gettext.gettext
  5. local function _(msgid)
  6. return gettext(msgid)
  7. end
  8. local script_data = {}
  9. script_data.metadata = {
  10. name = "lightgallery_export_module",
  11. purpose = _("Export selected files into a directory and call a python script to create a lightGallery"),
  12. author = "Markus Spring",
  13. help = "https://gogs.hermes.markus-spring.info/springm/darktable_to_lightgallery"
  14. }
  15. -- local variables
  16. local help_url = "https://gogs.hermes.markus-spring.info/springm/darktable_to_lightgallery"
  17. local du = require "lib/dtutils"
  18. local df = require "lib/dtutils.file"
  19. local dtsys = require "lib/dtutils.system"
  20. local debug = require "darktable.debug"
  21. local image_max_xy = 2500
  22. local jpg_quality_str = '92'
  23. local PS = dt.configuration.running_os == "windows" and "\\" or "/"
  24. script_data.destroy = nil -- function to destory the script
  25. script_data.destroy_method = nil -- set to hide for libs since we can't destroy them commpletely yet, otherwise leave as nil
  26. script_data.restart = nil -- how to restart the (lib) script after it's been hidden - i.e. make it visible again
  27. -- Register preferences
  28. dt.preferences.register("lightgallery_export", "export_path", "string",
  29. "LightGallery Export Path", "Path to export lightGallery", "")
  30. dt.preferences.register("lightgallery_export", "gallery_title", "string",
  31. "LightGallery Title", "Title for the lightGallery", "--..--")
  32. dt.preferences.register("lightgallery_export", "gallery_uplink", "string",
  33. "LightGallery Uplink", "Uplink for lightGallery index.html", "..")
  34. -- dt.preferences.register("lightgallery_export", "gallery_family_tags", "bool", "LightGallery attach published..family tag", "attach published..family tag", false)
  35. dt.preferences.register("lightgallery_export", "gallery_tag", "string",
  36. "LightGallery attach published|gallery|<name> tag", "attach published|gallery|<name> tag", "family")
  37. dt.preferences.register("lightgallery_export", "exiftoolbinary", "file",
  38. _("lightGallery: executable for exiftool"),
  39. _("select executable for exiftool command line version") , "")
  40. dt.preferences.register("lightgallery_export", "post_export_script", "file",
  41. _("lightGallery: select script to run after image export"),
  42. _("select script to run after image export") , "")
  43. function mws_basename(str)
  44. local name = string.gsub(str, "(.*)%..*", "%1")
  45. return name
  46. end
  47. function exists(name)
  48. if type(name)~="string" then return false end
  49. return os.rename(name,name) and true or false
  50. end
  51. function isFile(name)
  52. if type(name)~="string" then return false end
  53. if not exists(name) then return false end
  54. local f = io.open(name)
  55. if f then
  56. f:close()
  57. return true
  58. end
  59. return false
  60. end
  61. function isDir(name)
  62. return (exists(name) and not isFile(name))
  63. end
  64. local export_path_widget = dt.new_widget("file_chooser_button") {
  65. title = "Select export path",
  66. is_directory = true,
  67. tooltip = "Choose the directory where to export the images for the lightGallery",
  68. value = dt.preferences.read("lightgallery_export", "export_path", "string")
  69. }
  70. local export_path_widget_box = dt.new_widget("box") {
  71. orientation = "horizontal",
  72. dt.new_widget("label") {
  73. label = "Verzeichnis: "
  74. },
  75. export_path_widget
  76. }
  77. local gallery_title_widget = dt.new_widget("entry") {
  78. text = dt.preferences.read("lightgallery_export", "gallery_title", "string"),
  79. tooltip = "Enter the title for the lightGallery"
  80. }
  81. local gallery_title_widget_box = dt.new_widget("box") {
  82. orientation = "horizontal",
  83. dt.new_widget("label") {
  84. label = "Titel: "
  85. },
  86. gallery_title_widget
  87. }
  88. local gallery_uplink_widget = dt.new_widget("entry") {
  89. text = dt.preferences.read("lightgallery_uplink", "gallery_uplink", "string"),
  90. tooltip = "Uplink for the lightGallery index.html"
  91. }
  92. local gallery_uplink_widget_box = dt.new_widget("box") {
  93. orientation = "horizontal",
  94. dt.new_widget("label") {
  95. label = "Uplink: "
  96. },
  97. gallery_uplink_widget
  98. }
  99. local gallery_tag_widget = dt.new_widget("entry") {
  100. text = dt.preferences.read("lightgallery_export", "gallery_tag", "string")
  101. }
  102. local gallery_tag_widget_box = dt.new_widget("box") {
  103. orientation = "horizontal",
  104. dt.new_widget("label") {
  105. label = "photography|published|gallery Tag: "
  106. },
  107. gallery_tag_widget
  108. }
  109. -- Function to save preferences
  110. local function save_preferences()
  111. dt.preferences.write("lightgallery_export", "export_path", "string", export_path_widget.value)
  112. dt.preferences.write("lightgallery_export", "gallery_title", "string", gallery_title_widget.text)
  113. dt.preferences.write("lightgallery_export", "lightgallery_uplink", "string", gallery_uplink_widget.text)
  114. dt.preferences.write("lightgallery_export", "gallery_tag", "string", gallery_tag_widget.text)
  115. end
  116. -- Function to check if a string is not empty
  117. local function is_not_empty(s)
  118. return s ~= "" and s ~= nil
  119. end
  120. local function run_post_export_script(exp_path)
  121. title = dt.preferences.read("lightgallery_export", "gallery_title", "string")
  122. if title == "" then
  123. title = "n.n"
  124. end
  125. uplink = dt.preferences.read("lightgallery_export", "lightgallery_uplink", "string")
  126. if uplink == "" then
  127. uplink = ".."
  128. end
  129. local post_export_script = dt.preferences.read("lightgallery_export", "post_export_script", "file")
  130. dt.print_log( "post_export_script: ".. post_export_script.." -t '"..title.."' -u '"..uplink.."' "..exp_path )
  131. os.execute( post_export_script.." -t '"..title.."' -u '"..uplink.."' "..exp_path )
  132. end
  133. -- Function to export images to Light Gallery
  134. local function export_to_lightgallery()
  135. local exp_path = export_path_widget.value
  136. local gallery_title = gallery_title_widget.text
  137. local exiftool = dt.preferences.read("lightgallery_export", "exiftoolbinary", "file")
  138. -- Save preferences
  139. save_preferences()
  140. -- Create the export directory if it doesn't exist
  141. os.execute("mkdir -p " .. exp_path)
  142. local jpeg_exporter = dt.new_format("jpeg")
  143. jpeg_exporter.quality = jpg_quality_str
  144. jpeg_exporter.max_height = image_max_xy
  145. jpeg_exporter.max_width = image_max_xy
  146. -- Loop over the selected images
  147. local images = dt.gui.selection()
  148. for _, i in ipairs(images) do
  149. local tmpname = os.tmpname()
  150. local tmp_exported = tmpname..".jpg"
  151. if dt.configuration.running_os == "windows" then
  152. tmp_exported = dt.configuration.tmp_dir .. tmp_exported -- windows os.tmpname() defaults to root directory
  153. end
  154. if i.rating < 2 then
  155. i.rating = 2
  156. end
  157. dt.print("Exporting "..i.filename)
  158. jpeg_exporter:write_image(i, tmp_exported, false)
  159. run_cmd = exiftool..' -TagsFromFile '..df.sanitize_filename(i.sidecar)..' -xmp:all -exif:all --subifd:all -overwrite_original '..df.sanitize_filename(tmp_exported)
  160. dt.print_log(string.format("Running: %s", run_cmd))
  161. resp = dtsys.external_command(run_cmd)
  162. targetfile = df.sanitize_filename(string.gsub(exp_path, "'", "")..PS..mws_basename(i.filename)..'.jpg')
  163. dt.print('mv ' .. tmp_exported .. ' ' .. targetfile)
  164. os.execute('mv ' .. tmp_exported .. ' ' .. targetfile)
  165. tag = dt.preferences.read("lightgallery_export", "gallery_tag", "string")
  166. if is_not_empty(tag) then
  167. tag = 'photography|published|gallery|'..tag
  168. tnr = dt.tags.find(tag)
  169. if not tnr then
  170. tnr = dt.tags.create(tag)
  171. end
  172. dt.tags.attach(tnr,i)
  173. end
  174. os.execute( "rm -f " .. tmpname )
  175. end
  176. run_post_export_script(exp_path)
  177. dt.print("Exported " .. #images .. " images to lightGallery")
  178. end
  179. -- Create export button
  180. local gallery_export_button = dt.new_widget("button"){
  181. label = "Run Export",
  182. clicked_callback = export_to_lightgallery
  183. }
  184. -- Create a button widget with a help link
  185. local help_button = dt.new_widget("button"){
  186. label = "Help/Documentation",
  187. clicked_callback = function()
  188. -- Open the help URL in the default web browser
  189. dt.control.execute("xdg-open "..help_url)
  190. end
  191. }
  192. -- Create the module widget
  193. local module_widget = dt.new_widget("box"){
  194. orientation = "vertical",
  195. gallery_title_widget_box,
  196. export_path_widget_box,
  197. gallery_uplink_widget_box,
  198. gallery_tag_widget_box,
  199. gallery_export_button,
  200. help_button
  201. }
  202. -- Register the module
  203. dt.register_lib(
  204. "lightgallery_export_module",
  205. "lightGallery Export",
  206. true,
  207. false,
  208. {
  209. [dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 100},
  210. },
  211. module_widget
  212. )
  213. script_data.destroy = nil
  214. script_data.destroy_method = nil
  215. return script_data