Initial Commit
This commit is contained in:
BIN
LR Plugin Instructions.pdf
Normal file
BIN
LR Plugin Instructions.pdf
Normal file
Binary file not shown.
36
photonodes.lrplugin/Info.lua
Normal file
36
photonodes.lrplugin/Info.lua
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--[[----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Info.lua
|
||||||
|
Summary information for ftp_upload sample plug-in
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ADOBE SYSTEMS INCORPORATED
|
||||||
|
Copyright 2007 Adobe Systems Incorporated
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
|
||||||
|
with the terms of the Adobe license agreement accompanying it. If you have received
|
||||||
|
this file from a source other than Adobe, then your use, modification, or distribution
|
||||||
|
of it requires the prior written permission of Adobe.
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------]]
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
LrSdkVersion = 3.0,
|
||||||
|
LrSdkMinimumVersion = 1.3, -- minimum SDK version required by this plug-in
|
||||||
|
|
||||||
|
LrToolkitIdentifier = 'com.photonodes.lightroom.export.web_upload',
|
||||||
|
|
||||||
|
LrPluginName = LOC "$$$/photonodes/PluginName=Photonodes Export Plugin",
|
||||||
|
|
||||||
|
LrExportServiceProvider = {
|
||||||
|
title = "PhotoNodes",
|
||||||
|
file = 'PhotonodesUploadServiceProvider.lua',
|
||||||
|
},
|
||||||
|
|
||||||
|
VERSION = { major=1, minor=2, revision=0, },
|
||||||
|
|
||||||
|
}
|
||||||
168
photonodes.lrplugin/PhotonodesUploadExportDialogSections.lua
Normal file
168
photonodes.lrplugin/PhotonodesUploadExportDialogSections.lua
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
-- Lightroom SDK
|
||||||
|
local LrView = import 'LrView'
|
||||||
|
|
||||||
|
--============================================================================--
|
||||||
|
|
||||||
|
PhotonodesUploadExportDialogSections = {}
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local function updateExportStatus( propertyTable )
|
||||||
|
|
||||||
|
local message = nil
|
||||||
|
|
||||||
|
repeat
|
||||||
|
-- Use a repeat loop to allow easy way to "break" out.
|
||||||
|
-- (It only goes through once.)
|
||||||
|
|
||||||
|
if propertyTable.client_id == nil or propertyTable.client_id == "" then
|
||||||
|
message = LOC "$$$/Photonodes/ExportDialog/Messages/SelectPreset=Enter a PhotoNodes Client Id"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if propertyTable.event_code == nil or propertyTable.event_code == "" then
|
||||||
|
message = LOC "$$$/Photonodes/ExportDialog/Messages/SelectPreset=Enter a PhotoNodes Event Code"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
if propertyTable.gallery_name == nil or propertyTable.gallery_name == "" then
|
||||||
|
message = LOC "$$$/Photonodes/ExportDialog/Messages/SelectPreset=Enter a Gallery Name"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
until true
|
||||||
|
|
||||||
|
if message then
|
||||||
|
propertyTable.message = message
|
||||||
|
propertyTable.hasError = true
|
||||||
|
propertyTable.hasNoError = false
|
||||||
|
propertyTable.LR_cantExportBecause = message
|
||||||
|
else
|
||||||
|
propertyTable.message = nil
|
||||||
|
propertyTable.hasError = false
|
||||||
|
propertyTable.hasNoError = true
|
||||||
|
propertyTable.LR_cantExportBecause = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function PhotonodesUploadExportDialogSections.startDialog( propertyTable )
|
||||||
|
|
||||||
|
propertyTable:addObserver( 'items', updateExportStatus )
|
||||||
|
propertyTable:addObserver( 'client_id', updateExportStatus )
|
||||||
|
propertyTable:addObserver( 'event_code', updateExportStatus )
|
||||||
|
propertyTable:addObserver( 'gallery_name', updateExportStatus )
|
||||||
|
|
||||||
|
updateExportStatus( propertyTable )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function PhotonodesUploadExportDialogSections.sectionsForBottomOfDialog( _, propertyTable )
|
||||||
|
|
||||||
|
local f = LrView.osFactory()
|
||||||
|
local bind = LrView.bind
|
||||||
|
local share = LrView.share
|
||||||
|
|
||||||
|
local result = {
|
||||||
|
|
||||||
|
{
|
||||||
|
title = LOC "$$$/Photonodes/ExportDialog/EventSettings=Photonodes Settings",
|
||||||
|
|
||||||
|
synopsis = bind { key = 'fullPath', object = propertyTable },
|
||||||
|
|
||||||
|
-- f:row {
|
||||||
|
-- f:static_text {
|
||||||
|
-- title = LOC "$$$/FtpUpload/ExportDialog/Destination=Destination:",
|
||||||
|
-- alignment = 'right',
|
||||||
|
-- width = share 'labelWidth'
|
||||||
|
-- },
|
||||||
|
|
||||||
|
-- LrFtp.makeFtpPresetPopup {
|
||||||
|
-- factory = f,
|
||||||
|
-- properties = propertyTable,
|
||||||
|
-- valueBinding = 'ftpPreset',
|
||||||
|
-- itemsBinding = 'items',
|
||||||
|
-- fill_horizontal = 1,
|
||||||
|
-- },
|
||||||
|
-- },
|
||||||
|
|
||||||
|
f:row {
|
||||||
|
f:spacer {
|
||||||
|
width = share 'labelWidth'
|
||||||
|
},
|
||||||
|
|
||||||
|
f:static_text {
|
||||||
|
title = LOC "$$$/PhotonodesUpload/ExportDialog/ClientId=Client Id:",
|
||||||
|
alignment = 'right',
|
||||||
|
width = share 'labelWidth',
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
f:edit_field {
|
||||||
|
title = LOC "$$$/PhotonodesUpload/ExportDialog/ClientId=Client Id:",
|
||||||
|
value = bind 'client_id',
|
||||||
|
enabled = true,
|
||||||
|
truncation = 'middle',
|
||||||
|
immediate = true,
|
||||||
|
fill_horizontal = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
f:row {
|
||||||
|
f:spacer {
|
||||||
|
width = share 'labelWidth'
|
||||||
|
},
|
||||||
|
|
||||||
|
f:static_text {
|
||||||
|
title = LOC "$$$/PhotonodesUpload/ExportDialog/EventCode=Event Code:",
|
||||||
|
alignment = 'right',
|
||||||
|
width = share 'labelWidth',
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
f:edit_field {
|
||||||
|
title = LOC "$$$/PhotonodesUpload/ExportDialog/EventCode=Event Code:",
|
||||||
|
value = bind 'event_code',
|
||||||
|
enabled = true,
|
||||||
|
truncation = 'middle',
|
||||||
|
immediate = true,
|
||||||
|
fill_horizontal = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
f:row {
|
||||||
|
f:spacer {
|
||||||
|
width = share 'labelWidth'
|
||||||
|
},
|
||||||
|
|
||||||
|
f:static_text {
|
||||||
|
title = LOC "$$$/PhotonodesUpload/ExportDialog/GalleryName=Gallery Name:",
|
||||||
|
alignment = 'right',
|
||||||
|
width = share 'labelWidth',
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
f:edit_field {
|
||||||
|
title = LOC "$$$/PhotonodesUpload/ExportDialog/GalleryName=Gallery Name:",
|
||||||
|
value = bind 'gallery_name',
|
||||||
|
enabled = true,
|
||||||
|
truncation = 'middle',
|
||||||
|
immediate = true,
|
||||||
|
fill_horizontal = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
end
|
||||||
27
photonodes.lrplugin/PhotonodesUploadServiceProvider.lua
Normal file
27
photonodes.lrplugin/PhotonodesUploadServiceProvider.lua
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
-- PhotoNodes Upload plug-in
|
||||||
|
require "PhotonodesUploadExportDialogSections"
|
||||||
|
require "PhotonodesUploadTask"
|
||||||
|
|
||||||
|
|
||||||
|
--============================================================================--
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
hideSections = { 'exportLocation' },
|
||||||
|
|
||||||
|
allowFileFormats = nil, -- nil equates to all available formats
|
||||||
|
|
||||||
|
allowColorSpaces = nil, -- nil equates to all color spaces
|
||||||
|
|
||||||
|
exportPresetFields = {
|
||||||
|
{ key = 'client_id', default = nil; },
|
||||||
|
{ key = 'event_code', default = 'LR Photos' },
|
||||||
|
{ key = "gallery_name", default = nil },
|
||||||
|
},
|
||||||
|
|
||||||
|
startDialog = PhotonodesUploadExportDialogSections.startDialog,
|
||||||
|
sectionsForBottomOfDialog = PhotonodesUploadExportDialogSections.sectionsForBottomOfDialog,
|
||||||
|
|
||||||
|
processRenderedPhotos = PhotonodesUploadTask.processRenderedPhotos,
|
||||||
|
|
||||||
|
}
|
||||||
188
photonodes.lrplugin/PhotonodesUploadTask.lua
Normal file
188
photonodes.lrplugin/PhotonodesUploadTask.lua
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
-- Lightroom API
|
||||||
|
local LrPathUtils = import 'LrPathUtils'
|
||||||
|
local LrHttp = import 'LrHttp'
|
||||||
|
local LrFileUtils = import 'LrFileUtils'
|
||||||
|
local LrErrors = import 'LrErrors'
|
||||||
|
local LrDialogs = import 'LrDialogs'
|
||||||
|
local logger = import 'LrLogger'
|
||||||
|
|
||||||
|
--============================================================================--
|
||||||
|
|
||||||
|
local myLogger = logger( 'photonodes_logger' ) -- the log file name
|
||||||
|
myLogger:enable( "logfile" )
|
||||||
|
|
||||||
|
local function table_to_string(tbl)
|
||||||
|
local result = "{"
|
||||||
|
for k, v in pairs(tbl) do
|
||||||
|
-- Check the key type (ignore any numerical keys - assume its an array)
|
||||||
|
if type(k) == "string" then
|
||||||
|
result = result.."[\""..k.."\"]".."="
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check the value type
|
||||||
|
if type(v) == "table" then
|
||||||
|
result = result..table_to_string(v)
|
||||||
|
elseif type(v) == "boolean" then
|
||||||
|
result = result..tostring(v)
|
||||||
|
else
|
||||||
|
result = result.."\""..v.."\""
|
||||||
|
end
|
||||||
|
result = result..","
|
||||||
|
end
|
||||||
|
-- Remove leading commas from the result
|
||||||
|
if result ~= "" then
|
||||||
|
result = result:sub(1, result:len()-1)
|
||||||
|
end
|
||||||
|
return result.."}"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
PhotonodesUploadTask = {}
|
||||||
|
|
||||||
|
|
||||||
|
function PhotonodesUploadTask.outputToLog( message )
|
||||||
|
myLogger:trace( message )
|
||||||
|
end
|
||||||
|
|
||||||
|
function PhotonodesUploadTask.debugToLog( val )
|
||||||
|
myLogger:debug( val )
|
||||||
|
end
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function PhotonodesUploadTask.processRenderedPhotos( functionContext, exportContext )
|
||||||
|
|
||||||
|
-- Make a local reference to the export parameters.
|
||||||
|
|
||||||
|
local exportSession = exportContext.exportSession
|
||||||
|
local exportParams = exportContext.propertyTable
|
||||||
|
|
||||||
|
|
||||||
|
-- Set progress title.
|
||||||
|
|
||||||
|
local nPhotos = exportSession:countRenditions()
|
||||||
|
|
||||||
|
local progressScope = exportContext:configureProgress {
|
||||||
|
title = nPhotos > 1
|
||||||
|
and LOC( "$$$/photonodes/Upload/Progress=Uploading ^1 photos to Photonodes", nPhotos )
|
||||||
|
or LOC "$$$/photonodes/Upload/Progress/One=Uploading one photo to Photonodes",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
local client_id = exportParams.client_id
|
||||||
|
local event_code = exportParams.event_code
|
||||||
|
local gallery_name = exportParams.gallery_name
|
||||||
|
|
||||||
|
PhotonodesUploadTask.outputToLog(string.format("Client Id: %s Event Code: %s Gallery Name: %s", client_id, event_code, gallery_name))
|
||||||
|
|
||||||
|
if client_id==nil or client_id=="" then
|
||||||
|
LrErrors.throwUserError( LOC "$$$/photonodes/Upload/Errors/InvalidParameters=The specified Client Id incomplete and cannot be used." )
|
||||||
|
elseif event_code==nil or event_code=="" then
|
||||||
|
LrErrors.throwUserError( LOC "$$$/photonodes/Upload/Errors/InvalidParameters=The specified Event Code is incomplete and cannot be used." )
|
||||||
|
elseif gallery_name==nil or gallery_name=="" then
|
||||||
|
LrErrors.throwUserError( LOC "$$$/photonodes/Upload/Errors/InvalidParameters=The specified Gallery Name is incomplete and cannot be used." )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- This url uses event_id for event_code
|
||||||
|
-- local upload_url = string.format("http://api.photonodes.com/kiosk/api/gallerybyname/photos/upload/%s/%s", client_id, event_code)
|
||||||
|
|
||||||
|
-- This url uses event code for event_code (staging)
|
||||||
|
-- local upload_url = string.format("http://staging.photonodes.com/plugin/api/gallerybyname/photos/upload/%s", client_id)
|
||||||
|
|
||||||
|
-- This url uses event code for event_code (live)
|
||||||
|
local upload_url = string.format("http://api.photonodes.com/plugin/api/gallerybyname/photos/upload/%s", client_id)
|
||||||
|
|
||||||
|
PhotonodesUploadTask.outputToLog(string.format("Upload Url: %s", upload_url))
|
||||||
|
|
||||||
|
-- Iterate through photo renditions.
|
||||||
|
|
||||||
|
local failures = {}
|
||||||
|
local successes = {}
|
||||||
|
|
||||||
|
for _, rendition in exportContext:renditions{ stopIfCanceled = true } do
|
||||||
|
|
||||||
|
-- Wait for next photo to render.
|
||||||
|
|
||||||
|
local success, pathOrMessage = rendition:waitForRender()
|
||||||
|
|
||||||
|
-- Check for cancellation again after photo has been rendered.
|
||||||
|
|
||||||
|
if progressScope:isCanceled() then break end
|
||||||
|
|
||||||
|
if success then
|
||||||
|
|
||||||
|
local filename = LrPathUtils.leafName( pathOrMessage )
|
||||||
|
|
||||||
|
local mimeChunks = {}
|
||||||
|
mimeChunks[ #mimeChunks + 1 ] = { name = 'gallery_name', value = gallery_name }
|
||||||
|
mimeChunks[ #mimeChunks + 1 ] = { name = 'event_code', value = event_code }
|
||||||
|
mimeChunks[ #mimeChunks + 1 ] = { name = 'photo_file', fileName = filename, filePath = pathOrMessage, contentType = 'application/octet-stream' }
|
||||||
|
|
||||||
|
local result, hdrs = LrHttp.postMultipart(upload_url, mimeChunks )
|
||||||
|
|
||||||
|
PhotonodesUploadTask.outputToLog(string.format("Http Post result: %s", result))
|
||||||
|
PhotonodesUploadTask.outputToLog(string.format("Http Post headers: %s", table_to_string(hdrs)))
|
||||||
|
|
||||||
|
if not result then
|
||||||
|
if hdrs and hdrs.error then
|
||||||
|
PhotonodesUploadTask.outputToLog(string.format("Http Post error: %s", formatError( hdrs.error.nativeCode )))
|
||||||
|
LrErrors.throwUserError( formatError( hdrs.error.nativeCode ) )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if hdrs and hdrs.status == 200 then
|
||||||
|
success = true
|
||||||
|
elseif hdrs and hdrs.status == 404 then
|
||||||
|
PhotonodesUploadTask.outputToLog("Http Post error: 404")
|
||||||
|
LrErrors.throwUserError( "Client Id or Event Code not found" )
|
||||||
|
elseif hdrs and hdrs.status == 403 then
|
||||||
|
PhotonodesUploadTask.outputToLog("Http Post error: 403")
|
||||||
|
LrErrors.throwUserError( "Error uploading file" )
|
||||||
|
else
|
||||||
|
success=false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Http stuff goes here
|
||||||
|
--local success = ftpInstance:putFile( pathOrMessage, filename )
|
||||||
|
|
||||||
|
if not success then
|
||||||
|
|
||||||
|
-- If we can't upload that file, log it. For example, maybe user has exceeded disk
|
||||||
|
-- quota, or the file already exists and we don't have permission to overwrite, or
|
||||||
|
-- we don't have permission to write to that directory, etc....
|
||||||
|
|
||||||
|
table.insert( failures, filename )
|
||||||
|
else
|
||||||
|
table.insert(successes, 1)
|
||||||
|
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 )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if #failures > 0 then
|
||||||
|
local message
|
||||||
|
if #failures == 1 then
|
||||||
|
message = LOC "$$$/photonodes/Upload/Errors/OneFileFailed=1 file failed to upload correctly."
|
||||||
|
else
|
||||||
|
message = LOC ( "$$$/photonodes/Upload/Errors/SomeFileFailed=^1 files failed to upload correctly.", #failures )
|
||||||
|
end
|
||||||
|
LrDialogs.message( message, table.concat( failures, "\n" ) )
|
||||||
|
else
|
||||||
|
|
||||||
|
if #successes == 1 then
|
||||||
|
message = string.format("1 file successfully uploaded to gallery %s.", gallery_name)
|
||||||
|
else
|
||||||
|
message = string.format("%s files successfully uploaded to gallery %s.", #successes, gallery_name)
|
||||||
|
end
|
||||||
|
LrDialogs.message( message )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user