Skip to content

Commit fe78ac4

Browse files
committed
Add maintenance/display of Custom metadata displaying details of most recent upload for an image
1 parent d1778cf commit fe78ac4

10 files changed

Lines changed: 266 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
# Changelog
2+
3+
## [20251224.16] - 2025-12-24
4+
### Added
5+
- Custom metadata displaying details of most recent upload for an image is maintained. Note that if the same image is published via multiple instances of this plugin (for example to different Piwigo hosts) then only details of the most recent upload will be displayed. Details of the previous upload are overwritten. This metadata is for display / information purposes only so the overwrite has no functional impact. Images published with earlier versions of the plugin will not display the metadata - re-publishing them will refresh it. When an image is removed from a published collection this metadata is cleared, regardless of whether it has also been published via a different instance of this plugin.
6+
7+
### Fixed
8+
Fixed #18 Setting up another publish service on a different catalogue generates an error message 'PiwigoAPI.lua 694 attempt to concatenate local statusDes (a nil value) - note this fixes the crash rather than the underlying issue that triggered the crash which is still being investigated
9+
210
## [20251223.15] - 2025-12-23
311
### Fixed
412
- Set Piwigo Album Cover from Selected Photo would only allow setting the cover for the selected photo's album or immediate parent. This fix allow any album cover in the selected photo's album hierarchy to be set to the selected photo

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ A Lightroom Classic plugin which publishes images to a Piwigo host via the Piwig
2323
* New keywords are created if not present in the Piwigo keywords list
2424
* Tag comparison between LrC and Piwigo is not case sensitive - so for example 'This Is A Keyword' and 'this is a keyword' are treated as the same when sending keywords to Piwigo.
2525
* GPS location data is only sent via exif so users of the OpenStreetMap plugin need to ensure that location info is included in the Metadata settings on the LrC Publishing Manager
26+
* The plugin maintains a custom metadata set, Piwigo Publisher Metadata, with details of the most recent publishing activity for an image. NOTE - only images published using release 20251224.16 or later of this plugin will have this metadata.
2627
* Changes to images which trigger a re-publish will overwrite the previously published Piwigo image.
2728
* Images removed from the Publish Service are removed from corresponding album on Piwigo
2829
* Moving a Published Collection under a different Published Collection Set is reflected in the associated Piwigo albums
@@ -34,11 +35,12 @@ A Lightroom Classic plugin which publishes images to a Piwigo host via the Piwig
3435

3536
## The following functionality is under development:
3637

37-
* Consistency Check - check for images missing on Piwigo and update published status accordingly
38+
* Metadata customisation - select which LrC metedata fields are used for Piwigo photo Title and Description fields.
3839
* Metadata Check - check metadata on Piwigo matches Lrc (Title, Caption, GPS, Creator)
3940

4041
## The following functionality is planned:
4142

43+
* Consistency Check - check for images missing on Piwigo and update published status accordingly
4244
* Support for the X-PIWIGO-API header instead of Authorization when sending API keys - v16.1 and above
4345
* Import collection/set/image structure from another publish service
4446
* if remoteIds / URLs are present these will be copied. Useful to copy another publish service where a Piwigo host is the target without having to clear the existing Piwigo albums prior to re-publishing.
@@ -91,6 +93,10 @@ I am investigating whether there is something else causing this but I suspect so
9193

9294
If you see similar errors please check image sizes prior to raising an issue.
9395

96+
## Logging
97+
98+
Windows logs are UTF-16 and need to be opened with UTF-16 encoding
99+
94100
## CREDITS
95101

96102
As a user of both Lightroom Classic and Piwigo, the ability use the powerful Publishing Service in LrC to keep my Piwigo galleries up to date is very appealing. I've been a long time user of a popular plugin that has been providing this functionality, but unfortunately since the version 15 release of LrC that has not been available.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
--[[
2+
3+
CustomeMetadata.lua
4+
5+
Copyright (C) 2024 Fiona Boston <fiona@fbphotography.uk>.
6+
7+
This file is part of PiwigoPublish
8+
9+
This program is free software: you can redistribute it and/or modify
10+
it under the terms of the GNU General Public License as published by
11+
the Free Software Foundation; either version 3 of the License, or
12+
(at your option) any later version.
13+
14+
This program is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
GNU General Public License for more details.
18+
19+
You should have received a copy of the GNU General Public License
20+
along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
]]
22+
23+
24+
25+
return {
26+
schemaVersion = 4,
27+
metadataFieldsForPhotos = {
28+
29+
{
30+
dataType = 'url',
31+
readOnly = true,
32+
searchable = true,
33+
browsable = true,
34+
id = 'pwHostURL',
35+
title = 'Piwigo Host',
36+
version = 3
37+
},
38+
{
39+
dataType = 'string',
40+
readOnly = true,
41+
searchable = true,
42+
browsable = true,
43+
id = 'pwAlbumName',
44+
title = 'Album Name',
45+
version = 2
46+
},
47+
{
48+
dataType = 'url',
49+
readOnly = true,
50+
searchable = false,
51+
browsable = false,
52+
id = 'pwAlbumURL',
53+
title = 'Album URL',
54+
version = 4
55+
},
56+
{
57+
dataType = 'url',
58+
readOnly = true,
59+
searchable = false,
60+
browsable = false,
61+
id = 'pwImageURL',
62+
title = 'Photo URL',
63+
version = 4
64+
},
65+
{
66+
dataType = 'string',
67+
readOnly = true,
68+
searchable = true,
69+
browsable = true,
70+
id = 'pwUploadDate',
71+
title = 'Upload Date',
72+
version = 2
73+
},
74+
{
75+
dataType = 'string',
76+
readOnly = true,
77+
searchable = true,
78+
browsable = true,
79+
id = 'pwUploadTime',
80+
title = 'Upload Time',
81+
version = 2
82+
},
83+
}
84+
}

piwigoPublish.lrplugin/Info.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ return {
2323
LrSdkVersion = 14.3,
2424
LrSdkMinimumVersion = 6.0,
2525
LrPluginName = "Piwigo Publisher",
26+
-- typo in PwigoPublish is noted but can't be changed without forcing all services using this plugin to be re-initialised.
2627
LrToolkitIdentifier = "fiona.boston.PwigoPublish",
27-
28+
LrMetadataProvider = 'CustomMetadata.lua',
29+
LrMetadataTagsetFactory = 'Tagset.lua',
2830
LrInitPlugin = "Init.lua",
2931

3032
LrExportServiceProvider = {
@@ -57,5 +59,5 @@ return {
5759

5860
LrPluginInfoProvider = 'PluginInfo.lua',
5961

60-
VERSION = { major=20251223, minor=15, revision=0 },
62+
VERSION = { major=20251224, minor=16, revision=0 },
6163
}

piwigoPublish.lrplugin/Init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,5 @@ end
7272

7373
_G.PiwigoBusy = false
7474
_G.iconPath = _PLUGIN:resourceId("icons/icon_med.png")
75-
_G.pluginVersion = "20251223.15"
75+
_G.pluginVersion = "20251224.16"
7676

piwigoPublish.lrplugin/PWSendMetadata.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,12 @@ local function SendMetadata()
9696
callStatus = {}
9797
local metaData = {}
9898

99+
-- allow custom metadata selection here
99100
metaData.Creator = lrPhoto:getFormattedMetadata( "creator" ) or ""
100101
metaData.Title = lrPhoto:getFormattedMetadata("title") or ""
101102
metaData.Caption = lrPhoto:getFormattedMetadata("caption") or ""
103+
104+
102105
metaData.fileName = lrPhoto:getFormattedMetadata("fileName") or ""
103106
local lrTime = lrPhoto:getRawMetadata("dateTimeOriginal")
104107
metaData.dateCreated = LrDate.timeToUserFormat(lrTime, "%Y-%m-%d %H:%M:%S")

piwigoPublish.lrplugin/PiwigoAPI.lua

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ function PiwigoAPI.createPublishCollection(catalog, publishService, propertyTabl
531531
]]
532532
return newColl
533533
end
534+
534535
-- *************************************************
535536
function PiwigoAPI.ConnectionChange(propertyTable)
536537
log:info('PublishDialogSections.ConnectionChange')
@@ -543,6 +544,30 @@ function PiwigoAPI.ConnectionChange(propertyTable)
543544
propertyTable.token = ""
544545
end
545546

547+
-- *************************************************
548+
function PiwigoAPI.storeMetaData(catalog, propertyTable, lrPhoto, pluginData)
549+
550+
log:info("PiwigoAPI.storeMetaData - pluginData\n" .. utils.serialiseVar(pluginData))
551+
552+
-- set metadata for photo
553+
catalog:withWriteAccessDo("Updating " .. lrPhoto:getFormattedMetadata("fileName"),
554+
function()
555+
556+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwHostURL",pluginData.pwHostURL)
557+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwAlbumName",pluginData.albumName)
558+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwAlbumURL",pluginData.albumUrl)
559+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwImageURL",pluginData.ImageURL)
560+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwUploadDate",pluginData.pwUploadDate)
561+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwUploadTime",pluginData.pwUploadTime)
562+
563+
end )
564+
565+
566+
-- store mapping between lrPhoto and pwigo id
567+
propertyTable.publishedPhotoMap[pluginData.pwImageID] = lrPhoto.localIdentifier
568+
569+
end
570+
546571
-- *************************************************
547572
function PiwigoAPI.getPublishServicesForPlugin(pluginID)
548573
-- Helper to get all publish service connections for this plugin
@@ -688,7 +713,7 @@ function PiwigoAPI.pwConnect(propertyTable)
688713
statusDes = httpHeaders.error.name
689714
status = httpHeaders.error.errorCode
690715
else
691-
statusDes = httpHeaders.statusDes
716+
statusDes = httpHeaders.statusDes or httpHeaders.statusDesc
692717
status = httpHeaders.status
693718
end
694719
LrDialogs.message("Cannot log in to Piwigo - ", status .. ", " .. statusDes)

piwigoPublish.lrplugin/PublishDialogSections.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ local function prefsDialog (f, propertyTable)
198198
local share = LrView.share
199199

200200
return {
201-
title = "Piwigo Publish Service Configuration Extras",
201+
title = "Piwigo Publish Service Configuration and Options",
202202
bind_to_object = propertyTable,
203203
f:row {
204204
f:static_text {

piwigoPublish.lrplugin/PublishTask.lua

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ function PublishTask.processRenderedPhotos(functionContext, exportContext)
3232
end
3333
PiwigoBusy = true
3434
local callStatus ={}
35+
local catalog = LrApplication.activeCatalog()
3536
local exportSession = exportContext.exportSession
3637
local propertyTable = exportContext.propertyTable
3738
local rv
@@ -54,8 +55,9 @@ function PublishTask.processRenderedPhotos(functionContext, exportContext)
5455
log:info('PublishTask.processRenderedPhotos - publishSettings:\n' .. utils.serialiseVar(propertyTable))
5556

5657
local publishedCollection = exportContext.publishedCollection
57-
local albumId = publishedCollection:getRemoteId()
5858
local albumName = publishedCollection:getName()
59+
local albumId = publishedCollection:getRemoteId()
60+
local albumUrl = publishedCollection:getRemoteUrl()
5961
local parentCollSet = publishedCollection:getParent()
6062
local parentID = ""
6163
local requestRepub = false
@@ -118,9 +120,11 @@ function PublishTask.processRenderedPhotos(functionContext, exportContext)
118120
local filePath = pathOrMessage
119121
local metaData = {}
120122
metaData.Albumid = albumId
123+
-- allow custom metadata selection here
121124
metaData.Creator = lrPhoto:getFormattedMetadata( "creator" ) or ""
122125
metaData.Title = lrPhoto:getFormattedMetadata("title") or ""
123126
metaData.Caption = lrPhoto:getFormattedMetadata("caption") or ""
127+
124128
metaData.fileName = lrPhoto:getFormattedMetadata("fileName") or ""
125129
local lrTime = lrPhoto:getRawMetadata("dateTimeOriginal")
126130
metaData.dateCreated = LrDate.timeToUserFormat(lrTime, "%Y-%m-%d %H:%M:%S")
@@ -139,7 +143,20 @@ function PublishTask.processRenderedPhotos(functionContext, exportContext)
139143
rendition:recordPublishedPhotoId(callStatus.remoteid or "")
140144
rendition:recordPublishedPhotoUrl(callStatus.remoteurl or "")
141145
rendition:renditionIsDone(true)
142-
146+
-- set metadata for photo
147+
148+
catalog:withWriteAccessDo("Updating " .. lrPhoto:getFormattedMetadata("fileName"),
149+
function()
150+
151+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwHostURL",propertyTable.host)
152+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwAlbumName",albumName)
153+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwAlbumURL",albumUrl)
154+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwImageURL",callStatus.remoteurl)
155+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwUploadDate",os.date("%Y-%m-%d"))
156+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwUploadTime",os.date("%H:%M:%S"))
157+
158+
end )
159+
143160
-- photo was uploaded with keywords included, but existing keywords aren't replaced by this process,
144161
-- so force a metadata update using pwg.images.setInfo with single_value_mode set to "replace" to force old metadata/keywords to be replaced
145162
metaData.Remoteid = callStatus.remoteid
@@ -190,10 +207,32 @@ function PublishTask.deletePhotosFromPublishedCollection(publishSettings, arrayO
190207
end
191208
PiwigoBusy = true
192209
local callStatus ={}
210+
local errStatus = ""
193211

194212

213+
-- build tables to allow access to catalog LrPhoto object
195214
local catalog = LrApplication.activeCatalog()
196215
local publishedCollection = catalog:getPublishedCollectionByLocalIdentifier(localCollectionId)
216+
local publishedPhotos = publishedCollection:getPublishedPhotos()
217+
local photosToUnpublish = {}
218+
local pubPhotoByRemoteID = {}
219+
for _, pubPhoto in pairs(publishedPhotos) do
220+
pubPhotoByRemoteID[pubPhoto:getRemoteId()] = pubPhoto
221+
end
222+
223+
-- build table of photo objects for each item in arrayofphotoids
224+
for i = 1, #arrayOfPhotoIds do
225+
local pwImageID = arrayOfPhotoIds[i]
226+
local pubPhoto = pubPhotoByRemoteID[pwImageID]
227+
local lrphoto = pubPhoto:getPhoto()
228+
photosToUnpublish[i] = {}
229+
photosToUnpublish[i][1] = lrphoto
230+
photosToUnpublish[i][2] = pwImageID
231+
photosToUnpublish[i][3] = pubPhoto
232+
end
233+
234+
local pwCatID = publishedCollection:getRemoteId()
235+
197236

198237
-- check connection to piwigo
199238
if not (publishSettings.Connected) then
@@ -205,14 +244,52 @@ function PublishTask.deletePhotosFromPublishedCollection(publishSettings, arrayO
205244
end
206245
end
207246

247+
-- set up async prococess for piwigo calls
248+
LrTasks.startAsyncTask(function ()
249+
-- now go through each photo in photosToUnpublish and renove from Piwigo
250+
for i, thisPhotoToUnpublish in pairs(photosToUnpublish) do
251+
local thisLrPhoto = thisPhotoToUnpublish[1]
252+
local thispwImageID = thisPhotoToUnpublish[2]
253+
local thisPubPhoto = thisPhotoToUnpublish[3]
254+
callStatus = PiwigoAPI.deletePhoto(publishSettings, pwCatID, thispwImageID, callStatus)
255+
if callStatus.status then
256+
catalog:withWriteAccessDo("Updating " .. thisLrPhoto:getFormattedMetadata("fileName"),
257+
function()
258+
259+
thisLrPhoto:setPropertyForPlugin(_PLUGIN,"pwHostURL","")
260+
thisLrPhoto:setPropertyForPlugin(_PLUGIN,"pwAlbumName","")
261+
thisLrPhoto:setPropertyForPlugin(_PLUGIN,"pwAlbumURL","")
262+
thisLrPhoto:setPropertyForPlugin(_PLUGIN,"pwImageURL","")
263+
thisLrPhoto:setPropertyForPlugin(_PLUGIN,"pwUploadDate","")
264+
thisLrPhoto:setPropertyForPlugin(_PLUGIN,"pwUploadTime","")
265+
end )
266+
thisPhotoToUnpublish[4] = true
267+
else
268+
PiwigoBusy = false
269+
LrErrors.throwUserError('Failed to delete photo ' .. pwImageID .. ' from Piwigo - ' .. callStatus.statusMsg, 'Failed to delete photo')
270+
end
271+
272+
273+
end
274+
end, errStatus )
275+
--[[
208276
for i = 1, #arrayOfPhotoIds do
209277
local pwImageID = arrayOfPhotoIds[i]
210-
local pwCatID = publishedCollection:getRemoteId()
211-
278+
212279
-- check if image is another album on Piwigo
213280
-- if not, can delete image,otherwise remove association with this ablum
214281
215282
callStatus = PiwigoAPI.deletePhoto(publishSettings,pwCatID,pwImageID, callStatus)
283+
284+
-- remove custom metadata from photo
285+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwHostURL",propertyTable.host)
286+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwAlbumName",albumName)
287+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwAlbumURL",albumUrl)
288+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwImageURL",callStatus.remoteurl)
289+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwUploadDate",os.date("%Y-%m-%d"))
290+
lrPhoto:setPropertyForPlugin(_PLUGIN,"pwUploadTime",os.date("%H:%M:%S"))
291+
292+
216293
if callStatus.status then
217294
deletedCallback(arrayOfPhotoIds[i])
218295
else
@@ -221,6 +298,13 @@ function PublishTask.deletePhotosFromPublishedCollection(publishSettings, arrayO
221298
end
222299
deletedCallback( pwImageID)
223300
end
301+
]]
302+
-- now finish process via deletedCallback
303+
for i, thisPhotoToUnpublish in pairs(photosToUnpublish) do
304+
local thispwImageID = thisPhotoToUnpublish[2]
305+
deletedCallback(thispwImageID)
306+
end
307+
224308
PiwigoBusy = false
225309
end
226310

0 commit comments

Comments
 (0)