-
Notifications
You must be signed in to change notification settings - Fork 2
/
StippleExportServiceProvider.lua
684 lines (582 loc) · 29.3 KB
/
StippleExportServiceProvider.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
-- Lightroom SDK
local LrBinding = import 'LrBinding'
local LrDialogs = import 'LrDialogs'
local LrErrors = import 'LrErrors'
local LrFileUtils = import 'LrFileUtils'
local LrPathUtils = import 'LrPathUtils'
local LrView = import 'LrView'
local logger = import 'LrLogger'( 'StippleAPI' )
logger:enable('print')
-- Common shortcuts
local bind = LrView.bind
local share = LrView.share
-- JSON Reading/Writing
local JSON = require 'json'
-- Stipple plug-in
require 'StippleAPI'
require 'StipplePublishSupport'
local exportServiceProvider = {}
-- A typical service provider would probably roll all of this into one file, but
-- this approach allows us to document the publish-specific hooks separately.
for name, value in pairs( StipplePublishSupport ) do
exportServiceProvider[ name ] = value
end
exportServiceProvider.supportsIncrementalPublish = 'only'
--------------------------------------------------------------------------------
--- (optional) Plug-in defined value declares which fields in your property table should
-- be saved as part of an export preset or a publish service connection. If present,
-- should contain an array of items with key and default values. For example:
-- <pre>
-- exportPresetFields = {<br/>
-- { key = 'username', default = "" },<br/>
-- { key = 'fullname', default = "" },<br/>
-- { key = 'nsid', default = "" },<br/>
-- { key = 'privacy', default = 'public' },<br/>
-- { key = 'privacy_family', default = false },<br/>
-- { key = 'privacy_friends', default = false },<br/>
-- }<br/>
-- </pre>
-- <p>The <code>key</code> item should match the values used by your user interface
-- controls.</p>
-- <p>The <code>default</code> item is the value to the first time
-- your plug-in is selected in the Export or Publish dialog. On second and subsequent
-- activations, the values chosen by the user in the previous session are used.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @name exportServiceProvider.exportPresetFields
-- @class property
exportServiceProvider.exportPresetFields = {
{ key = 'username', default = "" },
{ key = 'fullname', default = "" },
{ key = 'nsid', default = "" },
-- { key = 'isUserPro', default = false },
-- { key = 'auth_token', default = '' },
-- { key = 'privacy', default = 'public' },
-- { key = 'privacy_family', default = false },
-- { key = 'privacy_friends', default = false },
-- { key = 'safety', default = 'safe' },
-- { key = 'hideFromPublic', default = false },
{ key = 'type', default = 'photo' },
{ key = 'addToPhotoset', default = false },
{ key = 'photoset', default = '' },
{ key = 'titleFirstChoice', default = 'title' },
{ key = 'titleSecondChoice', default = 'filename' },
{ key = 'titleRepublishBehavior', default = 'replace' },
}
--------------------------------------------------------------------------------
--- (optional) Plug-in defined value restricts the display of sections in the Export
-- or Publish dialog to those named. You can use either <code>hideSections</code> or
-- <code>showSections</code>, but not both. If present, this should be an array
-- containing one or more of the following strings:
-- <ul>
-- <li>exportLocation</li>
-- <li>fileNaming</li>
-- <li>fileSettings</li>
-- <li>imageSettings</li>
-- <li>outputSharpening</li>
-- <li>metadata</li>
-- <li>watermarking</li>
-- </ul>
-- <p>You cannot suppress display of the "Connection Name" section in the Publish Manager dialog.</p>
-- <p>If you suppress the "exportLocation" section, the files are rendered into
-- a temporary folder which is deleted immediately after the Export operation
-- completes.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @name exportServiceProvider.showSections
-- @class property
--exportServiceProvider.showSections = { 'fileNaming', 'fileSettings', etc... } -- not used for Stipple plug-in
--------------------------------------------------------------------------------
--- (optional) Plug-in defined value suppresses the display of the named sections in
-- the Export or Publish dialogs. You can use either <code>hideSections</code> or
-- <code>showSections</code>, but not both. If present, this should be an array
-- containing one or more of the following strings:
-- <ul>
-- <li>exportLocation</li>
-- <li>fileNaming</li>
-- <li>fileSettings</li>
-- <li>imageSettings</li>
-- <li>outputSharpening</li>
-- <li>metadata</li>
-- <li>watermarking</li>
-- </ul>
-- <p>You cannot suppress display of the "Connection Name" section in the Publish Manager dialog.</p>
-- <p>If you suppress the "exportLocation" section, the files are rendered into
-- a temporary folder which is deleted immediately after the Export operation
-- completes.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @name exportServiceProvider.hideSections
-- @class property
exportServiceProvider.hideSections = {'exportLocation', 'fileNaming', 'video'}
--------------------------------------------------------------------------------
--- (optional, Boolean) If your plug-in allows the display of the exportLocation section,
-- this property controls whether the item "Temporary folder" is available.
-- If the user selects this option, the files are rendered into a temporary location
-- on the hard drive, which is deleted when the export finished.
-- <p>If your plug-in hides the exportLocation section, this temporary
-- location behavior is always used.</p>
-- @name exportServiceProvider.canExportToTemporaryLocation
-- @class property
-- exportServiceProvider.canExportToTemporaryLocation = true -- not used for Stipple plug-in
--------------------------------------------------------------------------------
--- (optional) Plug-in defined value restricts the available file format choices in the
-- Export or Publish dialogs to those named. You can use either <code>allowFileFormats</code> or
-- <code>disallowFileFormats</code>, but not both. If present, this should be an array
-- containing one or more of the following strings:
-- <ul>
-- <li>JPEG</li>
-- <li>PSD</li>
-- <li>TIFF</li>
-- <li>DNG</li>
-- <li>ORIGINAL</li>
-- </ul>
-- <p>This property affects the output of still photo files only;
-- it does not affect the output of video files.
-- See <a href="#exportServiceProvider.canExportVideo"><code>canExportVideo</code></a>.)</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @name exportServiceProvider.allowFileFormats
-- @class property
exportServiceProvider.allowFileFormats = {'JPEG'}
--------------------------------------------------------------------------------
--- (optional) Plug-in defined value suppresses the named file formats from the list
-- of available file format choices in the Export or Publish dialogs.
-- You can use either <code>allowFileFormats</code> or
-- <code>disallowFileFormats</code>, but not both. If present,
-- this should be an array containing one or more of the following strings:
-- <ul>
-- <li>JPEG</li>
-- <li>PSD</li>
-- <li>TIFF</li>
-- <li>DNG</li>
-- <li>ORIGINAL</li>
-- </ul>
-- <p>Affects the output of still photo files only, not video files.
-- See <a href="#exportServiceProvider.canExportVideo"><code>canExportVideo</code></a>.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @name exportServiceProvider.disallowFileFormats
-- @class property
--exportServiceProvider.disallowFileFormats = { 'PSD', 'TIFF', 'DNG', 'ORIGINAL' } -- not used for Stipple plug-in
--------------------------------------------------------------------------------
--- (optional) Plug-in defined value restricts the available color space choices in the
-- Export or Publish dialogs to those named. You can use either <code>allowColorSpaces</code> or
-- <code>disallowColorSpaces</code>, but not both. If present, this should be an array
-- containing one or more of the following strings:
-- <ul>
-- <li>sRGB</li>
-- <li>AdobeRGB</li>
-- <li>ProPhotoRGB</li>
-- </ul>
-- <p>Affects the output of still photo files only, not video files.
-- See <a href="#exportServiceProvider.canExportVideo"><code>canExportVideo</code></a>.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @name exportServiceProvider.allowColorSpaces
-- @class property
exportServiceProvider.allowColorSpaces = {'sRGB'}
--------------------------------------------------------------------------------
--- (optional) Plug-in defined value suppresses the named color spaces from the list
-- of available color space choices in the Export or Publish dialogs. You can use either <code>allowColorSpaces</code> or
-- <code>disallowColorSpaces</code>, but not both. If present, this should be an array
-- containing one or more of the following strings:
-- <ul>
-- <li>sRGB</li>
-- <li>AdobeRGB</li>
-- <li>ProPhotoRGB</li>
-- </ul>
-- <p>Affects the output of still photo files only, not video files.
-- See <a href="#exportServiceProvider.canExportVideo"><code>canExportVideo</code></a>.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @name exportServiceProvider.disallowColorSpaces
-- @class property
--exportServiceProvider.disallowColorSpaces = { 'AdobeRGB', 'ProPhotoRGB' } -- not used for Stipple plug-in
--------------------------------------------------------------------------------
--- (optional, Boolean) Plug-in defined value is true to hide print resolution controls
-- in the Image Sizing section of the Export or Publish dialog.
-- (Recommended when uploading to most web services.)
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @name exportServiceProvider.hidePrintResolution
-- @class property
exportServiceProvider.hidePrintResolution = true
--------------------------------------------------------------------------------
--- (optional, Boolean) When plug-in defined value istrue, both video and
-- still photos can be exported through this plug-in. If not present or set to false,
-- video files cannot be exported through this plug-in. If set to the string "only",
-- video files can be exported, but not still photos.
-- <p>No conversions are available for video files. They are simply
-- copied in the same format that was originally imported into Lightroom.</p>
-- <p>First supported in version 3.0 of the Lightroom SDK.</p>
-- @name exportServiceProvider.canExportVideo
-- @class property
exportServiceProvider.canExportVideo = false -- video is not supported through this sample plug-in
--------------------------------------------------------------------------------
-- FLICKR SPECIFIC: Helper functions and tables.
local function updateCantExportBecause( propertyTable )
if not propertyTable.validAccount then
propertyTable.LR_cantExportBecause = LOC "$$$/Stipple/ExportDialog/NoLogin=You haven't logged in to Stipple yet."
return
end
propertyTable.LR_cantExportBecause = nil
end
local displayNameForTitleChoice = {
filename = LOC "$$$/Stipple/ExportDialog/Title/Filename=Filename",
title = LOC "$$$/Stipple/ExportDialog/Title/Title=IPTC Title",
empty = LOC "$$$/Stipple/ExportDialog/Title/Empty=Leave Blank",
}
--local kSafetyTitles = {
-- safe = LOC "$$$/Stipple/ExportDialog/Safety/Safe=Safe",
-- moderate = LOC "$$$/Stipple/ExportDialog/Safety/Moderate=Moderate",
-- restricted = LOC "$$$/Stipple/ExportDialog/Safety/Restricted=Restricted",
--}
local function booleanToNumber( value )
return value and 1 or 0
end
local privacyToNumber = {
private = 0,
public = 1,
}
local safetyToNumber = {
safe = 1,
moderate = 2,
restricted = 3,
}
local contentTypeToNumber = {
photo = 1,
screenshot = 2,
other = 3,
}
local function getStippleTitle( photo, exportSettings, pathOrMessage )
local title
-- Get title according to the options in Stipple Title section.
if exportSettings.titleFirstChoice == 'filename' then
title = LrPathUtils.leafName( pathOrMessage )
elseif exportSettings.titleFirstChoice == 'title' then
title = photo:getFormattedMetadata 'title'
if ( not title or #title == 0 ) and exportSettings.titleSecondChoice == 'filename' then
title = LrPathUtils.leafName( pathOrMessage )
end
end
return title
end
--------------------------------------------------------------------------------
--- (optional) This plug-in defined callback function is called when the
-- user chooses this export service provider in the Export or Publish dialog,
-- or when the destination is already selected when the dialog is invoked,
-- (remembered from the previous export operation).
-- <p>This is a blocking call. If you need to start a long-running task (such as
-- network access), create a task using the <a href="LrTasks.html"><code>LrTasks</code></a>
-- namespace.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @param propertyTable (table) An observable table that contains the most
-- recent settings for your export or publish plug-in, including both
-- settings that you have defined and Lightroom-defined export settings
-- @name exportServiceProvider.startDialog
-- @class function
function exportServiceProvider.startDialog( propertyTable )
-- Clear login if it's a new connection.
if not propertyTable.LR_editingExistingPublishConnection then
propertyTable.username = nil
propertyTable.nsid = nil
end
-- Can't export until we've validated the login.
propertyTable:addObserver( 'validAccount', function() updateCantExportBecause( propertyTable ) end )
updateCantExportBecause( propertyTable )
-- Make sure we're logged in.
require 'StippleUser'
StippleUser.verifyLogin( propertyTable )
end
--------------------------------------------------------------------------------
--- (optional) This plug-in defined callback function is called when the user
-- chooses a different export service provider in the Export or Publish dialog
-- or closes the dialog.
-- <p>This is a blocking call. If you need to start a long-running task (such as
-- network access), create a task using the <a href="LrTasks.html"><code>LrTasks</code></a>
-- namespace.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @param propertyTable (table) An observable table that contains the most
-- recent settings for your export or publish plug-in, including both
-- settings that you have defined and Lightroom-defined export settings
-- @param why (string) The reason this function was called. One of
-- 'ok', 'cancel', or 'changedServiceProvider'
-- @name exportServiceProvider.endDialog
-- @class function
--function exportServiceProvider.endDialog( propertyTable )
-- not used for Stipple plug-in
--end
--------------------------------------------------------------------------------
--- (optional) This plug-in defined callback function is called when the user
-- chooses this export service provider in the Export or Publish dialog.
-- It can create new sections that appear above all of the built-in sections
-- in the dialog (except for the Publish Service section in the Publish dialog,
-- which always appears at the very top).
-- <p>Your plug-in's <a href="#exportServiceProvider.startDialog"><code>startDialog</code></a>
-- function, if any, is called before this function is called.</p>
-- <p>This is a blocking call. If you need to start a long-running task (such as
-- network access), create a task using the <a href="LrTasks.html"><code>LrTasks</code></a>
-- namespace.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @param f (<a href="LrView.html#LrView.osFactory"><code>LrView.osFactory</code> object)
-- A view factory object.
-- @param propertyTable (table) An observable table that contains the most
-- recent settings for your export or publish plug-in, including both
-- settings that you have defined and Lightroom-defined export settings
-- @return (table) An array of dialog sections (see example code for details)
-- @name exportServiceProvider.sectionsForTopOfDialog
-- @class function
function exportServiceProvider.sectionsForTopOfDialog( f, propertyTable )
return {
{
title = LOC "$$$/Stipple/ExportDialog/Account=Stipple Account",
synopsis = bind 'accountStatus',
f:row {
spacing = f:control_spacing(),
f:static_text {
title = bind 'accountStatus',
alignment = 'right',
fill_horizontal = 1,
},
f:push_button {
width = tonumber( LOC "$$$/locale_metric/Stipple/ExportDialog/LoginButton/Width=90" ),
title = bind 'loginButtonTitle',
enabled = bind 'loginButtonEnabled',
action = function()
require 'StippleUser'
StippleUser.login(propertyTable)
end,
},
},
},{
title = LOC "$$$/Stipple/ExportDialog/Title=Stipple Title",
synopsis = function(props)
if props.titleFirstChoice == 'title' then
return LOC("$$$/Stipple/ExportDialog/Synopsis/TitleWithFallback=IPTC Title or ^1", displayNameForTitleChoice[ props.titleSecondChoice ])
else
return props.titleFirstChoice and displayNameForTitleChoice[ props.titleFirstChoice ] or ''
end
end,
f:column {
spacing = f:control_spacing(),
f:row {
spacing = f:label_spacing(),
f:static_text {
title = LOC "$$$/Stipple/ExportDialog/ChooseTitleBy=Set Stipple Title Using:",
alignment = 'right',
width = share 'stippleTitleSectionLabel',
},
f:popup_menu {
value = bind 'titleFirstChoice',
width = share 'stippleTitleLeftPopup',
items = {
{ value = 'filename', title = displayNameForTitleChoice.filename },
{ value = 'title', title = displayNameForTitleChoice.title },
{ value = 'empty', title = displayNameForTitleChoice.empty },
},
},
f:spacer { width = 20 },
f:static_text {
title = LOC "$$$/Stipple/ExportDialog/ChooseTitleBySecondChoice=If Empty, Use:",
enabled = LrBinding.keyEquals( 'titleFirstChoice', 'title', propertyTable ),
},
f:popup_menu {
value = bind 'titleSecondChoice',
enabled = LrBinding.keyEquals( 'titleFirstChoice', 'title', propertyTable ),
items = {
{ value = 'filename', title = displayNameForTitleChoice.filename },
{ value = 'empty', title = displayNameForTitleChoice.empty },
},
},
},
f:row {
spacing = f:label_spacing(),
f:static_text {
title = LOC "$$$/Stipple/ExportDialog/OnUpdate=When Updating Photos:",
alignment = 'right',
width = share 'stippleTitleSectionLabel',
},
f:popup_menu {
value = bind 'titleRepublishBehavior',
width = share 'stippleTitleLeftPopup',
items = {
{ value = 'replace', title = LOC "$$$/Stipple/ExportDialog/ReplaceExistingTitle=Replace Existing Title" },
{ value = 'leaveAsIs', title = LOC "$$$/Stipple/ExportDialog/LeaveAsIs=Leave Existing Title" },
},
},
},
},
},
}
end
--------------------------------------------------------------------------------
--- (optional) This plug-in defined callback function is called when the user
-- chooses this export service provider in the Export or Publish dialog.
-- It can create new sections that appear below all of the built-in sections in the dialog.
-- <p>Your plug-in's <a href="#exportServiceProvider.startDialog"><code>startDialog</code></a>
-- function, if any, is called before this function is called.</p>
-- <p>This is a blocking call. If you need to start a long-running task (such as
-- network access), create a task using the <a href="LrTasks.html"><code>LrTasks</code></a>
-- namespace.</p>
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @param f (<a href="LrView.html#LrView.osFactory"><code>LrView.osFactory</code> object)
-- A view factory object
-- @param propertyTable (table) An observable table that contains the most
-- recent settings for your export or publish plug-in, including both
-- settings that you have defined and Lightroom-defined export settings
-- @return (table) An array of dialog sections (see example code for details)
-- @name exportServiceProvider.sectionsForBottomOfDialog
-- @class function
--------------------------------------------------------------------------------
--- (optional) This plug-in defined callback function is called at the beginning
-- of each export and publish session before the rendition objects are generated.
-- It provides an opportunity for your plug-in to modify the export settings.
-- <p>First supported in version 2.0 of the Lightroom SDK.</p>
-- @param exportSettings (table) The current export settings.
-- @name exportServiceProvider.updateExportSettings
-- @class function
--function exportServiceProvider.updateExportSettings( exportSettings ) -- not used for the Stipple sample plug-in
-- exportSettings.LR_format = 'JPEG'
-- exportSettings.LR_jpeg_quality = 100
-- end
--------------------------------------------------------------------------------
--- (optional) This plug-in defined callback function is called for each exported photo
-- after it is rendered by Lightroom and after all post-process actions have been
-- applied to it. This function is responsible for transferring the image file
-- to its destination, as defined by your plug-in. The function that
-- you define is launched within a cooperative task that Lightroom provides. You
-- do not need to start your own task to run this function; and in general, you
-- should not need to start another task from within your processing function.
-- <p>First supported in version 1.3 of the Lightroom SDK.</p>
-- @param functionContext (<a href="LrFunctionContext.html"><code>LrFunctionContext</code></a>)
-- function context that you can use to attach clean-up behaviors to this
-- process; this function context terminates as soon as your function exits.
-- @param exportContext (<a href="LrExportContext.html"><code>LrExportContext</code></a>)
-- Information about your export settings and the photos to be published.
function exportServiceProvider.processRenderedPhotos( functionContext, exportContext )
local exportSession = exportContext.exportSession -- Make a local reference to the export parameters.
local exportSettings = assert( exportContext.propertyTable )
local nPhotos = exportSession:countRenditions() -- Get the # of photos.
-- Set progress title.
local progressScope = exportContext:configureProgress {
title = nPhotos > 1
and LOC( "$$$/Stipple/Publish/Progress=Publishing ^1 photos to Stipple", nPhotos )
or LOC "$$$/Stipple/Publish/Progress/One=Publishing one photo to Stipple",
}
local uploadedPhotoIds = {} -- Save off uploaded photo IDs so we can take user to those photos later.
local publishedCollectionInfo = exportContext.publishedCollectionInfo
local isDefaultCollection = publishedCollectionInfo.isDefaultCollection
-- Look for a photoset id for this collection.
local photosetId = publishedCollectionInfo.remoteId
-- Get a list of photos already in this photoset so we know which ones we can replace and which have
-- to be re-uploaded entirely.
local photosetPhotos = photosetId and StippleAPI.listPhotosFromPhotoset( exportSettings, { photosetId = photosetId } )
local photosetPhotosSet = {} -- Turn it into a set for quicker access later.
local couldNotPublishBecauseFreeAccount = {}
local stipplePhotoIdsForRenditions = {}
local photosetUrl
for i, rendition in exportContext:renditions { stopIfCanceled = true } do
progressScope:setPortionComplete( ( i - 1 ) / nPhotos ) -- Update progress scope.
local photo = rendition.photo -- Get next photo.
local stipplePhotoId = rendition.publishedPhotoId -- See if we previously uploaded this photo.
if not rendition.wasSkipped then
local success, pathOrMessage = rendition:waitForRender() -- Update progress scope again once we've got rendered photo.
progressScope:setPortionComplete( ( i - 0.5 ) / nPhotos ) -- Check for cancellation again after photo has been rendered.
if progressScope:isCanceled() then break end
if success then
local title = getStippleTitle( photo, exportSettings, pathOrMessage ) -- Build up common metadata for this photo.
local description = photo:getFormattedMetadata( 'caption' )
local keywordTags = photo:getFormattedMetadata( 'keywordTagsForExport' )
local tags
if keywordTags then
tags = {}
local keywordIter = string.gfind( keywordTags, "[^,]+" )
for keyword in keywordIter do
if string.sub( keyword, 1, 1 ) == ' ' then
keyword = string.sub( keyword, 2, -1 )
end
if string.find( keyword, ' ' ) ~= nil then
keyword = '"' .. keyword .. '"'
end
tags[ #tags + 1 ] = keyword
end
end
local content_type = contentTypeToNumber[ exportSettings.type ]
local previous_tags = photo:getPropertyForPlugin( _PLUGIN, 'previous_tags' )
local didReplace = not not stipplePhotoId
stipplePhotoId = StippleAPI.uploadPhoto(exportSettings, {
id = stipplePhotoId,
filePath = pathOrMessage,
photo = {
caption = description,
source_page = ""
},
claim = 1, -- always claim the photo
}
)
-- if didReplace then
-- -- The replace call used by StippleAPI.uploadPhoto ignores all of the metadata that is passed
-- -- in above. We have to manually upload that info after the fact in this case.
-- if exportSettings.titleRepublishBehavior == 'replace' then
-- --StippleAPI.callRestMethod( exportSettings, {
-- --method = 'stipple.photos.setMeta',
-- --photo_id = stipplePhotoId,
-- --title = title or '',
-- --description = description or '',
-- --})
-- end
-- end
-- When done with photo, delete temp file. There is a cleanup step that happens later,
-- but this will help manage space in the event of a large upload.
LrFileUtils.delete( pathOrMessage )
-- Remember this in the list of photos we uploaded.
uploadedPhotoIds[ #uploadedPhotoIds + 1 ] = stipplePhotoId
-- If this isn't the Photostream, set up the photoset.
if not photosetUrl then
if not isDefaultCollection then
-- Create or update this photoset.
photosetUrl = 'https://stipple.com'
photosetId, photosetUrl = StippleAPI.createOrUpdatePhotoset(exportSettings, {
photosetId = photosetId,
name = publishedCollectionInfo.name,
description = '',
primary_photo_id = uploadedPhotoIds[ 1 ],
})
else
photosetUrl = StippleAPI.constructPhotostreamURL( exportSettings ) -- Photostream: find the URL.
end
end
rendition:recordPublishedPhotoId(stipplePhotoId) -- Record this Stipple ID with the photo so we know to replace instead of upload.
local photoUrl
if (not isDefaultCollection) then
photoUrl = StippleAPI.constructPhotoURL(exportSettings, {
id = stipplePhotoId,
photosetId = photosetId,
})
-- Add the uploaded photos to the correct photoset.
StippleAPI.addPhotosToSet(exportSettings, {
photoId = stipplePhotoId,
photosetId = photosetId,
})
else
photoUrl = StippleAPI.constructPhotoURL(exportSettings, {
id = stipplePhotoId,
})
end
rendition:recordPublishedPhotoUrl( photoUrl )
-- Because it is common for Stipple users (even viewers) to add additional tags
-- via the Stipple web site, so we can avoid removing those user-added tags that
-- were never in Lightroom to begin with. See earlier comment.
photo.catalog:withPrivateWriteAccessDo(function()
photo:setPropertyForPlugin( _PLUGIN, 'previous_tags', table.concat( tags, ',' ) )
end )
end
else
-- To get the skipped photo out of the to-republish bin.
rendition:recordPublishedPhotoId(rendition.publishedPhotoId)
end
end
if #uploadedPhotoIds > 0 then
if (not isDefaultCollection) then
exportSession:recordRemoteCollectionId( photosetId )
end
-- Set up some additional metadata for this collection.
exportSession:recordRemoteCollectionUrl( photosetUrl )
end
progressScope:done()
end
--------------------------------------------------------------------------------
return exportServiceProvider