110 Commits

Author SHA1 Message Date
Bill Ferguson
6548a12bf1 contrib/dbmaint - backported to API-9.2.0. Script to perform database
maintenance by removing database entries for missing
                  filmrolls and images.
2024-06-09 12:21:56 -04:00
Bill Ferguson
becfa5350b tools/script_manager - back ported gettext.bindomain fix 2024-05-18 09:56:50 -04:00
wpferguson
ebd2cd7bf7 Merge pull request #462 from menschmaschine/master
Cropping guide for German passport and ID card photos.
2024-05-11 20:09:45 -04:00
Christian Sueltrop
52b4508e08 Added LUA script "passport_guide_germany.lua", which implements a cropping guide for passport photos according to the standards for German passport and ID card photos. 2024-05-06 21:53:46 +02:00
wpferguson
19fdbc14c5 Merge pull request #461 from wpferguson/reimplement_ensure_lib_in_path
reimplemented ensure_lib_in_path with a windows aware path specification
2024-04-08 23:33:12 -04:00
Bill Ferguson
63d5aad465 tools/script_manager reimplemented ensure_lib_in_path with a windows
aware path specification
2024-04-08 23:30:30 -04:00
wpferguson
9d6ff85893 Merge pull request #458 from wpferguson/revert_ensure_lib_in_path
revert ensure_lib_in_path
2024-04-06 21:51:26 -04:00
Bill Ferguson
125af63bda tools/script_manager - revert ensure_lib_in_path because of windows problems. 2024-04-06 21:48:51 -04:00
wpferguson
65c22e475a Merge pull request #457 from wpferguson/script_manager_lib_search_path
script_manager - support libraries in "local" directories
2024-04-03 13:54:46 -04:00
Bill Ferguson
e78e718769 tools/script_manager - allow for inclusion of directory/package specific
libraries by adding "local" libraries to the search
                       path to ensure they are found when needed.
2024-04-02 17:54:10 -04:00
wpferguson
40949b3855 Merge pull request #456 from wpferguson/fix_NaN
examples/gui_action.lua - changed nan to NaN
2024-03-29 16:05:22 -04:00
Bill Ferguson
06ab263e74 examples/gui_action.lua - changed nan to NaN 2024-03-29 16:04:07 -04:00
wpferguson
bccc86c70a Merge pull request #362 from dterrahe/lua_action
simple module to call dt_action_process
2024-03-29 16:01:37 -04:00
wpferguson
12640c7d29 Merge pull request #454 from mime01/script_manager
tools/script_manager - fixed crash
2024-01-28 12:40:44 -05:00
Michael Meister
febc3b1659 tools/script_manager - fixed crash
The script manager crashes if a LUA script was not copied to a
subfolder but directly into the LUA directory. The reason is that
the regular expression, which among other things extracts the
category of the script from its file path, does not match and thus
the category is null. To prevent this, a null check has been added.
2024-01-27 12:27:40 +01:00
wpferguson
9fdd69556c Merge pull request #453 from wpferguson/452_fix
don't set lib visibility unless we are in lighttable view
2024-01-24 13:18:59 -05:00
Bill Ferguson
4735be470a tools/script_manager - don't set lib visibility unless we are in
lighttable view
2024-01-24 13:16:42 -05:00
wpferguson
3b8e802e42 Merge pull request #444 from MStraeten/patch-1
Update x-touch.lua with support for primaries slider
2024-01-15 11:11:47 -05:00
Martin Straeten
f54d449316 increase required api version
… to match darktable 4.6.x
2024-01-15 07:01:43 +01:00
wpferguson
1b0fe4d7b9 Merge pull request #449 from wpferguson/cycle_group_leader
cycle group leader
2024-01-14 22:33:13 -05:00
Bill Ferguson
cf1dca9e1a contrib/cycle_group_leader.lus - adds shortcut to change the group
leader to the next image in a group
                                 wrapping around when the end of the
                                 group is reached.
2024-01-14 22:29:27 -05:00
wpferguson
45d54ef4e8 Merge pull request #448 from darktable-org/revert-447-change_group_leader
Revert "Change group leader"
2024-01-14 22:14:03 -05:00
wpferguson
8bfab0325b Revert "Change group leader" 2024-01-14 22:13:38 -05:00
wpferguson
4b99d00ab5 Merge pull request #447 from wpferguson/change_group_leader
Change group leader
2024-01-14 21:25:00 -05:00
Bill Ferguson
a5961eb066 contrib/change_group_leader.lua - adds a shortcut to cycle through
the images in a group making the
                                  next on the new group leader.
                                  When the end of the group is reached
                                  the first image in the group is
                                  selected.
2024-01-14 21:19:09 -05:00
wpferguson
95e19ef163 Merge pull request #446 from wpferguson/hif_group_leader
Make hif image group leader for raw + hif pairs
2024-01-14 17:31:07 -05:00
wpferguson
d4eb6577bf Merge pull request #445 from wpferguson/jpg_group_leader
Make jpg group leader for raw + jpg pairs
2024-01-14 17:30:52 -05:00
Bill Ferguson
294b693905 contrib/hif_group_leader.lua - make the hif image the group leader
for raw + hif image pairs.  Works
                               on import, selection, and collection.
2024-01-14 17:15:28 -05:00
Bill Ferguson
23835edc1f contrib/jpg_group_leader.lua - New script to make jpg images the
group leader for raw + jpg image
                               combinations.
2024-01-14 17:10:43 -05:00
Martin Straeten
5f29211f79 Update x-touch.lua with support for primaries slider
maps knobs to the primaries sliders
requires darktable 4.6.x
2024-01-11 20:42:32 +01:00
wpferguson
025f4299ea Merge pull request #435 from ddittmar/feature/select_non_existing
select non-existing images
2023-11-10 18:42:01 -05:00
ddittmar
dc50d40886 select non-existing images 2023-10-28 11:14:51 +02:00
wpferguson
867c49b1b9 Merge pull request #433 from wpferguson/script_manager_quote_fix
tools/script_manager - fixed quote
2023-10-17 16:04:42 -04:00
Bill Ferguson
13f02c95ea tools/script_manager - fixed quote with a " instead of s 2023-10-17 16:02:27 -04:00
wpferguson
d55dae73f0 Merge pull request #431 from wpferguson/script_manager_username_space_fix
Fix script_manager doesn't start on windows when username has a space
2023-10-16 22:44:10 -04:00
Bill Ferguson
34b9831472 tools/script_manager.lua - wrapped the scipt_dir in quotes to handle
the space in username problem on windows.
2023-10-16 22:41:12 -04:00
wpferguson
014a0fc1c9 Merge pull request #430 from wpferguson/explicitly_set_false
Explicitly set non running scriopts to FALSE
2023-09-20 13:54:02 -04:00
Bill Ferguson
bf17dccd69 tools/script_manager.lua - Explicitly set non running scriopts to FALSE
instead of relying on no value being intrepreted
                           as false.
2023-09-20 13:48:18 -04:00
wpferguson
890168d0d0 Merge pull request #426 from wpferguson/425_fix_executable_manager_not_appearing
Change window position of executable_manager and script_manager
2023-08-18 12:27:28 -04:00
Bill Ferguson
191aecacdf tools - Moved script_manager to bottom of lower left panel and
moved executable_manager to middle of lower left panel
        to work around windows GTK window placement error.
2023-08-18 12:23:24 -04:00
wpferguson
44ec01b136 Merge pull request #424 from wpferguson/fix_check_for_updates_comment
official/check_for_updates - updated instructions for additional modules
2023-07-17 17:41:10 -04:00
Bill Ferguson
a177da2040 official/check_for_updates = updated instructions for additional modules
required
2023-07-17 17:39:24 -04:00
wpferguson
c899040688 Merge pull request #423 from wpferguson/update_flatpak_readme
README.md - updated (fixed typos) echo commands to build luarc file
2023-07-16 13:24:56 -04:00
Bill Ferguson
e8af665b3c README.md - updated (fixed typos) echo commands to build luarc file 2023-07-16 13:22:06 -04:00
wpferguson
875734d455 Merge pull request #422 from wpferguson/fix_script_data_show
Fix script data show
2023-07-16 13:08:05 -04:00
Bill Ferguson
14d5a79db2 Added script_data.show to script_data blocks 2023-07-16 13:04:00 -04:00
Bill Ferguson
e1b2715ee9 contrib/gpx_export - added show function to script_data to fix #418 and #419. 2023-07-16 12:50:28 -04:00
wpferguson
7ecd5ca55d Merge pull request #421 from wpferguson/script_manager_updates
Script manager updates
2023-07-15 20:00:24 -04:00
wpferguson
931e7a4d37 Merge pull request #416 from wpferguson/check_max_api_version
Add check for max api version
2023-07-15 19:58:57 -04:00
Bill Ferguson
1792410efe lib/dtutils.lua - corrected test 2023-07-15 19:52:39 -04:00
wpferguson
8cbd9224f1 Merge pull request #377 from spaceChRiS/filter_manager_tooltip
Added tooltip to filter manager to better match new import scheme.
2023-07-14 17:40:10 -04:00
Bill Ferguson
24b552d619 lib/dtutils.lua - fix typo from testing 2023-07-12 13:18:01 -04:00
Bill Ferguson
68ae9326bf tools/script_manager.lua - added translation to preference setting 2023-07-12 12:37:14 -04:00
Bill Ferguson
b4626f2787 lib/dtutils.lua - changed log message to error on fail to load. Added
printing of the returned error.
2023-07-04 15:57:12 -04:00
Bill Ferguson
2fc8ed78e4 tools/script_manager.lua - added check to ensure script_data.show() runction
was passed as part of the script_data table
                           before trying to use it. Fixes #418.
2023-07-03 23:44:13 -04:00
Bill Ferguson
236b25a235 tools/script_manager.lua - clean up formatting and documentation 2023-07-03 23:42:47 -04:00
Bill Ferguson
a4f6af73ec tools/script_manager.lua - enabled log levels in callback routines 2023-06-24 19:56:51 -04:00
Bill Ferguson
fad74d6438 tools/script_manager.lua - cleaned up deactivate comments 2023-06-23 19:09:57 -04:00
Bill Ferguson
3e2d4c956d tools/script_manager.lua - Documented more fields for the sm.scripts table
Removed extra declaration of check_update preference
2023-06-22 16:04:26 -04:00
wpferguson
cd1d623390 Merge pull request #409 from dterrahe/x_touch_mimic
example slider mimic script for x-touch mini
2023-05-30 18:38:48 -04:00
Bill Ferguson
9e0374d597 lib/dtutils.lua - fix typos 2023-05-06 14:56:58 -04:00
Bill Ferguson
e47672b495 lib/dtutils.lua - added delay in check_min_api_version to sllow display of the error
message before script_manager displays an error message.
2023-05-06 14:36:22 -04:00
Bill Ferguson
1905be8577 lib/dtutils.lua - added check_max_api_version to handle the case where part of
the API is removed as in the case of the darktable.gui.libs.fixter functions.
2023-05-06 14:31:15 -04:00
dterrahe
4726821e7d Fix 8th knob 2023-05-05 23:19:00 +01:00
dterrahe
7ac37ddc1a Probe individual mask sliders 2023-05-03 23:43:01 +01:00
dterrahe
3889742e06 add x-touch mini script documentation 2023-03-25 18:49:55 +00:00
dterrahe
6bf3706455 add x-touch color calibration customisation 2023-03-25 18:14:19 +00:00
wpferguson
612ecaff6c Merge pull request #411 from wpferguson/doc_update
Updated documentation
2023-03-25 13:25:45 -04:00
Bill Ferguson
a85364ecff Updated documentation 2023-03-25 13:24:04 -04:00
wpferguson
c0af03c503 Merge pull request #408 from wpferguson/move_filename_string_functions_to_strings_library
Move filename/path/extension string functions to string library
2023-03-25 13:22:50 -04:00
wpferguson
9b61e4793b Merge pull request #410 from darktable-org/script_manager_running_script
script_manager darktable shortcut integration
2023-03-25 13:07:00 -04:00
wpferguson
75a19e74a0 Merge branch 'master' into script_manager_running_script 2023-03-25 13:03:55 -04:00
Bill Ferguson
21d7e72b0c tools/script_manager - resolved conflicts 2023-03-25 13:01:40 -04:00
Bill Ferguson
05d555eae5 tools/script_manager - let the shortcut system know that script_manager
widgets belong to script_manager
2023-03-25 12:46:59 -04:00
dterrahe
8e412c3eb3 example slider mimic script for x-touch mini 2023-03-25 10:59:19 -04:00
Bill Ferguson
80147a9ebc lib/dtugiles.file - Moved filename/path/extension string functions to string library. Left
the existing function calls in place for backward compatibility.  They
                      now call the new functions in the string library

lib/dtutils.string - Moved the filename/path/extension string functions to the string library
                     to prevent a circular library depnedency.  The file library includes the
                     string library.  If the string library needed to manipulate filename
                     related strings then the string library would need to include the
                     file library which would lead to a stack overflow.
2023-03-24 13:40:34 -04:00
Bill Ferguson
3f6a3e25f1 added global variable script+_manager_running_script to convey the script name to the darktable shortcut system 2023-03-16 20:59:10 -04:00
wpferguson
800cbeef9d Merge pull request #407 from wpferguson/script_manager_check_for_updates_pref
script_manager preference - check for updated scripts
2023-03-06 23:08:54 -05:00
Bill Ferguson
574f6a976f script_manager.lua - added a preference allowing the user to disable
automatic checking for updated scripts.
2023-03-06 22:56:55 -05:00
supertobi
030b360e57 Merge pull request #404 from darktable-org/macOS_HOME
Mac os home
2023-02-27 09:30:44 +01:00
supertobi
b883714192 fix HOME environment variable name for macOS 2023-02-27 09:29:16 +01:00
supertobi
d556f48168 fix HOME environment variable name for macOS 2023-02-27 09:27:25 +01:00
wpferguson
cd7cac0eec Merge pull request #403 from rds13/featureFixKML
fix HOME environment variable name
2023-02-25 12:21:41 -05:00
Romuald du Song
9b31f18470 fix HOME environment variable name 2023-02-25 17:41:45 +01:00
wpferguson
42a194b3d7 Merge pull request #400 from wpferguson/update_change_group_leader
Update contrib/change_group_leader
2022-10-16 14:03:16 -04:00
Bill Ferguson
6748a7125e README.md Added change_group_leader to contrib section
change_group_leader.lua  Updated copyright information

                         Added script_manager integration

                         Added i18n
2022-10-16 13:58:19 -04:00
wpferguson
c2b3f29f3b Merge pull request #399 from dexterlb/change_group_leader
Add group leader script
2022-10-15 13:02:49 -04:00
dexterlb
572a634d90 fix title 2022-10-10 21:39:38 +03:00
dexterlb
652606ffb0 fix copyright message 2022-10-10 21:38:30 +03:00
dexterlb
803537c63e add comments to change_group_leader 2022-10-09 12:00:29 +03:00
dexterlb
4648c2d9af add change_group_leader script 2022-10-09 11:54:02 +03:00
supertobi
edceb3e7e9 Merge pull request #396 from mpaglia0/master - Added Italian translation + improved label
Added Italian translation + improved label
2022-07-15 09:52:14 +02:00
Maurizio Paglia
da6bddcd77 Clear button now can be translated 2022-07-14 18:44:42 +02:00
Maurizio Paglia
b11f43e903 Added Italian translations 2022-07-14 18:43:02 +02:00
supertobi
ef218a4d2e Merge pull request #394 from manu-p/master
OpenInExplorer fr_FR translation
2022-06-28 10:02:45 +02:00
manu-p
b061f27e7a OpenInExplorer fr_FR translation 2022-06-27 17:36:47 +02:00
wpferguson
8e64d54ab1 Merge pull request #389 from wpferguson/fix_readme_links
[README.md] fix links to documentation
2022-03-16 13:12:59 -04:00
Bill Ferguson
56b40a80ac [README.md] fix links to documentation 2022-03-16 13:10:06 -04:00
supertobi
d359d8ecb4 Merge pull request #383 from dtorop/fuji-dr-load-only-with-exiftool
fujifilm_dynamic_range: only load if exiftool present
2022-02-14 09:58:13 +01:00
Dan Torop
2bc55d00bb fujifilm_dynamic_range: only load if exiftool present
Fail to load if exiftool binary is not present. This may be better
than silently (in UI) failing to read dyanmic range data.
2022-02-13 22:14:57 -05:00
wpferguson
d3cf564b71 Merge pull request #379 from wpferguson/cleanup_changelog
fix changelog formatting
2022-01-12 14:59:04 -05:00
Bill Ferguson
4fb8b97084 fix changelog formatting 2022-01-12 14:57:57 -05:00
wpferguson
32c5cceb1d Merge pull request #378 from wpferguson/update_docs
Updated documentation
2022-01-12 14:54:30 -05:00
Bill Ferguson
f38c14d6b5 Updated documentation 2022-01-12 14:53:02 -05:00
Christian Mandel
3070ca0bc4 Added tooltip to filter manager to better match new import scheme. 2022-01-09 15:46:29 +01:00
wpferguson
0122b3f717 Merge pull request #374 from wpferguson/which_deprecation_369
Fix dtutils/file.lua deprecation warning
2021-12-28 20:50:21 -05:00
Bill Ferguson
79678fd82f [lib/dtutils/file.lua] replaced deprecated "which" call with recommended
"command -v" call to check the existence of a
                       program
2021-12-28 20:45:50 -05:00
wpferguson
034ddfbafb Merge pull request #373 from wpferguson/deprecate_rename_tags
Deprecate rename-tags.lua
2021-12-28 11:22:25 -05:00
Bill Ferguson
aebd26d03a [lib/dtutils.lua] - Added deprecated function to use when deprecating
scripts

[contrib/rename-tags.lua] - Added deprecation warning
2021-12-27 19:36:15 -05:00
Diederik ter Rahe
28ae2ea501 simple module to call dt_action_process 2021-09-12 18:16:09 +02:00
64 changed files with 2376 additions and 203 deletions

View File

@@ -1,6 +1,23 @@
## Changes from most recent to oldest
**25 Mar 2023 - wpferguson**
* Added script_manager darktable shortcut integration
* Moved filename/path/extension string functions to string library
**06 Mar 2023 - wpferguson - Added option to disable script_manager update check**
**12 Jan 2022 - wpferguson - Documented contrib/rename_images.lua**
**28 Dec 2021 - wpferguson - Replaced deprecated _which_ command with _command -v_ in lib/dtutils/file.lua**
**12 Dec 2021 - wpferguson**
* Added deprecated function to library
* Added deprecation warning to contrib/rename-tags.lua
**22 Oct 2021 - wpferguson for Volker Bödker - make sure sequence is 4 digits in rename_images.lua**
**31 Aug 2021 - wpferguson - remove styles hiding from AutoGrouper.lua**
**02 Jul 2021 - wpferguson - merged API-7.0.0-dev branch to master**
* API-7.0.0 is darktable 3.6
* breaking changes

View File

@@ -34,36 +34,39 @@ These scripts are contributed by users. They are meant to have an "owner", i.e.
Name|Standalone|OS |Purpose
----|:--------:|:---:|-------
[AutoGrouper](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/AutoGrouper)|Yes|LMW|Group images together by time
[AutoGrouper](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/autogrouper)|Yes|LMW|Group images together by time
[autostyle](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/autostyle)|Yes|LMW|Automatically apply styles on import
[clear_GPS](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/clear_GPS)|Yes|LMW|Reset GPS information for selected images
[CollectHelper](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/CollectHelper)|Yes|LMW|Add buttons to selected images module to manipulate the collection
change_group_leader|Yes|LMW|Change which image leads group
[clear_GPS](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/clear_gps)|Yes|LMW|Reset GPS information for selected images
[CollectHelper](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/collecthelper)|Yes|LMW|Add buttons to selected images module to manipulate the collection
[copy_attach_detach_tags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/copy_attach_detach_tags)|Yes|LMW|Copy and paste tags from/to images
[cr2hdr](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/cr2hdr)|Yes|L|Process image created with Magic Lantern Dual ISO
[enfuseAdvanced](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/enfuseAdvanced)|No|LMW|Merge multiple images into Dynamic Range Increase (DRI) or Depth From Focus (DFF) images
[exportLUT](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/exportLUT)|Yes|LMW|Create a LUT from a style and export it
[enfuseAdvanced](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/enfuseadvanced)|No|LMW|Merge multiple images into Dynamic Range Increase (DRI) or Depth From Focus (DFF) images
[exportLUT](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/exportlut)|Yes|LMW|Create a LUT from a style and export it
[ext_editor](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/ext_editor)|No|LW|Export pictures to collection and edit them with up to nine user-defined external editors
[face_recognition](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/face_recognition)|No|LM|Identify and tag images using facial recognition
[fujifilm_dynamic_range](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/fujifilm_dynamic_range)|No|LMW|Correct fujifilm exposure based on exposure bias camera setting
[fujifilm_ratings](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/fujifilm_ratings)|No|LM|Support importing Fujifilm ratings
[geoJSON_export](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/geoJSON_export)|No|L|Create a geo JSON script with thumbnails for use in ...
[geoToolbox](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/geoToolbox)|No|LMW|A toolbox of geo functions
[geoJSON_export](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/geojson_export)|No|L|Create a geo JSON script with thumbnails for use in ...
[geoToolbox](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/geotoolbox)|No|LMW|A toolbox of geo functions
[gimp](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/gimp)|No|LMW|Open an image in GIMP for editing and return the result
[gpx_export](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/gpx_export)|No|LMW|Export a GPX track file from selected images GPS data
[HDRMerge](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/HDRMerge)|No|LMW|Combine the selected images into an HDR DNG and return the result
[HDRMerge](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/hdrmerge)|No|LMW|Combine the selected images into an HDR DNG and return the result
[hugin](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/hugin)|No|LMW|Combine selected images into a panorama and return the result
[image_stack](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/image_stack)|No|LMW|Combine a stack of images to remove noise or transient objects
[image_time](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/image_time)|Yes|LMW|Adjust the EXIF image time
[kml_export](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/kml_export)|No|L|Export photos with a KML file for usage in Google Earth
[LabelsToTags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/LabelsToTags)|Yes|LMW|Apply tags based on color labels and ratings
[OpenInExplorer](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/OpenInExplorer)|No|LMW|Open the selected images in the system file manager
[LabelsToTags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/labelstotags)|Yes|LMW|Apply tags based on color labels and ratings
[OpenInExplorer](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/openinexplorer)|No|LMW|Open the selected images in the system file manager
[passport_guide](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/passport_guide)|Yes|LMW|Add passport cropping guide to darkroom crop tool
[pdf_slideshow](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/pdf_slideshow)|No|LM|Export images to a PDF slideshow
[photils](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/photils)|No|LM|Automatic tag suggestions for your images
[quicktag](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/quicktag)|Yes|LMW|Create shortcuts for quickly applying tags
[rate_group](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/rate_group)|Yes|LMW|Apply or remove a star rating from grouped images
[rename_images](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/rename_images)|Yes|LMW|Rename single or multiple images
[rename-tags](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/rename-tags)|Yes|LMW|Change a tag name
[RL_out_sharp](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/RL_out_sharp)|No|LW|Output sharpening using GMic (Richardson-Lucy algorithm)
[RL_out_sharp](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/rl_out_sharp)|No|LW|Output sharpening using GMic (Richardson-Lucy algorithm)
[select_non_existing](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/select_non_existing)|Yes|LMW|Enable selection of non-existing images in the the currently worked on images
[select_untagged](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/select_untagged)|Yes|LMW|Enable selection of untagged images
[slideshowMusic](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/slideshowMusic)|No|L|Play music during a slideshow
[transfer_hierarchy](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/contrib/transfer_hierarchy)|Yes|LMW|Image move/copy preserving directory hierarchy
@@ -77,14 +80,14 @@ Name|Standalone|OS |Purpose
----|:--------:|:---:|-------
[api_version](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/api_version)|Yes|LMW|Print the current API version
[darkroom_demo](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/darkroom_demo)|Yes|LMW|Demonstrate changing images in darkoom
[gettextExample](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/gettextExample)|Yes|LM|How to use translation
[gettextExample](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/gettextexample)|Yes|LM|How to use translation
[hello_world](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/hello_world)|Yes|LMW|Prints hello world when darktable starts
[lighttable_demo](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/lighttable_demo)|Yes|LMW|Demonstrate controlling lighttable mode, zoom, sorting and filtering
[moduleExample](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/moduleExample)|Yes|LMW|How to create a lighttable module
[moduleExample](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/moduleexample)|Yes|LMW|How to create a lighttable module
[multi_os](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/multi_os)|No|LMW|How to create a cross platform script that calls an external executable
[panels_demo](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/panels_demo)|Yes|LMW|Demonstrate hiding and showing darktable panels
[preferenceExamples](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/preferenceExamples)|Yes|LMW|How to use preferences in a script
[printExamples](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/printExamples)|Yes|LMW|How to use various print functions from a script
[preferenceExamples](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/preferenceexamples)|Yes|LMW|How to use preferences in a script
[printExamples](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/printexamples)|Yes|LMW|How to use various print functions from a script
[running_os](https://darktable-org.github.io/luadocs/lua.scripts.manual/scripts/examples/running_os)|Yes|LMW|Print out the running operating system
### Tools
@@ -114,6 +117,7 @@ The following third-party projects are listed for information only. Think of thi
* [arru/darktable-scripts](https://github.com/arru/darktable-scripts)
* [nbremond77/darktable](https://github.com/nbremond77/darktable/tree/master/scripts)
* [s5k6/dtscripts](https://github.com/s5k6/dtscripts)
* [ChristianBirzer/darktable_extra_scripts](https://github.com/ChristianBirzer/darktable_extra_scripts)
## Download and Install
@@ -171,7 +175,7 @@ The recommended way to enable and disable specific scripts is using the script m
### Windows
echo "require 'tools/script_manager'" > %LOCALAPPDATA%\darktable\luarc
echo require "tools/script_manager" > %LOCALAPPDATA%\darktable\luarc
### Snap
@@ -179,7 +183,7 @@ The recommended way to enable and disable specific scripts is using the script m
### Flatpak
echo require "tools/script_manager"' > ~/.var/app/org.darktable.Darktable/config/darktable/luarc
echo 'require "tools/script_manager"' > ~/.var/app/org.darktable.Darktable/config/darktable/luarc
You can also create or add lines to the luarc file from the command line:

View File

@@ -50,6 +50,7 @@ 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

View File

@@ -63,6 +63,7 @@ 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 function _(msgid)
return gettext.dgettext("CollectHelper", msgid)

View File

@@ -58,6 +58,7 @@ 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 mod = 'module_HDRMerge'

View File

@@ -59,6 +59,7 @@ 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
-- Lua 5.3 no longer has "unpack" but "table.unpack"
unpack = unpack or table.unpack

View File

@@ -63,6 +63,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("OpenInExplorer",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -72,6 +72,7 @@ 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
-- OS compatibility
local PS = dt.configuration.running_os == "windows" and "\\" or "/"

View File

@@ -49,6 +49,7 @@ 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
-- run command and retrieve stdout
local function get_stdout(cmd)

View File

@@ -0,0 +1,201 @@
--[[
change group leader
copyright (c) 2020, 2022 Bill Ferguson <wpferguson@gmail.com>
copyright (c) 2021 Angel Angelov
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[
CHANGE GROUP LEADER
automatically change the leader of raw+jpg paired image groups
INSTALLATION
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory
* add the following line in the file $CONFIGDIR/luarc
require "change_group_leader"
USAGE
* in lighttable mode, select the image groups you wish to process,
select whether you want to set the leader to "jpg" or "raw",
and click "Execute"
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local gettext = dt.gettext
local MODULE = "change_group_leader"
du.check_min_api_version("3.0.0", MODULE)
-- 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain(MODULE, dt.configuration.config_dir.."/lua/locale/")
local function _(msgid)
return gettext.dgettext(MODULE, msgid)
end
-- create a namespace to contain persistent data and widgets
chg_grp_ldr = {}
local cgl = chg_grp_ldr
cgl.widgets = {}
cgl.event_registered = false
cgl.module_installed = false
-- - - - - - - - - - - - - - - - - - - - - - - -
-- F U N C T I O N S
-- - - - - - - - - - - - - - - - - - - - - - - -
local function install_module()
if not cgl.module_installed then
dt.register_lib(
MODULE, -- Module name
_("change_group_leader"), -- Visible name
true, -- expandable
false, -- resetable
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_RIGHT_CENTER", 700}}, -- containers
cgl.widgets.box,
nil,-- view_enter
nil -- view_leave
)
cgl.module_installed = true
end
end
local function find_group_leader(images, mode)
for _, img in ipairs(images) do
dt.print_log("checking image " .. img.id .. " named " .. img.filename)
local found = false
if mode == "jpg" then
if string.match(string.lower(img.filename), "jpg$") then
dt.print_log("jpg matched image " .. img.filename)
found = true
end
elseif mode == "raw" then
if img.is_raw and img.duplicate_index == 0 then
dt.print_log("found raw " .. img.filename)
found = true
end
elseif mode == "non-raw" then
if img.is_ldr then
dt.print_log("found ldr " .. img.filename)
found = true
end
else
dt.print_error(MODULE .. ": unrecognized mode " .. mode)
return
end
if found then
dt.print_log("making " .. img.filename .. " group leader")
img:make_group_leader()
return
end
end
end
local function process_image_groups(images)
if #images < 1 then
dt.print(_("No images selected."))
dt.print_log(MODULE .. "no images seletected, returning...")
else
local mode = cgl.widgets.mode.value
for _,img in ipairs(images) do
dt.print_log("checking image " .. img.id)
local group_images = img:get_group_members()
if group_images == 1 then
dt.print_log("only one image in group for image " .. image.id)
else
find_group_leader(group_images, mode)
end
end
end
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - -
local function destroy()
dt.gui.libs[MODULE].visible = false
end
local function restart()
dt.gui.libs[MODULE].visible = true
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- W I D G E T S
-- - - - - - - - - - - - - - - - - - - - - - - -
cgl.widgets.mode = dt.new_widget("combobox"){
label = _("select new group leader"),
tooltip = _("select type of image to be group leader"),
selected = 1,
"jpg", "raw", "non-raw",
}
cgl.widgets.execute = dt.new_widget("button"){
label = _("Execute"),
clicked_callback = function()
process_image_groups(dt.gui.action_images)
end
}
cgl.widgets.box = dt.new_widget("box"){
orientation = "vertical",
cgl.widgets.mode,
cgl.widgets.execute,
}
-- - - - - - - - - - - - - - - - - - - - - - - -
-- D A R K T A B L E I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - -
if dt.gui.current_view().id == "lighttable" then
install_module()
else
if not cgl.event_registered then
dt.register_event(
"view-changed",
function(event, old_view, new_view)
if new_view.name == "lighttable" and old_view.name == "darkroom" then
install_module()
end
end
)
cgl.event_registered = true
end
end
script_data.destroy = destroy
script_data.restart = restart
script_data.destroy_method = "hide"
script_data.show = restart
return script_data

View File

@@ -46,6 +46,7 @@ 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
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

View File

@@ -51,6 +51,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("copy_attach_detach_tags",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -44,6 +44,7 @@ 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 queue = {}
local processed_files = {}

View File

@@ -0,0 +1,158 @@
--[[
cycle_group_leader.lua - change image grouip leader
Copyright (C) 2024 Bill Ferguson <wpferguson@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]
--[[
cycle_group_leader - change image grouip leader
cycle_group_leader changes the group leader to the next
image in the group. If the end of the group is reached
then the next image is wrapped around to the first image.
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
None
USAGE
* enable with script_manager
* assign a key to the shortcut
BUGS, COMMENTS, SUGGESTIONS
Bill Ferguson <wpferguson@gmail.com>
CHANGES
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local df = require "lib/dtutils.file"
-- - - - - - - - - - - - - - - - - - - - - - - -
-- C O N S T A N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
local MODULE = "cycle_group_leader"
-- - - - - - - - - - - - - - - - - - - - - - - -
-- A P I C H E C K
-- - - - - - - - - - - - - - - - - - - - - - - -
du.check_min_api_version("7.0.0", MODULE)
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
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
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
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- I 1 8 N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local gettext = dt.gettext
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain(MODULE, dt.configuration.config_dir .. "/lua/locale/")
local function _(msgid)
return gettext.dgettext(MODULE, msgid)
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- F U N C T I O N S
-- - - - - - - - - - - - - - - - - - - - - - - -
local function toggle_global_toolbox_grouping()
dt.gui.libs.global_toolbox.grouping = false
dt.gui.libs.global_toolbox.grouping = true
end
local function hinter_msg(msg)
dt.print_hinter(msg)
dt.control.sleep(1500)
dt.print_hinter(" ")
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- M A I N P R O G R A M
-- - - - - - - - - - - - - - - - - - - - - - - -
local function cycle_group_leader(image)
local group_images = image:get_group_members()
if #group_images < 2 then
hinter_msg(_("No images to cycle to in group"))
return
else
local position = nil
for i, img in ipairs(group_images) do
if image == img then
position = i
end
end
if position == #group_images then
position = 1
else
position = position + 1
end
new_leader = group_images[position]
new_leader:make_group_leader()
dt.gui.selection({new_leader})
if dt.gui.libs.global_toolbox.grouping then
-- toggle the grouping to make the new leader show
toggle_global_toolbox_grouping()
end
end
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- D A R K T A B L E I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - -
local function destroy()
-- put things to destroy (events, storages, etc) here
dt.destroy_event(MODULE, "shortcut")
end
script_data.destroy = destroy
-- - - - - - - - - - - - - - - - - - - - - - - -
-- E V E N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
dt.register_event(MODULE, "shortcut",
function(event, shortcut)
-- ignore the film roll, it contains all the images, not just the imported
local images = dt.gui.selection()
if #images < 1 then
dt.print(_("No image selected. Please select an image and try again"))
else
cycle_group_leader(images[1])
end
end,
_("cycle group leader")
)
return script_data

314
contrib/dbmaint.lua Normal file
View File

@@ -0,0 +1,314 @@
--[[
dbmaint.lua - perform database maintenance
Copyright (C) 2024 Bill Ferguson <wpferguson.com>.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]
--[[
dbmaint - perform database maintenance
Perform database maintenance to clean up missing images and filmstrips.
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
None
USAGE
* start dbmaint from script_manager
* scan for missing film rolls or missing images
* look at the results and choose to delete or not
BUGS, COMMENTS, SUGGESTIONS
Bill Ferguson <wpferguson.com>
CHANGES
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local df = require "lib/dtutils.file"
local log = require "lib/dtutils.log"
-- - - - - - - - - - - - - - - - - - - - - - - -
-- C O N S T A N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
local MODULE <const> = "dbmaint"
local DEFAULT_LOG_LEVEL <const> = log.error
local PS <const> = dt.configuration.running_os == "windows" and "\\" or "/"
-- - - - - - - - - - - - - - - - - - - - - - - -
-- A P I C H E C K
-- - - - - - - - - - - - - - - - - - - - - - - -
du.check_min_api_version("7.0.0", MODULE) -- choose the minimum version that contains the features you need
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- I 1 8 N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local gettext = dt.gettext.gettext
dt.gettext.bindtextdomain(MODULE , dt.configuration.config_dir .. "/lua/locale/")
local function _(msgid)
return gettext(MODULE, msgid)
end
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
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
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
script_data.metadata = {
name = "dbmaint",
purpose = _("perform database maintenance"),
author = "Bill Ferguson <wpferguson.com>",
help = "https://docs.darktable.org/lua/stable/lua.scripts.manual/scripts/contrib/dbmaint/"
}
-- - - - - - - - - - - - - - - - - - - - - - - -
-- L O G L E V E L
-- - - - - - - - - - - - - - - - - - - - - - - -
log.log_level(DEFAULT_LOG_LEVEL)
-- - - - - - - - - - - - - - - - - - - - - - - -
-- N A M E S P A C E
-- - - - - - - - - - - - - - - - - - - - - - - -
local dbmaint = {}
-- - - - - - - - - - - - - - - - - - - - - - - -
-- G L O B A L V A R I A B L E S
-- - - - - - - - - - - - - - - - - - - - - - - -
dbmaint.main_widget = nil
-- - - - - - - - - - - - - - - - - - - - - - - -
-- A L I A S E S
-- - - - - - - - - - - - - - - - - - - - - - - -
local namespace = dbmaint
-- - - - - - - - - - - - - - - - - - - - - - - -
-- F U N C T I O N S
-- - - - - - - - - - - - - - - - - - - - - - - -
local function scan_film_rolls()
local missing_films = {}
for _, filmroll in ipairs(dt.films) do
if not df.check_if_file_exists(filmroll.path) then
table.insert(missing_films, filmroll)
end
end
return missing_films
end
local function scan_images(film)
local missing_images = {}
if film then
for i = 1, #film do
local image = film[i]
log.log_msg(log.debug, "checking " .. image.filename)
if not df.check_if_file_exists(image.path .. PS .. image.filename) then
log.log_msg(log.info, image.filename .. " not found")
table.insert(missing_images, image)
end
end
end
return missing_images
end
local function remove_missing_film_rolls(list)
for _, filmroll in ipairs(list) do
filmroll:delete(true)
end
end
-- force the lighttable to reload
local function refresh_lighttable(film)
local rules = dt.gui.libs.collect.filter()
dt.gui.libs.collect.filter(rules)
end
local function remove_missing_images(list)
local film = list[1].film
for _, image in ipairs(list) do
image:delete()
end
refresh_lighttable(film)
end
local function install_module()
if not namespace.module_installed then
dt.register_lib(
MODULE, -- Module name
_("DB maintenance"), -- Visible name
true, -- expandable
true, -- resetable
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER", 0}}, -- containers
namespace.main_widget,
nil,-- view_enter
nil -- view_leave
)
namespace.module_installed = true
end
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- U S E R I N T E R F A C E
-- - - - - - - - - - - - - - - - - - - - - - - -
dbmaint.list_widget = dt.new_widget("text_view"){
editable = false,
reset_callback = function(this)
this.text = ""
end
}
dbmaint.chooser = dt.new_widget("combobox"){
label = "scan for",
selected = 1,
"film rolls", "images",
reset_callback = function(this)
this.selected = 1
end
}
dbmaint.scan_button = dt.new_widget("button"){
label = "scan",
tooltip = "click to scan for missing film rolls/files",
clicked_callback = function(this)
local found = nil
local found_text = ""
if dbmaint.chooser.value == "film rolls" then
found = scan_film_rolls()
if #found > 0 then
for _, film in ipairs(found) do
local dir_name = du.split(film.path, PS)
found_text = found_text .. dir_name[#dir_name] .. "\n"
end
end
else
log.log_msg(log.debug, "checking path " .. dt.collection[1].path .. " for missing files")
found = scan_images(dt.collection[1].film)
if #found > 0 then
for _, image in ipairs(found) do
found_text = found_text .. image.filename .. "\n"
end
end
end
if #found > 0 then
dbmaint.list_widget.text = found_text
dbmaint.found = found
dbmaint.remove_button.sensitive = true
end
end,
reset_callback = function(this)
dbmaint.found = nil
end
}
dbmaint.remove_button = dt.new_widget("button"){
label = "remove",
tooltip = "remove missing film rolls/images",
sensitive = false,
clicked_callback = function(this)
if dbmaint.chooser.value == "film rolls" then
remove_missing_film_rolls(dbmaint.found)
else
remove_missing_images(dbmaint.found)
end
dbmaint.found = nil
dbmaint.list_widget.text = ""
this.sensitive = false
end,
reset_callback = function(this)
this.sensitive = false
end
}
dbmaint.main_widget = dt.new_widget("box"){
orientation = "vertical",
dt.new_widget("section_label"){label = "missing items"},
dbmaint.list_widget,
dt.new_widget("label"){label = ""},
dbmaint.chooser,
dt.new_widget("label"){label = ""},
dbmaint.scan_button,
dbmaint.remove_button
}
-- - - - - - - - - - - - - - - - - - - - - - - -
-- D A R K T A B L E I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - -
local function destroy()
dt.gui.libs[MODULE].visible = false
if namespace.event_registered then
dt.destroy_event(MODULE, "view-changed")
end
return
end
local function restart()
dt.gui.libs[MODULE].visible = true
return
end
script_data.destroy = destroy
script_data.restart = restart
script_data.destroy_method = "hide"
script_data.show = restart
-- - - - - - - - - - - - - - - - - - - - - - - -
-- E V E N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
if dt.gui.current_view().id == "lighttable" then
install_module()
else
if not namespace.event_registered then
dt.register_event(MODULE, "view-changed",
function(event, old_view, new_view)
if new_view.name == "lighttable" and old_view.name == "darkroom" then
install_module()
end
end
)
namespace.event_registered = true
end
end
return script_data

View File

@@ -74,6 +74,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
local gettext = dt.gettext

View File

@@ -40,6 +40,7 @@ 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

View File

@@ -82,6 +82,7 @@ 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
-- OS compatibility
local PS = dt.configuration.running_os == "windows" and "\\" or "/"

View File

@@ -61,6 +61,7 @@ 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
-- namespace

View File

@@ -2,7 +2,7 @@
Compensate for Fujifilm raw files made using "dynamic range".
Copyright (C) 2021 Dan Torop <dant@pnym.net>
Copyright (C) 2021, 2022 Dan Torop <dant@pnym.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -70,6 +70,7 @@ 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 function detect_dynamic_range(event, image)
if image.exif_maker ~= "FUJIFILM" then
@@ -116,6 +117,11 @@ local function destroy()
dt.destroy_event("fujifilm_dr", "post-import-image")
end
if not df.check_if_bin_exists("exiftool") then
dt.print_log("Please install exiftool to use fujifilm_dynamic_range")
error "[fujifilm_dynamic_range] exiftool not found"
end
dt.register_event("fujifilm_dr", "post-import-image",
detect_dynamic_range)

View File

@@ -37,6 +37,7 @@ 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
gettext.bindtextdomain("fujifilm_ratings", dt.configuration.config_dir.."/lua/locale/")

View File

@@ -46,6 +46,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("geoJSON_export",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -39,6 +39,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("geoToolbox",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -81,6 +81,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("gimp",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -36,6 +36,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("gpx_export",dt.configuration.config_dir.."/lua/locale/")
@@ -203,5 +204,6 @@ end
script_data.destroy = destroy
script_data.restart = restart
script_data.destroy_method = "hide"
script_data.show = restart
return script_data

View File

@@ -0,0 +1,196 @@
--[[
hif_group_leader.lua - Make hif image group leader
Copyright (C) 2024 Bill Ferguson <wpferguson@gmail.com>.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]
--[[
hif_group_leader - Make hif image group leader
After a film roll is imported, check for RAW-JPG image groups
and make the JPG image the group leader. This is on by default
but can be disabled in preferences.
Shortcuts are included to filter existing collections or
selections of images and make the hif the group leader.
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
None
USAGE
Start script from script_manager
Assign keys to the shortcuts
BUGS, COMMENTS, SUGGESTIONS
Bill Ferguson <wpferguson@gmail.com>
CHANGES
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local df = require "lib/dtutils.file"
-- - - - - - - - - - - - - - - - - - - - - - - -
-- C O N S T A N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
local MODULE = "hif_group_leader"
-- - - - - - - - - - - - - - - - - - - - - - - -
-- A P I C H E C K
-- - - - - - - - - - - - - - - - - - - - - - - -
du.check_min_api_version("7.0.0", MODULE)
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
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
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
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- I 1 8 N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local gettext = dt.gettext
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain(MODULE, dt.configuration.config_dir .. "/lua/locale/")
local function _(msgid)
return gettext.dgettext(MODULE, msgid)
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- P R E F E R E N C E S
-- - - - - - - - - - - - - - - - - - - - - - - -
dt.preferences.register(MODULE, "on_import", "bool", _("make hif group leader on import"), _("automatically make the hif file the group leader when raw + hif are imported"), true)
-- - - - - - - - - - - - - - - - - - - - - - - -
-- N A M E S P A C E
-- - - - - - - - - - - - - - - - - - - - - - - -
local jgloi = {}
jgloi.images = {}
-- - - - - - - - - - - - - - - - - - - - - - - -
-- F U N C T I O N S
-- - - - - - - - - - - - - - - - - - - - - - - -
local function toggle_global_toolbox_grouping()
dt.gui.libs.global_toolbox.grouping = false
dt.gui.libs.global_toolbox.grouping = true
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- M A I N P R O G R A M
-- - - - - - - - - - - - - - - - - - - - - - - -
local function make_hif_group_leader(images)
-- if the image is part of a group, make it the leader
for _, image in ipairs(images) do
if #image:get_group_members() > 1 then
image:make_group_leader()
end
end
if dt.gui.libs.global_toolbox.grouping then
-- toggle the grouping to make the new leader show
toggle_global_toolbox_grouping()
end
end
local function make_existing_hif_group_leader(images)
for _, image in ipairs(images) do
if string.lower(df.get_filetype(image.filename)) == "hif" then
if #image:get_group_members() > 1 then
image:make_group_leader()
end
end
end
if dt.gui.libs.global_toolbox.grouping then
-- toggle the grouping to make the new leader show
toggle_global_toolbox_grouping()
end
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- D A R K T A B L E I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - -
local function destroy()
if dt.preferences.read(MODULE, "on_import", "bool") then
dt.destroy_event(MODULE, "post-import-film")
dt.destroy_event(MODULE, "post-import-image")
end
dt.destroy_event(MODULE .. "_collect", "shortcut")
dt.destroy_event(MODULE .. "_select", "shortcut")
end
script_data.destroy = destroy
-- - - - - - - - - - - - - - - - - - - - - - - -
-- E V E N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
if dt.preferences.read(MODULE, "on_import", "bool") then
dt.register_event(MODULE, "post-import-film",
function(event, film_roll)
-- ignore the film roll, it contains all the images, not just the imported
local images = jgloi.images
if #images > 0 then
jgloi.images = {}
make_hif_group_leader(images)
end
end
)
dt.register_event(MODULE, "post-import-image",
function(event, image)
if string.lower(df.get_filetype(image.filename)) == "hif" then
table.insert(jgloi.images, image)
end
end
)
end
dt.register_event(MODULE .. "_collect", "shortcut",
function(event, shortcut)
-- ignore the film roll, it contains all the images, not just the imported
local images = dt.collection
make_existing_hif_group_leader(images)
end,
_("Make hif group leader for collection")
)
dt.register_event(MODULE .. "_select", "shortcut",
function(event, shortcut)
local images = dt.gui.selection()
make_existing_hif_group_leader(images)
end,
_("Make hif group leader for selection")
)
return script_data

View File

@@ -63,6 +63,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("hugin",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -80,6 +80,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("image_stack",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -122,6 +122,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain

View File

@@ -0,0 +1,196 @@
--[[
jpg_group_leader.lua - Make jpg image group leader
Copyright (C) 2024 Bill Ferguson <wpferguson@gmail.com>.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]
--[[
jpg_group_leader - Make jpg image group leader
After a film roll is imported, check for RAW-JPG image groups
and make the JPG image the group leader. This is on by default
but can be disabled in preferences.
Shortcuts are included to filter existing collections or
selections of images and make the jpg the group leader.
ADDITIONAL SOFTWARE NEEDED FOR THIS SCRIPT
None
USAGE
Start script from script_manager
Assign keys to the shortcuts
BUGS, COMMENTS, SUGGESTIONS
Bill Ferguson <wpferguson@gmail.com>
CHANGES
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local df = require "lib/dtutils.file"
-- - - - - - - - - - - - - - - - - - - - - - - -
-- C O N S T A N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
local MODULE = "jpg_group_leader"
-- - - - - - - - - - - - - - - - - - - - - - - -
-- A P I C H E C K
-- - - - - - - - - - - - - - - - - - - - - - - -
du.check_min_api_version("7.0.0", MODULE)
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- S C R I P T M A N A G E R I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
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
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
-- - - - - - - - - - - - - - - - - - - - - - - - - -
-- I 1 8 N
-- - - - - - - - - - - - - - - - - - - - - - - - - -
local gettext = dt.gettext
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain(MODULE, dt.configuration.config_dir .. "/lua/locale/")
local function _(msgid)
return gettext.dgettext(MODULE, msgid)
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- P R E F E R E N C E S
-- - - - - - - - - - - - - - - - - - - - - - - -
dt.preferences.register(MODULE, "on_import", "bool", _("make jpg group leader on import"), _("automatically make the jpg file the group leader when raw + jpg are imported"), true)
-- - - - - - - - - - - - - - - - - - - - - - - -
-- N A M E S P A C E
-- - - - - - - - - - - - - - - - - - - - - - - -
local jgloi = {}
jgloi.images = {}
-- - - - - - - - - - - - - - - - - - - - - - - -
-- F U N C T I O N S
-- - - - - - - - - - - - - - - - - - - - - - - -
local function toggle_global_toolbox_grouping()
dt.gui.libs.global_toolbox.grouping = false
dt.gui.libs.global_toolbox.grouping = true
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- M A I N P R O G R A M
-- - - - - - - - - - - - - - - - - - - - - - - -
local function make_jpg_group_leader(images)
-- if the image is part of a group, make it the leader
for _, image in ipairs(images) do
if #image:get_group_members() > 1 then
image:make_group_leader()
end
end
if dt.gui.libs.global_toolbox.grouping then
-- toggle the grouping to make the new leader show
toggle_global_toolbox_grouping()
end
end
local function make_existing_jpg_group_leader(images)
for _, image in ipairs(images) do
if string.lower(df.get_filetype(image.filename)) == "jpg" then
if #image:get_group_members() > 1 then
image:make_group_leader()
end
end
end
if dt.gui.libs.global_toolbox.grouping then
-- toggle the grouping to make the new leader show
toggle_global_toolbox_grouping()
end
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- D A R K T A B L E I N T E G R A T I O N
-- - - - - - - - - - - - - - - - - - - - - - - -
local function destroy()
if dt.preferences.read(MODULE, "on_import", "bool") then
dt.destroy_event(MODULE, "post-import-film")
dt.destroy_event(MODULE, "post-import-image")
end
dt.destroy_event(MODULE .. "_collect", "shortcut")
dt.destroy_event(MODULE .. "_select", "shortcut")
end
script_data.destroy = destroy
-- - - - - - - - - - - - - - - - - - - - - - - -
-- E V E N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
if dt.preferences.read(MODULE, "on_import", "bool") then
dt.register_event(MODULE, "post-import-film",
function(event, film_roll)
-- ignore the film roll, it contains all the images, not just the imported
local images = jgloi.images
if #images > 0 then
jgloi.images = {}
make_jpg_group_leader(images)
end
end
)
dt.register_event(MODULE, "post-import-image",
function(event, image)
if string.lower(df.get_filetype(image.filename)) == "jpg" then
table.insert(jgloi.images, image)
end
end
)
end
dt.register_event(MODULE .. "_collect", "shortcut",
function(event, shortcut)
-- ignore the film roll, it contains all the images, not just the imported
local images = dt.collection
make_existing_jpg_group_leader(images)
end,
_("Make jpg group leader for collection")
)
dt.register_event(MODULE .. "_select", "shortcut",
function(event, shortcut)
local images = dt.gui.selection()
make_existing_jpg_group_leader(images)
end,
_("Make jpg group leader for selection")
)
return script_data

View File

@@ -52,6 +52,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("kml_export",dt.configuration.config_dir.."/lua/locale/")
@@ -334,7 +335,7 @@ local defaultDir = ''
if dt.configuration.running_os == "windows" then
defaultDir = os.getenv("USERPROFILE")
elseif dt.configuration.running_os == "macos" then
defaultDir = os.getenv("home")
defaultDir = os.getenv("HOME")
else
local handle = io.popen("xdg-user-dir DESKTOP")
defaultDir = handle:read()

View File

@@ -0,0 +1,105 @@
--[[
German passport photo cropping guide for darktable.
Derived from the passport cropping guide by Kåre Hampf.
copyright (c) 2017 Kåre Hampf
copyright (c) 2024 Christian Sültrop
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[
PASSPORT CROPPING GUIDE
Guides for cropping passport and ID card ("Personalausweis") photos based on the "Passbild-Schablone"
from the German Federal Ministry of the Interior and Community.
(https://www.bmi.bund.de/SharedDocs/downloads/DE/veroeffentlichungen/themen/moderne-verwaltung/ausweise/passbild-schablone-erwachsene.pdf?__blob=publicationFile&v=3)
INSTALLATION
* copy this file in $CONFIGDIR/lua/ where CONFIGDIR is your darktable configuration directory
* add the following line in the file $CONFIGDIR/luarc
require "passport_guide_germany"
* (optional) add the line:
"plugins/darkroom/clipping/extra_aspect_ratios/passport 35x45mm=45:35"
to $CONFIGDIR/darktablerc
USAGE
* when using the cropping tool, select "Passport Photo Germany" as guide and if you added the line in yout rc
select "passport 35x45mm" as aspect
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local gettext = dt.gettext
du.check_min_api_version("2.0.0", "passport_guide_germany")
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("passport_guide_germany",dt.configuration.config_dir.."/lua/locale/")
local function _(msgid)
return gettext.dgettext("passport_guide_germany", msgid)
end
dt.guides.register_guide("Passport Photo Germany",
-- draw
function(cairo, x, y, width, height, zoom_scale)
local _width, _height
-- get the max 35x45 rectangle
local aspect_ratio = 45 / 35
if width * aspect_ratio > height then
_width = height / aspect_ratio
_height = height
else
_width = width
_height = width * aspect_ratio
end
cairo:save()
cairo:translate(x + (width - _width) / 2, y + (height - _height) / 2)
cairo:scale(_width / 35, _height / 45)
-- the outer rectangle
cairo:rectangle( 0, 0, 35, 45)
-- Nose position: The nose tip must be between these lines
cairo:draw_line(15.5, 45, 15.5, 13)
cairo:draw_line(35-15.5, 45, 35-15.5, 13)
-- Face height
-- optimum face height: The upper end of the head should be between these lines
cairo:draw_line(0, 4, 35, 4)
cairo:draw_line(0, 8, 35, 8)
-- tolerated face height: The upper end of the head must not be below this line
cairo:draw_line(6, 13, 30, 13)
-- Eye area: The eyes must be between these lines
cairo:draw_line(0, 13, 35, 13)
cairo:draw_line(0, 23, 35, 23)
-- Cheek line: The cheek must lie on this line
cairo:draw_line(9, 45-5, 27, 45-5)
cairo:restore()
end,
-- gui
function()
return dt.new_widget("label"){label = _("Passport Photo Germany"), halign = "start"}
end
)
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on; hl Lua;
-- vim: shiftwidth=2 expandtab tabstop=2 cindent syntax=lua

View File

@@ -65,6 +65,7 @@ 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
dt.preferences.register
("pdf_slideshow","open with","string",

View File

@@ -51,6 +51,7 @@ 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 PS = dt.configuration.running_os == "windows" and "\\" or "/"

View File

@@ -51,6 +51,7 @@ 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 function apply_rating(rating)
local images = dt.gui.action_images

View File

@@ -34,6 +34,7 @@ local debug = require "darktable.debug"
-- check API version
du.check_min_api_version("7.0.0", "rename-tags")
du.deprecated("contrib/rename-tags.lua","darktable release 4.0")
-- return data structure for script_manager
@@ -42,6 +43,7 @@ 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 rt = {}
rt.module_installed = false

View File

@@ -75,6 +75,7 @@ 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
-- - - - - - - - - - - - - - - - - - - - - - - -

View File

@@ -0,0 +1,77 @@
--[[
This file is part of darktable,
copyright (c) 2023 Dirk Dittmar
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[
Enable selection of non-existing images in the the currently worked on images, e.g. the ones selected by the collection module.
]]
local dt = require "darktable"
local du = require "lib/dtutils"
local df = require "lib/dtutils.file"
-- module name
local MODULE = "select_non_existing"
du.check_min_api_version("9.1.0", MODULE)
-- figure out the path separator
local PS = dt.configuration.running_os == "windows" and "\\" or "/"
local gettext = dt.gettext
gettext.bindtextdomain(MODULE, dt.configuration.config_dir..PS.."lua"..PS.."locale"..PS)
local function _(msgid)
return gettext.dgettext(MODULE, msgid)
end
local function stop_job(job)
job.valid = false
end
local function select_nonexisting_images(event, images)
local selection = {}
local job = dt.gui.create_job(_("select non existing images"), true, stop_job)
for key,image in ipairs(images) do
if(job.valid) then
job.percent = (key - 1)/#images
local filepath = image.path..PS..image.filename
local file_exists = df.test_file(filepath, "e")
dt.print_log(filepath.." exists? => "..tostring(file_exists))
if (not file_exists) then
table.insert(selection, image)
end
else
break
end
end
stop_job(job)
return selection
end
local function destroy()
dt.gui.libs.select.destroy_selection(MODULE)
end
dt.gui.libs.select.register_selection(
MODULE,
_("select non existing"),
select_nonexisting_images,
_("select all non-existing images in the current images"))
local script_data = {}
script_data.destroy = destroy
return script_data

View File

@@ -31,6 +31,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("select_untagged",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -38,6 +38,7 @@ 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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("slideshowMusic",dt.configuration.config_dir.."/lua/locale/")

View File

@@ -87,6 +87,7 @@ 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 MKDIR_COMMAND = darktable.configuration.running_os == "windows" and "mkdir " or "mkdir -p "
local PATH_SEPARATOR = darktable.configuration.running_os == "windows" and "\\\\" or "/"

View File

@@ -48,6 +48,7 @@ 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 MODULE_NAME = "video_ffmpeg"
@@ -285,7 +286,7 @@ local defaultVideoDir = ''
if dt.configuration.running_os == "windows" then
defaultVideoDir = os.getenv("USERPROFILE")..PS .."videos"
elseif dt.configuration.running_os == "macos" then
defaultVideoDir = os.getenv("home")..PS.."Videos"
defaultVideoDir = os.getenv("HOME")..PS.."Videos"
else
local handle = io.popen("xdg-user-dir VIDEOS")
defaultVideoDir = handle:read()

105
examples/gui_action.lua Normal file
View File

@@ -0,0 +1,105 @@
local dt = require "darktable"
local NaN = 0/0
local wg = {}
wg.action = dt.new_widget("entry"){
text = "lib/filter/view",
placeholder = "action path",
tooltip = "enter the full path of an action, for example 'lib/filter/view'"
}
wg.instance = dt.new_widget("combobox"){
label = "instance",
tooltip = "the instance of an image processing module to execute action on",
"0", "+1", "-1", "+2", "-2", "+3", "-3", "+4", "-4", "+5", "-5", "+6", "-6", "+7", "-7", "+8", "-8", "+9", "-9"
}
wg.element = dt.new_widget("entry"){
text = "",
placeholder = "action element",
tooltip = "enter the element of an action, for example 'selection', or leave empty for default"
}
wg.effect = dt.new_widget("entry"){
text = "next",
placeholder = "action effect",
tooltip = "enter the effect of an action, for example 'next', or leave empty for default"
}
wg.speed = dt.new_widget("entry"){
text = "1",
placeholder = "action speed",
tooltip = "enter the speed to use in action execution, or leave empty to only read state"
}
wg.check = dt.new_widget("check_button"){
label = 'perform action',
tooltip = 'perform action or only read return',
clicked_callback = function()
wg.speed.sensitive = wg.check.value
end,
value = true
}
wg.return_value = dt.new_widget("entry"){
text = "",
sensitive = false
}
dt.register_lib(
"execute_action", -- Module name
"execute gui actions", -- name
true, -- expandable
false, -- resetable
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER", 100},
[dt.gui.views.darkroom] = {"DT_UI_CONTAINER_PANEL_LEFT_CENTER", 100}},
dt.new_widget("box")
{
orientation = "vertical",
dt.new_widget("box")
{
orientation = "horizontal",
dt.new_widget("label"){label = "action path", halign = "start"},
wg.action
},
wg.instance,
dt.new_widget("box")
{
orientation = "horizontal",
dt.new_widget("label"){label = "element", halign = "start"},
wg.element
},
dt.new_widget("box")
{
orientation = "horizontal",
dt.new_widget("label"){label = "effect", halign = "start"},
wg.effect
},
wg.check,
dt.new_widget("box")
{
orientation = "horizontal",
dt.new_widget("label"){label = "speed", halign = "start"},
wg.speed
},
dt.new_widget("button")
{
label = "execute action",
tooltip = "execute the action specified in the fields above",
clicked_callback = function(_)
local sp = NaN
if wg.check.value then sp = wg.speed.text end
wg.return_value.text = dt.gui.action(wg.action.text, wg.instance.value, wg.element.text, wg.effect.text, sp)
end
},
dt.new_widget("box")
{
orientation = "horizontal",
dt.new_widget("label"){label = "return value:", halign = "start"},
wg.return_value
},
}
)

View File

@@ -42,6 +42,7 @@ 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
-- translation

163
examples/x-touch.lua Normal file
View File

@@ -0,0 +1,163 @@
--[[
This file is part of darktable,
copyright (c) 2023 Diederik ter Rahe
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
]]
--[[
X-Touch Mini flexible encoder shortcuts
This script will create virtual sliders that are mapped dynamically to
the most relevant sliders for the currently focused processing module.
Tailored modules are color zones, tone equalizer, color calibration and
mask manager properties. The script can easily be amended for other
devices or personal preferences. Virtual "toggle" buttons can be created
as well, that dynamically change meaning depending on current status.
USAGE
* require this script from your main lua file
* restart darktable
* create shortcuts for each of the encoders on the x-touch mini
to a virtual slider under lua/x-touch
or import the following shortcutsrc file in the shortcuts dialog/preferences tab:
None;midi:CC1=lua/x-touch/knob 1
None;midi:CC2=lua/x-touch/knob 2
None;midi:CC3=lua/x-touch/knob 3
None;midi:CC4=lua/x-touch/knob 4
None;midi:CC5=lua/x-touch/knob 5
None;midi:CC6=lua/x-touch/knob 6
None;midi:CC7=lua/x-touch/knob 7
None;midi:CC8=lua/x-touch/knob 8
midi:E0=global/modifiers
midi:F0=global/modifiers;ctrl
midi:F#0=global/modifiers;alt
midi:G#-1=iop/blend/tools/show and edit mask elements
midi:A-1=iop/colorzones;focus
midi:A#-1=iop/toneequal;focus
midi:B-1=iop/colorbalancergb;focus
midi:C0=iop/channelmixerrgb;focus
]]
local dt = require "darktable"
local du = require "lib/dtutils"
du.check_min_api_version("9.2.0", "x-touch")
-- set up 8 mimic sliders with the same function
for k = 1,8 do
dt.gui.mimic("slider", "knob ".. k,
function(action, element, effect, size)
-- take the number from the mimic name
local k = tonumber(action:sub(-1))
-- only operate in darkroom; return NAN otherwise
if dt.gui.current_view() ~= dt.gui.views.darkroom then
return 0/0
end
local maskval = 0/0
if k < 8 then
-- first try if the mask slider at that position is active
local s = { "opacity",
"size",
"feather",
"hardness",
"rotation",
"curvature",
"compression" }
maskval = dt.gui.action("lib/masks/properties/" .. s[k],
element, effect, size)
end
-- if a value different from NAN is returned, the slider was active
if maskval == maskval then
return maskval
-- try if colorzones module is focused; if so select element of graph
elseif dt.gui.action("iop/colorzones", "focus") ~= 0 then
which = "iop/colorzones/graph"
local e = { "red",
"orange",
"yellow",
"green",
"aqua",
"blue",
"purple",
"magenta" }
element = e[k]
-- if the sigmoid rgb primaries is focused,
-- check sliders
elseif dt.gui.action("iop/sigmoid", "focus") ~= 0 and k <8 then
local e = { "red attenuation", "red rotation", "green attenuation", "green rotation", "blue attenuation", "blue rotation", "recover purity" }
which = "iop/sigmoid/primaries/"..e[k]
-- if the rgb primaries is focused,
-- check sliders
elseif dt.gui.action("iop/primaries", "focus") ~= 0 and k >=1 then
local e = { "red hue", "red purity", "green hue", "green purity", "blue hue", "blue purity", "tint hue", "tint purity" }
which = "iop/primaries/" ..e[k]
-- if the tone equalizer is focused,
-- select one of the sliders in the "simple" tab
elseif dt.gui.action("iop/toneequal", "focus") ~= 0 then
which ="iop/toneequal/simple/"..(k-9).." EV"
-- if color calibration is focused,
-- the last 4 knobs are sent there
elseif dt.gui.action("iop/channelmixerrgb", "focus") ~= 0
and k >= 5 then
-- knob 5 selects the active tab; pressing it resets to CAT
if k == 5 then
which = "iop/channelmixerrgb/page"
element = "CAT"
-- since the tab action is not a slider,
-- the effects need to be translated
if effect == "up" then effect = "next"
elseif effect == "down" then effect = "previous"
else effect = "activate"
end
else
-- knobs 6, 7 and 8 are for the three color sliders on each tab
which = "iop/focus/sliders"
local e = { "1st",
"2nd",
"3rd" }
element = e[k - 5]
end
-- the 4th knob is contrast;
-- either colorbalance if it is focused, or filmic
elseif dt.gui.action("iop/colorbalancergb", "focus") ~= 0
and k == 4 then
which = "iop/colorbalancergb/contrast"
-- in all other cases use a default selection
else
local s = { "iop/exposure/exposure",
"iop/filmicrgb/white relative exposure",
"iop/filmicrgb/black relative exposure",
"iop/filmicrgb/contrast",
"iop/crop/left",
"iop/crop/right",
"iop/crop/top",
"iop/crop/bottom" }
which = s[k]
end
-- now pass the element/effect/size to the selected slider
return dt.gui.action(which, element, effect, size)
end)
end

View File

@@ -65,10 +65,47 @@ function dtutils.check_min_api_version(min_api, script_name)
dt.print_error("This application is written for lua api version " .. min_api .. " or later.")
dt.print_error("The current lua api version is " .. current_api)
dt.print("ERROR: " .. script_name .. " failed to load. Lua API version " .. min_api .. " or later required.")
dt.control.sleep(2000) -- allow time for the error to display before script_manager writes it's error message
error("Minimum API " .. min_api .. " not met for " .. script_name .. ".", 0)
end
end
dtutils.libdoc.functions["check_max_api_version"] = {
Name = [[check_max_api_version]],
Synopsis = [[check the maximum required api version against the current api version]],
Usage = [[local du = require "lib/dtutils"
local result = du.check_max_api_version(max_api, script_name)
max_api - string - the api version that the application was written for (example: "5.0.0")
script_name - string - the name of the script]],
Description = [[check_max_api_version compares the maximum api required for the appllication to
run against the current api version. This function is used when a part of the Lua API that
the script relies on is removed. If the maximum api version is not met, then an
error message is printed saying the script_name failed to load, then an error is thrown causing the
program to stop executing.
Return_Value = [[result - true if the maximum api version is available, false if not.]],
Limitations = [[When using the default handler on a script being executed from the luarc file, the error thrown
will stop the luarc file from executing any remaining statements. This limitation does not apply to script_manger.]],
Example = [[check_max_api_version("9.0.0") does nothing if the api is less than or equal to 9.0.0 otherwise an
error message is printed and an error is thrown stopping execution of the script.]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils.check_max_api_version(max_api, script_name)
local current_api = dt.configuration.api_version_string
if current_api > max_api then
dt.print_error("This application is written for lua api version " .. max_api .. " or earlier.")
dt.print_error("The current lua api version is " .. current_api)
dt.print("ERROR: " .. script_name .. " failed to load. Lua API version " .. max_api .. " or earlier required.")
dt.control.sleep(2000) -- allow time for the error to display before script_manager writes it's error message
error("Maximum API " .. max_api .. " not met for " .. script_name .. ".", 0)
end
end
dtutils.libdoc.functions["split"] = {
Name = [[split]],
Synopsis = [[split a string on a specified separator]],
@@ -184,7 +221,8 @@ function dtutils.prequire(req_name)
if status then
log.msg(log.info, "Loaded " .. req_name)
else
log.msg(log.info, "Error loading " .. req_name)
log.msg(log.error, "Error loading " .. req_name)
log.msg(log.error, "Error returned is " .. lib)
end
return status, lib
end
@@ -330,4 +368,29 @@ function dtutils.find_image_by_id(imgid)
end
end
dtutils.libdoc.functions["deprecated"] = {
Name = [[deprecated]],
Synopsis = [[print deprecation warning]],
Usage = [[local du = require "lib/dtutils"
du.deprecated(script_name, removal_string)
script_name - name of the script being deprecated
removal_strubg - a string explaining when the script will be removed]],
Description = [[deprecated prints an error message saying the script is deprecated and when it will be removed]],
Return_Value = [[]],
Limitations = [[]],
Example = [[local du = require "lib/dtutils"
du.deprecated("contrib/rename-tags.lua", "darktable release 4.0")]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils.deprecated(script_name, removal_string)
dt.print_toast("WARNING: " .. script_name .. " is deprecated and will be removed in " .. removal_string)
dt.print_error("WARNING: " .. script_name .. " is deprecated and will be removed in " .. removal_string)
end
return dtutils

View File

@@ -191,7 +191,7 @@ end
local function _search_for_bin_nix(bin)
local result = false
local p = io.popen("which " .. bin)
local p = io.popen("command -v " .. bin)
local output = p:read("*a")
p:close()
if string.len(output) > 0 then
@@ -394,125 +394,32 @@ function dtutils_file.check_if_bin_exists(bin)
return result
end
dtutils_file.libdoc.functions["split_filepath"] = {
Name = [[split_filepath]],
Synopsis = [[split a filepath into parts]],
Usage = [[local df = require "lib/dtutils.file"
-- the following path, filename, etc functions have
-- moved to the string library since they are string
-- manipulation functions, and to prevent circular
-- library inclusiion.
local result = df.split_filepath(filepath)
filepath - string - path and filename]],
Description = [[split_filepath splits a filepath into the path, filename, basename and filetype and puts
that in a table]],
Return_Value = [[result - table - a table containing the path, filename, basename, and filetype]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
-- these functions are left here for compatibility
-- with older scripts
function dtutils_file.split_filepath(str)
-- strip out single quotes from quoted pathnames
str = string.gsub(str, "'", "")
str = string.gsub(str, '"', '')
local result = {}
-- Thank you Tobias Jakobs for the awesome regular expression, which I tweaked a little
result["path"], result["filename"], result["basename"], result["filetype"] = string.match(str, "(.-)(([^\\/]-)%.?([^%.\\/]*))$")
if result["basename"] == "" and result["filetype"]:len() > 1 then
result["basename"] = result["filetype"]
result["filetype"] = ""
end
return result
return ds.split_filepath(str)
end
dtutils_file.libdoc.functions["get_path"] = {
Name = [[get_path]],
Synopsis = [[get the path from a file path]],
Usage = [[local df = require "lib/dtutils.file"
local result = df.get_path(filepath)
filepath - string - path and filename]],
Description = [[get_path strips the filename and filetype from a path and returns the path]],
Return_Value = [[result - string - the path]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_file.get_path(str)
local parts = dtutils_file.split_filepath(str)
return parts["path"]
return ds.get_path(str)
end
dtutils_file.libdoc.functions["get_filename"] = {
Name = [[get_filename]],
Synopsis = [[get the filename and extension from a file path]],
Usage = [[local df = require "lib/dtutils.file"
local result = df.get_filename(filepath)
filepath - string - path and filename]],
Description = [[get_filename strips the path from a filepath and returns the filename]],
Return_Value = [[result - string - the file name and type]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_file.get_filename(str)
local parts = dtutils_file.split_filepath(str)
return parts["filename"]
return ds.get_filename(str)
end
dtutils_file.libdoc.functions["get_basename"] = {
Name = [[get_basename]],
Synopsis = [[get the filename without the path or extension]],
Usage = [[local df = require "lib/dtutils.file"
local result = df.get_basename(filepath)
filepath - string - path and filename]],
Description = [[get_basename returns the name of the file without the path or filetype
]],
Return_Value = [[result - string - the basename of the file]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_file.get_basename(str)
local parts = dtutils_file.split_filepath(str)
return parts["basename"]
return ds.get_basename(str)
end
dtutils_file.libdoc.functions["get_filetype"] = {
Name = [[get_filetype]],
Synopsis = [[get the filetype from a filename]],
Usage = [[local df = require "lib/dtutils.file"
local result = df.get_filetype(filepath)
filepath - string - path and filename]],
Description = [[get_filetype returns the filetype from the supplied filepath]],
Return_Value = [[result - string - the filetype]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_file.get_filetype(str)
local parts = dtutils_file.split_filepath(str)
return parts["filetype"]
return ds.get_filetype(str)
end

View File

@@ -294,6 +294,127 @@ function dtutils_string.sanitize_lua(str)
return str
end
dtutils_string.libdoc.functions["split_filepath"] = {
Name = [[split_filepath]],
Synopsis = [[split a filepath into parts]],
Usage = [[local ds = require "lib/dtutils.string"
local result = ds.split_filepath(filepath)
filepath - string - path and filename]],
Description = [[split_filepath splits a filepath into the path, filename, basename and filetype and puts
that in a table]],
Return_Value = [[result - table - a table containing the path, filename, basename, and filetype]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_string.split_filepath(str)
-- strip out single quotes from quoted pathnames
str = string.gsub(str, "'", "")
str = string.gsub(str, '"', '')
local result = {}
-- Thank you Tobias Jakobs for the awesome regular expression, which I tweaked a little
result["path"], result["filename"], result["basename"], result["filetype"] = string.match(str, "(.-)(([^\\/]-)%.?([^%.\\/]*))$")
if result["basename"] == "" and result["filetype"]:len() > 1 then
result["basename"] = result["filetype"]
result["filetype"] = ""
end
return result
end
dtutils_string.libdoc.functions["get_path"] = {
Name = [[get_path]],
Synopsis = [[get the path from a file path]],
Usage = [[local ds = require "lib/dtutils.string"
local result = ds.get_path(filepath)
filepath - string - path and filename]],
Description = [[get_path strips the filename and filetype from a path and returns the path]],
Return_Value = [[result - string - the path]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_string.get_path(str)
local parts = dtutils_string.split_filepath(str)
return parts["path"]
end
dtutils_string.libdoc.functions["get_filename"] = {
Name = [[get_filename]],
Synopsis = [[get the filename and extension from a file path]],
Usage = [[local ds = require "lib/dtutils.string"
local result = ds.get_filename(filepath)
filepath - string - path and filename]],
Description = [[get_filename strips the path from a filepath and returns the filename]],
Return_Value = [[result - string - the file name and type]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_string.get_filename(str)
local parts = dtutils_string.split_filepath(str)
return parts["filename"]
end
dtutils_string.libdoc.functions["get_basename"] = {
Name = [[get_basename]],
Synopsis = [[get the filename without the path or extension]],
Usage = [[local ds = require "lib/dtutils.string"
local result = ds.get_basename(filepath)
filepath - string - path and filename]],
Description = [[get_basename returns the name of the file without the path or filetype
]],
Return_Value = [[result - string - the basename of the file]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_string.get_basename(str)
local parts = dtutils_string.split_filepath(str)
return parts["basename"]
end
dtutils_string.libdoc.functions["get_filetype"] = {
Name = [[get_filetype]],
Synopsis = [[get the filetype from a filename]],
Usage = [[local ds = require "lib/dtutils.string"
local result = ds.get_filetype(filepath)
filepath - string - path and filename]],
Description = [[get_filetype returns the filetype from the supplied filepath]],
Return_Value = [[result - string - the filetype]],
Limitations = [[]],
Example = [[]],
See_Also = [[]],
Reference = [[]],
License = [[]],
Copyright = [[]],
}
function dtutils_string.get_filetype(str)
local parts = dtutils_string.split_filepath(str)
return parts["filetype"]
end
return dtutils_string

View File

@@ -0,0 +1,12 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
msgid "select non existing images"
msgstr "nicht vorhandene Bilder auswählen"
msgid "select non existing"
msgstr "nicht vorhandene auswählen"
msgid "select all non-existing images in the current images"
msgstr "alle nicht vorhandenen Bilder in den aktuellen Bildern auswählen"

View File

@@ -0,0 +1,85 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2022-06-27 17:22+0200\n"
"PO-Revision-Date: 2022-06-27 17:36+0200\n"
"Last-Translator: Manuel PINTOR <manu@lepassepartout.fr>\n"
"Language-Team: \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.3\n"
"X-Poedit-Basepath: ../../../contrib\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Poedit-SearchPath-0: OpenInExplorer.lua\n"
#: OpenInExplorer.lua:79
msgid ""
"OpenInExplorer plug-in only supports Linux, macOS, and Windows at this time"
msgstr ""
"Le script OpenInExplorer ne fonctionne que sur Linux, macOS et Windows pour "
"le moment"
#: OpenInExplorer.lua:95
msgid ""
"No links directory selected.\n"
"Please check the dt preferences (lua options)"
msgstr ""
"Aucun répertoire de liens sélectionné.\n"
"Voir dans les préférences dt > options lua"
#: OpenInExplorer.lua:99
#, lua-format
msgid ""
"Links directory '%s' not found.\n"
"Please check the dt preferences (lua options)"
msgstr ""
"Répertoire de liens '%s' inexistant.\n"
"Voir dans les préférences dt > options lua"
#: OpenInExplorer.lua:156
msgid "Failed to create links. Missing rights?"
msgstr "Erreur de création de liens. Droits insuffisants ?"
#: OpenInExplorer.lua:172
msgid "Please select an image"
msgstr "Sélectionner une image SVP"
#: OpenInExplorer.lua:178
msgid "Please select fewer images (max. 15)"
msgstr "Sélectionner moins d'images SVP (max. 15)"
#: OpenInExplorer.lua:203
msgid "show in file explorer"
msgstr "afficher dans le gestionnaire de fichiers"
#: OpenInExplorer.lua:205
msgid "Open the file manager at the selected image's location"
msgstr "Ouvre le gestionnaire de fichiers à l'endroit de l'image sélectionnée"
#: OpenInExplorer.lua:212
msgid "OpenInExplorer: linked files directory"
msgstr "OpenInExplorer : répertoire des fichiers liés"
#: OpenInExplorer.lua:213
msgid ""
"Directory to store the links to the file names. Requires restart to take "
"effect"
msgstr ""
"Répertoire dans lequel enregistrer les liens sur les fichiers. Nécessite un "
"redémarrage de dt"
#: OpenInExplorer.lua:216
msgid "Select directory"
msgstr "Sélectionner un répertoire"
#: OpenInExplorer.lua:222
msgid "OpenInExplorer: use links"
msgstr "OpenInExplorer : utiliser des liens"
#: OpenInExplorer.lua:223
msgid "Use links instead of multiple windows. Requires restart to take effect"
msgstr ""
"Utiliser des liens plutôt que de multiples fenêtres. Nécessite un "
"redémarrage de dt"

View File

@@ -0,0 +1,62 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Maurizio Paglia <mpaglia0@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-11 22:19+0200\n"
"PO-Revision-Date: 2022-07-11 22:21+0200\n"
"Last-Translator: Maurizio Paglia <mpaglia0@gmail.com>\n"
"Language-Team: Italian <>\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 21.12.3\n"
#: executable_manager.lua:144
msgid "No executable paths found, exiting..."
msgstr "Nessun percorso con eseguibili, esco..."
#: executable_manager.lua:160
msgid "select an executable"
msgstr "seleziona un eseguibile"
#: executable_manager.lua:160
msgid "search path for executable"
msgstr "cerca il percorso dell'eseguibile"
#: executable_manager.lua:169
msgid "select "
msgstr "seleziona"
#: executable_manager.lua:169
msgid " executable"
msgstr " eseguibile"
#: executable_manager.lua:190
msgid "select executable to modify"
msgstr "Seleziona l'eseguibile da modificare"
#: executable_manager.lua:205
msgid "current"
msgstr "Attuale"
#: executable_manager.lua:207
msgid "select"
msgstr "Seleziona"
#: executable_manager.lua:209
msgid "reset"
msgstr "Cancella"
#: executable_manager.lua:212
msgid "Clear path for "
msgstr "Cancella il percorso di "
#: executable_manager.lua:211
msgid "clear"
msgstr "Pulisci"

View File

@@ -0,0 +1,190 @@
# French messages for script_manager.lua
# Christophe Agathon <christophe.agathon@gmail.com>, 2020.
# Maurizio Paglia <mpaglia0@gmail.com>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2020-12-28 10:22+0100\n"
"PO-Revision-Date: 2022-07-11 22:03+0200\n"
"Last-Translator: Maurizio Paglia <mpaglia0@gmail.com>\n"
"Language-Team: Italian <>\n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 21.12.3\n"
"X-Poedit-Basepath: ../../../tools\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: script_manager.lua\n"
#: script_manager.lua:190
msgid "Cant read from "
msgstr "Non posso leggere da "
#: script_manager.lua:204
msgid "Loaded "
msgstr "Script caricato "
#: script_manager.lua:207
msgid " failed to load"
msgstr "Non riesco a caricare lo script"
#: script_manager.lua:223
msgid " will not start when darktable is restarted"
msgstr " non verrà avviato al riavvio di darktable"
#: script_manager.lua:281 script_manager.lua:345
msgid "find command is "
msgstr "Il comando find è "
#: script_manager.lua:321
msgid "lua scripts successfully updated"
msgstr "Gli script lua sono stati correttamente aggiornati"
#: script_manager.lua:381
msgid "category "
msgstr "Categoria"
#: script_manager.lua:381
msgid " is already in use. Please specify a different category name."
msgstr " è già utilizzato. Prego specificare un nome differente."
#: script_manager.lua:410
msgid "scripts successfully installed into category "
msgstr "Gli script sono stati installati correttamente nella categoria "
#: script_manager.lua:426
msgid "No scripts found to install"
msgstr "Non trovo script da installare"
#: script_manager.lua:430
msgid "failed to download scripts"
msgstr "Non riesco a scaricare gli script"
# Peut-être que « activé » serait mieux, mais ce n'est pas la traduction de « started »
#: script_manager.lua:458
msgid " started"
msgstr " avviato"
# Peut-être que « désactivé » serait mieux, mais ce n'est pas la traduction de « stopped »
#: script_manager.lua:460
msgid " stopped"
msgstr " bloccato"
#: script_manager.lua:545
msgid "Page "
msgstr "Pag."
#: script_manager.lua:545
msgid " of "
msgstr " di "
#: script_manager.lua:674
msgid "scripts to update"
msgstr "Script da aggiornare"
#: script_manager.lua:675
msgid "select the scripts installation to update"
msgstr "Selezionare l'installazione di script da aggiornare"
#: script_manager.lua:684 script_manager.lua:742
msgid "update scripts"
msgstr "Aggiornare gli script"
#: script_manager.lua:685
msgid "update the lua scripts from the repository"
msgstr "Aggiornare gli script lua del repo"
#: script_manager.lua:696
msgid ""
"enter the URL of the git repository containing the scripts you wish to add"
msgstr "Immettere l'URL del repo git che contiene gli script da aggiungere"
#: script_manager.lua:701
msgid "name of new category"
msgstr "Nome della nuova categoria"
#: script_manager.lua:702
msgid "enter a category name for the additional scripts"
msgstr "Immettere il nome della categoria per altri script"
#: script_manager.lua:707
msgid "URL to download additional scripts from"
msgstr "URL dal quale scaricare ulteriori script"
#: script_manager.lua:709
msgid "new category to place scripts in"
msgstr "Nuova categoria che dovrà contenere gli script"
#: script_manager.lua:712
msgid "install additional scripts"
msgstr "Installare gli script aggiuntivi"
#: script_manager.lua:720
msgid "Enable \"Disable Scripts\" button"
msgstr "Abilita il pulsante \"Disabilita Script\""
#: script_manager.lua:730
msgid "Disable Scripts"
msgstr "Disabilita Script"
#: script_manager.lua:736
msgid "lua scripts will not run the next time darktable is started"
msgstr "Gli script lua non verranno avviati al prossimo riavvio di darktable"
#: script_manager.lua:745
msgid "add more scripts"
msgstr "Aggiungi altri script"
#: script_manager.lua:747
msgid "disable scripts"
msgstr "Disabilita script"
#: script_manager.lua:755
msgid "category"
msgstr "categoria"
#: script_manager.lua:756
msgid "select the script category"
msgstr "Seleziona la categoria"
#: script_manager.lua:780
msgid "Page:"
msgstr "Pag.:"
#: script_manager.lua:808
msgid "Scripts"
msgstr "Scripts"
#: script_manager.lua:817
msgid "scripts per page"
msgstr "Script per pagina"
#: script_manager.lua:818
msgid "select number of start/stop buttons to display"
msgstr "Selezionare il numero di pulsanti da visualizzare"
#: script_manager.lua:829
msgid "change number of buttons"
msgstr "Modifica la quantità di pulsanti"
#: script_manager.lua:837
msgid "Configuration"
msgstr "Configurazione"
#: script_manager.lua:858
msgid "action"
msgstr "Azione"
#: script_manager.lua:864
msgid "install/update scripts"
msgstr "Installa/aggiorna script"
#: script_manager.lua:864
msgid "configure"
msgstr "Configura"
#: script_manager.lua:864
msgid "start/stop scripts"
msgstr "Avvia/blocca script"

View File

@@ -21,7 +21,7 @@ a simple script that will automatically look for newer releases on github and in
when there is something. it will only check on startup and only once a week.
USAGE
* install luasec and cjson for Lua 5.2 on your system
* install luasec and cjson for Lua 5.4 on your system
* require this script from your main lua file
* restart darktable
@@ -41,6 +41,7 @@ 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
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
-- compare two version strings of the form "major.minor.patch"
-- returns -1, 0, 1 if the first version is smaller, equal, greater than the second version,

View File

@@ -38,6 +38,7 @@ 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
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
-- set this to "false" if you don't want to overwrite metadata fields
-- (title, description, creator, publisher and rights) that are already set

View File

@@ -40,6 +40,7 @@ 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
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
dt.preferences.register("delete_long_tags", "length", "integer",
"maximum length of tags to keep",

View File

@@ -44,6 +44,7 @@ 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
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
-- deleting while iterating the tags list seems to break the iterator!
local unused_tags = {}

View File

@@ -50,6 +50,7 @@ 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
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
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("enfuse",dt.configuration.config_dir..PS .. "lua" .. PS .. "locale" .. PS)

View File

@@ -47,6 +47,7 @@ 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
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
dt.preferences.register("generate_image_txt",
"enabled",

View File

@@ -40,6 +40,7 @@ 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
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 ipiu = {}
ipiu.module_installed = false

View File

@@ -45,6 +45,7 @@ local filter_dropdown = dt.new_widget("combobox")
{
label = "import filter",
editable = false,
tooltip = "import filters are applied after completion of the import dialog",
changed_callback = function(widget)
dt.preferences.write("import_filter_manager", "active_filter", "string", widget.value)

View File

@@ -45,6 +45,7 @@ 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
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 buffer_count = 5

View File

@@ -45,6 +45,7 @@ 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
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
dt.preferences.register
("selection_to_pdf","Open with","string",

View File

@@ -41,6 +41,7 @@ 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
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 PS = dt.configuration.running_os == "windows" and "\\" or "/"
@@ -105,7 +106,7 @@ local function install_module()
"executable manager", -- Visible name
true, -- expandable
false, -- resetable
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_BOTTOM", 100}}, -- containers
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_BOTTOM", 600}}, -- containers
dt.new_widget("box") -- widget
{
orientation = "vertical",
@@ -208,7 +209,7 @@ for i,exec in ipairs(exec_table) do
executable_path_widgets[exec],
dt.new_widget("section_label"){label = _("reset")},
dt.new_widget("button"){
label = "clear",
label = _("clear"),
tooltip = _("Clear path for ") .. exec,
clicked_callback = function()
df.set_executable_path_preference(exec, "")

View File

@@ -1,6 +1,6 @@
--[[
This file is part of darktable,
copyright (c) 2018, 2020 Bill Ferguson <wpferguson@gmail.com>
copyright (c) 2018, 2020, 2023 Bill Ferguson <wpferguson@gmail.com>
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -60,7 +60,7 @@ local gettext = dt.gettext
-- Tell gettext where to find the .mo file translating messages for a particular domain
gettext.bindtextdomain("script_manager",dt.configuration.config_dir.."/lua/locale/")
dt.gettext.bindtextdomain("script_manager",dt.configuration.config_dir.."/lua/locale/")
local function _(msgid)
return gettext.dgettext("script_manager", msgid)
@@ -70,7 +70,6 @@ end
du.check_min_api_version("5.0.0", "script_manager")
-- - - - - - - - - - - - - - - - - - - - - - - -
-- C O N S T A N T S
-- - - - - - - - - - - - - - - - - - - - - - - -
@@ -94,6 +93,16 @@ local LUA_SCRIPT_REPO = "https://github.com/darktable-org/lua-scripts.git"
local LUA_API_VER = "API-" .. dt.configuration.api_version_string
-- - - - - - - - - - - - - - - - - - - - - - - -
-- P R E F E R E N C E S
-- - - - - - - - - - - - - - - - - - - - - - - -
dt.preferences.register(MODULE, "check_update", "bool",
_("check for updated scripts on start up"),
_("automatically update scripts to correct version"),
true)
local check_for_updates = dt.preferences.read(MODULE, "check_update", "bool")
-- - - - - - - - - - - - - - - - - - - - - - - -
-- L O G L E V E L
@@ -121,6 +130,10 @@ sm.event_registered = false
sm.widgets = {}
sm.categories = {}
-- set log level for functions
sm.log_level = DEFAULT_LOG_LEVEL
--[[
sm.scripts is a table of tables for containing the scripts
@@ -150,6 +163,8 @@ sm.categories = {}
storage_name name of the exporter (in the exporter storage menu)
has_action true if it creates an action
action_name name on the button
has_select true if it creates a select
select_name name on the button
has_event true if it creates an event handler
event_type type of event, shortcut, post-xxx, pre-xxx
callback name of the callback routine
@@ -181,22 +196,42 @@ sm.run = false
-- F U N C T I O N S
-- - - - - - - - - - - - - - - - - - - - - - - -
-------------------
-- helper functions
-------------------
local function set_log_level(level)
local old_log_level = log.log_level()
log.log_level(level)
return old_log_level
end
local function restore_log_level(level)
log.log_level(level)
end
local function pref_read(name, pref_type)
local old_log_level = set_log_level(sm.log_level)
log.msg(log.debug, "name is " .. name .. " and type is " .. pref_type)
local val = dt.preferences.read(MODULE, name, pref_type)
if not string.match(pref_type, "bool") then
log.msg(log.debug, "read value " .. tostring(val))
end
log.msg(log.debug, "read value " .. tostring(val))
restore_log_level(old_log_level)
return val
end
local function pref_write(name, pref_type, value)
dt.preferences.write(MODULE, name, pref_type, value)
local old_log_level = set_log_level(sm.log_level)
log.msg(log.debug, "writing value " .. tostring(value) .. " for name " .. name)
dt.preferences.write(MODULE, name, pref_type, value)
restore_log_level(old_log_level)
end
----------------
-- git interface
----------------
local function get_repo_status(repo)
local old_log_level = set_log_level(sm.log_level)
local p = io.popen("cd " .. repo .. CS .. "git status")
if p then
local data = p:read("*a")
@@ -204,10 +239,12 @@ local function get_repo_status(repo)
return data
end
log.msg(log.error, "unable to get status of " .. repo)
restore_log_level(old_log_level)
return nil
end
local function get_current_repo_branch(repo)
local old_log_level = set_log_level(sm.log_level)
local branch = nil
local p = io.popen("cd " .. repo .. CS .. "git branch --all")
if p then
@@ -226,10 +263,12 @@ local function get_current_repo_branch(repo)
if not branch then
log.msg(log.error, "no current branch detected in repo_data")
end
restore_log_level(old_log_level)
return nil
end
local function get_repo_branches(repo)
local old_log_level = set_log_level(sm.log_level)
local branches = {}
local p = io.popen("cd " .. repo .. CS .. "git pull --all" .. CS .. "git branch --all")
if p then
@@ -246,11 +285,12 @@ local function get_repo_branches(repo)
end
end
end
restore_log_level(old_log_level)
return branches
end
local function is_repo_clean(repo_data)
local old_log_level = set_log_level(sm.log_level)
if string.match(repo_data, "\n%s-%a.-%a:%s-%a%g-\n") then
log.msg(log.info, "repo is dirty")
return false
@@ -258,14 +298,22 @@ local function is_repo_clean(repo_data)
log.msg(log.info, "repo is clean")
return true
end
restore_log_level(old_log_level)
end
local function checkout_repo_branch(repo, branch)
local old_log_level = set_log_level(sm.log_level)
log.msg(log.info, "checkout out branch " .. branch .. " from repository " .. repo)
os.execute("cd " .. repo .. CS .. "git checkout " .. branch)
restore_log_level(old_log_level)
end
--------------------
-- utility functions
--------------------
local function update_combobox_choices(combobox, choice_table, selected)
local old_log_level = set_log_level(sm.log_level)
local items = #combobox
local choices = #choice_table
for i, name in ipairs(choice_table) do
@@ -281,11 +329,14 @@ local function update_combobox_choices(combobox, choice_table, selected)
end
combobox.value = selected
restore_log_level(old_log_level)
end
local function string_trim(str)
local old_log_level = set_log_level(sm.log_level)
local result = string.gsub(str, "^%s+", "")
result = string.gsub(result, "%s+$", "")
restore_log_level(old_log_level)
return result
end
@@ -293,15 +344,22 @@ local function string_dequote(str)
return string.gsub(str, "['\"]", "")
end
------------------
-- script handling
------------------
local function add_script_category(category)
local old_log_level = set_log_level(sm.log_level)
if #sm.categories == 0 or not string.match(du.join(sm.categories, " "), ds.sanitize_lua(category)) then
table.insert(sm.categories, category)
sm.scripts[category] = {}
log.msg(log.debug, "created category " .. category)
end
restore_log_level(old_log_level)
end
local function get_script_doc(script)
local old_log_level = set_log_level(sm.log_level)
local description = nil
f = io.open(LUA_DIR .. PS .. script .. ".lua")
if f then
@@ -314,19 +372,24 @@ local function get_script_doc(script)
log.msg(log.error, _("Cant read from " .. script))
end
if description then
restore_log_level(old_log_level)
return description
else
restore_log_level(old_log_level)
return "No documentation available"
end
end
local function activate(script)
local old_log_level = set_log_level(sm.log_level)
local status = nil -- status of start function
local err = nil -- error message returned if module doesn't start
log.msg(log.info, "activating " .. script.name)
if script.running == false then
script_manager_running_script = script.name
status, err = du.prequire(script.path)
log.msg(log.debug, "prequire returned " .. tostring(status) .. " and for err " .. tostring(err))
script_manager_running_script = nil
if status then
pref_write(script.script_name, "bool", true)
log.msg(log.screen, _("Loaded ") .. script.script_name)
@@ -334,7 +397,7 @@ local function activate(script)
if err ~= true then
log.msg(log.debug, "got lib data")
script.data = err
if script.data.destroy_method and script.data.destroy_method == "hide" then
if script.data.destroy_method and script.data.destroy_method == "hide" and script.data.show and dt.gui.current_view().id == "lighttable" then
script.data.show()
end
else
@@ -351,16 +414,20 @@ local function activate(script)
status = true
pref_write(script.script_name, "bool", true)
end
restore_log_level(old_log_level)
return status
end
local function deactivate(script)
-- presently the lua api doesn't support unloading gui elements however, we
-- can hide libs, so we just mark those as hidden and hide the gui
-- can delete storage
--therefore we just mark then inactive for the next time darktable starts
-- presently the lua api doesn't support unloading lib elements however, we
-- can hide libs, so we just mark those as hidden and hide the gui
-- can delete storages
-- can delete actions
-- can delete selects
-- and mark them inactive for the next time darktable starts
-- deactivate it....
local old_log_level = set_log_level(sm.log_level)
pref_write(script.script_name, "bool", false)
if script.data then
script.data.destroy()
@@ -382,9 +449,11 @@ local function deactivate(script)
log.msg(log.info, "setting " .. script.script_name .. " to not start")
log.msg(log.screen, script.name .. _(" will not start when darktable is restarted"))
end
restore_log_level(old_log_level)
end
local function add_script_name(name, path, category)
local old_log_level = set_log_level(sm.log_level)
log.msg(log.debug, "category is " .. category)
log.msg(log.debug, "name is " .. name)
local script = {
@@ -398,10 +467,14 @@ local function add_script_name(name, path, category)
table.insert(sm.scripts[category], script)
if pref_read(script.script_name, "bool") then
activate(script)
else
pref_write(script.script_name, "bool", false)
end
restore_log_level(old_log_level)
end
local function process_script_data(script_file)
local old_log_level = set_log_level(sm.log_level)
-- the script file supplied is category/filename.filetype
-- the following pattern splits the string into category, path, name, fileename, and filetype
@@ -424,21 +497,53 @@ local function process_script_data(script_file)
-- add the script data
local category,path,name,filename,filetype = string.match(script_file, pattern)
log.msg(log.debug, "category is " .. category)
log.msg(log.debug, "name is " .. name)
add_script_category(category)
if category and name and path then
log.msg(log.debug, "category is " .. category)
log.msg(log.debug, "name is " .. name)
if name then
add_script_category(category)
add_script_name(name, path, category)
end
restore_log_level(old_log_level)
end
local function ensure_lib_in_search_path(line)
local old_log_level = set_log_level(sm.log_level)
set_log_level(log.debug)
log.msg(log.debug, "line is " .. line)
if string.match(line, ds.sanitize_lua(dt.configuration.config_dir .. PS .. "lua" .. PS .. "lib")) then
log.msg(log.debug, line .. " is already in search path, returning...")
return
end
local pattern = dt.configuration.running_os == "windows" and "(.+)\\lib\\.+lua" or "(.+)/lib/.+lua"
local path = string.match(line, pattern)
log.msg(log.debug, "extracted path is " .. path)
log.msg(log.debug, "package.path is " .. package.path)
if not string.match(package.path, ds.sanitize_lua(path)) then
log.msg(log.debug, "path isn't in package.path, adding...")
package.path = package.path .. ";" .. path .. "/?.lua"
log.msg(log.debug, "new package.path is " .. package.path)
end
restore_log_level(old_log_level)
end
local function scan_scripts(script_dir)
local old_log_level = set_log_level(sm.log_level)
local script_count = 0
local find_cmd = "find -L " .. script_dir .. " -name \\*.lua -print | sort"
if dt.configuration.running_os == "windows" then
find_cmd = "dir /b/s " .. script_dir .. "\\*.lua | sort"
find_cmd = "dir /b/s \"" .. script_dir .. "\\*.lua\" | sort"
end
log.msg(log.debug, _("find command is ") .. find_cmd)
-- scan the scripts
@@ -453,14 +558,18 @@ local function scan_scripts(script_dir)
process_script_data(script_file)
script_count = script_count + 1
end
else
ensure_lib_in_search_path(line) -- but let's make sure libraries can be found
end
end
end
end
restore_log_level(old_log_level)
return script_count
end
local function update_scripts()
local old_log_level = set_log_level(sm.log_level)
local result = false
local git = sm.executables.git
@@ -483,10 +592,16 @@ local function update_scripts()
dt.print(_("lua scripts successfully updated"))
end
restore_log_level(old_log_level)
return result
end
--------------
-- UI handling
--------------
local function update_script_update_choices()
local old_log_level = set_log_level(sm.log_level)
local installs = {}
local pref_string = ""
for i, repo in ipairs(sm.installed_repositories) do
@@ -496,9 +611,11 @@ local function update_script_update_choices()
update_combobox_choices(sm.widgets.update_script_choices, installs, 1)
log.msg(log.debug, "repo pref string is " .. pref_string)
pref_write("installed_repos", "string", pref_string)
restore_log_level(old_log_level)
end
local function scan_repositories()
local old_log_level = set_log_level(sm.log_level)
local script_count = 0
local find_cmd = "find -L " .. LUA_DIR .. " -name \\*.git -print | sort"
if dt.configuration.running_os == "windows" then
@@ -533,15 +650,18 @@ local function scan_repositories()
end
end
update_script_update_choices()
restore_log_level(old_log_level)
end
local function install_scripts()
local old_log_level = set_log_level(sm.log_level)
local url = sm.widgets.script_url.text
local category = sm.widgets.new_category.text
if string.match(du.join(sm.categories, " "), ds.sanitize_lua(category)) then
log.msg(log.screen, _("category ") .. category .. _(" is already in use. Please specify a different category name."))
log.msg(log.error, "category " .. category .. " already exists, returning...")
restore_log_level(old_log_level)
return
end
@@ -551,6 +671,7 @@ local function install_scripts()
if not git then
dt.print(_("ERROR: git not found. Install or specify the location of the git executable."))
restore_log_level(old_log_level)
return
end
@@ -592,28 +713,34 @@ local function install_scripts()
dt.print(_("failed to download scripts"))
end
restore_log_level(old_log_level)
return result
end
local function clear_button(number)
local old_log_level = set_log_level(sm.log_level)
local button = sm.widgets.buttons[number]
button.label = ""
button.tooltip = ""
button.sensitive = false
--button.name = ""
--button.name = ""
restore_log_level(old_log_level)
end
local function find_script(category, name)
local old_log_level = set_log_level(sm.log_level)
log.msg(log.debug, "looking for script " .. name .. " in category " .. category)
for _, script in ipairs(sm.scripts[category]) do
if string.match(script.name, "^" .. ds.sanitize_lua(name) .. "$") then
return script
end
end
restore_log_level(old_log_level)
return nil
end
local function populate_buttons(category, first, last)
local old_log_level = set_log_level(sm.log_level)
log.msg(log.debug, "category is " .. category .. " and first is " .. first .. " and last is " .. last)
local button_num = 1
for i = first, last do
@@ -678,9 +805,11 @@ local function populate_buttons(category, first, last)
clear_button(i)
end
end
restore_log_level(old_log_level)
end
local function paginate(direction)
local old_log_level = set_log_level(sm.log_level)
local category = sm.page_status.category
log.msg(log.debug, "category is " .. category)
local num_scripts = #sm.scripts[category]
@@ -732,9 +861,11 @@ local function paginate(direction)
sm.widgets.page_status.label = _("Page ") .. cur_page .. _(" of ") .. max_pages
populate_buttons(category, first, last)
restore_log_level(old_log_level)
end
local function change_category(category)
local old_log_level = set_log_level(sm.log_level)
if not category then
log.msg(log.debug "setting category to selector value " .. sm.widgets.category_selector.value)
sm.page_status.category = sm.widgets.category_selector.value
@@ -744,9 +875,11 @@ local function change_category(category)
end
paginate(2)
restore_log_level(old_log_level)
end
local function change_num_buttons()
local old_log_level = set_log_level(sm.log_level)
cur_buttons = sm.page_status.num_buttons
new_buttons = sm.widgets.num_buttons.value
pref_write("num_buttons", "integer", new_buttons)
@@ -777,9 +910,11 @@ local function change_num_buttons()
log.msg(log.debug, "num_buttons set to " .. sm.page_status.num_buttons)
paginate(2) -- force the buttons to repopulate
sm.widgets.main_menu.selected = 3 -- jump back to start/stop scripts
restore_log_level(old_log_level)
end
local function load_preferences()
local old_log_level = set_log_level(sm.log_level)
-- load the prefs and update settings
-- update_script_choices
local pref_string = pref_read("installed_repos", "string")
@@ -821,16 +956,18 @@ local function load_preferences()
log.msg(log.debug, "set main menu to val " .. val .. " which is " .. sm.widgets.main_menu.value)
log.msg(log.debug, "set main menu to " .. sm.widgets.main_menu.value)
restore_log_level(old_log_level)
end
local function install_module()
local old_log_level = set_log_level(sm.log_level)
if not sm.module_installed then
dt.register_lib(
"script_manager", -- Module name
"script manager", -- Visible name
true, -- expandable
false, -- resetable
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_BOTTOM", 600}}, -- containers
{[dt.gui.views.lighttable] = {"DT_UI_CONTAINER_PANEL_LEFT_BOTTOM", 100}}, -- containers
sm.widgets.main_box,
nil,-- view_enter
nil -- view_leave
@@ -853,67 +990,75 @@ local function install_module()
dt.control.sleep(5000)
dt.print_log("setting sm expanded true")
dt.gui.libs["script_manager"].expanded = true]]
restore_log_level(old_log_level)
end
-- - - - - - - - - - - - - - - - - - - - - - - -
-- M A I N P R O G R A M
-- - - - - - - - - - - - - - - - - - - - - - - -
local repo_data = get_repo_status(LUA_DIR)
local current_branch = get_current_repo_branch(LUA_DIR)
local clean = is_repo_clean(repo_data)
local repo = LUA_DIR
if current_branch then
if sm.executables.git and clean and
(current_branch == "master" or string.match(current_branch, "^API%-")) then -- only make changes to clean branches
local branches = get_repo_branches(LUA_DIR)
if current_branch ~= LUA_API_VER and current_branch ~= "master" then
-- probably upgraded from an earlier api version so get back to master
-- to use the latest version of script_manager to get the proper API
checkout_repo_branch(repo, "master")
log.msg(log.screen, "lua API version reset, please restart darktable")
elseif LUA_API_VER == current_branch then
-- do nothing, we are fine
log.msg(log.debug, "took equal branch, doing nothing")
elseif string.match(LUA_API_VER, "dev") then
-- we are on a dev API version, so checkout the dev
-- api version or checkout/stay on master
log.msg(log.debug, "took the dev branch")
local match = false
for _, branch in ipairs(branches) do
log.msg(log.debug, "checking branch " .. branch .. " against API " .. LUA_API_VER)
if LUA_API_VER == branch then
match = true
log.msg(log.info, "checking out repo development branch " .. branch)
checkout_repo_branch(repo, branch)
-- ensure shortcuts module knows widgets belong to script_manager
script_manager_running_script = "script_manager"
if check_for_updates then
local repo_data = get_repo_status(LUA_DIR)
local current_branch = get_current_repo_branch(LUA_DIR)
local clean = is_repo_clean(repo_data)
local repo = LUA_DIR
if current_branch then
if sm.executables.git and clean and
(current_branch == "master" or string.match(current_branch, "^API%-")) then -- only make changes to clean branches
local branches = get_repo_branches(LUA_DIR)
if current_branch ~= LUA_API_VER and current_branch ~= "master" then
-- probably upgraded from an earlier api version so get back to master
-- to use the latest version of script_manager to get the proper API
checkout_repo_branch(repo, "master")
log.msg(log.screen, "lua API version reset, please restart darktable")
elseif LUA_API_VER == current_branch then
-- do nothing, we are fine
log.msg(log.debug, "took equal branch, doing nothing")
elseif string.match(LUA_API_VER, "dev") then
-- we are on a dev API version, so checkout the dev
-- api version or checkout/stay on master
log.msg(log.debug, "took the dev branch")
local match = false
for _, branch in ipairs(branches) do
log.msg(log.debug, "checking branch " .. branch .. " against API " .. LUA_API_VER)
if LUA_API_VER == branch then
match = true
log.msg(log.info, "checking out repo development branch " .. branch)
checkout_repo_branch(repo, branch)
end
end
end
if not match then
if current_branch == "master" then
log.msg(log.info, "staying on master, no dev branch yet")
else
log.msg(log.info, "no dev branch available, checking out master")
checkout_repo_branch(repo, "master")
if not match then
if current_branch == "master" then
log.msg(log.info, "staying on master, no dev branch yet")
else
log.msg(log.info, "no dev branch available, checking out master")
checkout_repo_branch(repo, "master")
end
end
end
elseif #branches > 0 and LUA_API_VER > branches[#branches] then
log.msg(log.info, "no newer branches, staying on master")
-- stay on master
else
-- checkout the appropriate branch for API version if it exists
log.msg(log.info, "checking out the appropriate API branch")
local match = false
for _, branch in ipairs(branches) do
log.msg(log.debug, "checking branch " .. branch .. " against API " .. LUA_API_VER)
if LUA_API_VER == branch then
match = true
log.msg(log.info, "checking out repo branch " .. branch)
checkout_repo_branch(repo, branch)
log.msg(log.screen, "you must restart darktable to use the correct version of the lua")
elseif #branches > 0 and LUA_API_VER > branches[#branches] then
log.msg(log.info, "no newer branches, staying on master")
-- stay on master
else
-- checkout the appropriate branch for API version if it exists
log.msg(log.info, "checking out the appropriate API branch")
local match = false
for _, branch in ipairs(branches) do
log.msg(log.debug, "checking branch " .. branch .. " against API " .. LUA_API_VER)
if LUA_API_VER == branch then
match = true
log.msg(log.info, "checking out repo branch " .. branch)
checkout_repo_branch(repo, branch)
log.msg(log.screen, "you must restart darktable to use the correct version of the lua")
end
end
if not match then
log.msg(log.warn, "no matching branch found for " .. LUA_API_VER)
end
end
if not match then
log.msg(log.warn, "no matching branch found for " .. LUA_API_VER)
end
end
end
@@ -923,7 +1068,6 @@ scan_scripts(LUA_DIR)
log.msg(log.debug, "finished processing scripts")
-- - - - - - - - - - - - - - - - - - - - - - - -
-- U S E R I N T E R F A C E
-- - - - - - - - - - - - - - - - - - - - - - - -
@@ -1135,6 +1279,7 @@ sm.widgets.main_box = dt.new_widget("box"){
sm.widgets.main_stack
}
script_manager_running_script = nil
-- - - - - - - - - - - - - - - - - - - - - - - -
-- D A R K T A B L E I N T E G R A T I O N