Copy link to clipboard
Copied
Hi folks
Is it possible to use the SDK to create a plugin that creates a Collection Set that contains a number of Smart collections.
I'd also like to be able to select a Folder and have the plugin use the folder name as one of the parameters in the Smart collections and the title of the Collection Set
Cheers in advance
Copy link to clipboard
Copied
Thanks Rob
I've already had a look in your FolderCollections.lua and there was some helpful code in there I'll check out the others soon
tongiht I've written a recursive function that gets an activeSource's parent and then gets the parent's parent, and so on until the 'root' is reached. The recursive function adds the succesive parents to an Array. ( a table in LUA speak I believe )
******************************************************
-- Function to create array of folder of collection parental structure
function MyHWLibraryItem.CreateParentStructure( source, parent_table, x )
local source_parent = source:getParent()
--add to parent table ( array )
parent_table
if parent_table
x=x+1
-- call itself to interrogate further up the parent branch
parent_table = MyHWLibraryItem.CreateParentStructure( source_parent, parent_table, x )
else -- parent doesn't exist - top of branch
parent_table
end
return parent_table
end
******************************************************
Interesting to note that I couldn't get this to work until I realised I couldn't assign an element of the array a value of "nil" ( which is returned when getParent() finds no parent ) and had to assign it a value of 'false' instead.
I think your Folder Collections plug deals with recreating path structures so I'll take another look at that shortly
Copy link to clipboard
Copied
Looks good John.
A couple lua-y things to note:
You can assign nil to an array, but:
* ipairs stops on the first nil.
* #tbl counts items (at positive integer indexes) up unitl the last nil.
I mean, assigning non-nil values (e.g. false) is probably the preferred approach in this case, but just so ya know:
#{ x=1 } == 0 -- is true
#{ 1, nil, 3 } == 3 -- true too
#{ 1, nil } == 1 -- also true
#{ x=1, 2 } == 1 -- true
{ x=1, 2 }[1] == 2 -- true
local x = {}
x[0] = 1
#x == 0 -- true
for i,v in ipairs{ 1, nil, 3 } do
local nothing = 1 -- executes only once
end
R
Copy link to clipboard
Copied
Cheers Rob very helpful
Copy link to clipboard
Copied
Hi peeps.
Just about finished. Seems to be working OK. Just gotta tidy up the dialog box. I'll post the code when done.
Copy link to clipboard
Copied
Standing by... (thanks).
R
Copy link to clipboard
Copied
Here ya go - A huge thanks to you chaps for all your help!.
**************************************************************************************
local LrFunctionContext = import 'LrFunctionContext'
local LrBinding = import 'LrBinding'
local LrDialogs = import 'LrDialogs'
local LrView = import 'LrView'
local LrColor = import 'LrColor'
local LrTasks = import 'LrTasks'
local LrApplication = import 'LrApplication'
local LrLogger = import 'LrLogger'
local myLogger = LrLogger( 'libraryLogger' )
myLogger:enable( "logfile" ) -- or "print"
MyHWLibraryItem = {}
-- Logger function
function MyHWLibraryItem.outputToLog( message )
myLogger:trace( message )
end
-- Function to extract names from parent table
function MyHWLibraryItem.Path_String_From_Parent_Table( parent_table )
-- stuff goes in here
local path_string =""
for y, source in ipairs( parent_table ) do
if source ~= false then
parent = source:getName()
else
parent = "ROOT"
end
if y == #parent_table then
path_string = path_string .. parent .. "/.."
else
path_string = path_string .. parent .. "/"
end
end
return path_string
end
-- Function to create array of folder of collection parental structure
function MyHWLibraryItem.CreateParentStructure( source, parent_table, x )
local source_parent = source:getParent()
--add to parent table ( array )
parent_table
if parent_table
x=x+1
-- call itself to interrogate further up the parent branch
parent_table = MyHWLibraryItem.CreateParentStructure( source_parent, parent_table, x )
else -- parent doesn't exist - top of branch
parent_table
end
return parent_table
end
function MyHWLibraryItem.showCustomDialog()
-- body of show-dialog function
LrFunctionContext.callWithContext( "ShowSources",
function( context )
catalog = LrApplication.activeCatalog()
local source_type
local source_name
local source_parent
local source_parent_name
local collection_set
local path = catalog:getPath()
local sources = catalog:getActiveSources()
--local folders = catalog:getFolders()
source_type = "Active Sources:\n***********\n\n"
-- analyse source table
for i, source in ipairs( sources ) do
-- Create table for parent structure of source
local parent_table = {}
source_name = source:getName()
x=1 -- init counter for parent table
-- call recursive function
parent_table = MyHWLibraryItem.CreateParentStructure( source, parent_table, x )
-- now reverse the parent table
local y=1
local z = #parent_table
local parent_table_rev = {} -- create empty rev table
for a = z , 1, -1 do
parent_table_rev
y=y+1 z=z-1
end
parent_table = parent_table_rev
-- end reverse parent table
-- create path string from parent_table
source_parent_name = MyHWLibraryItem.Path_String_From_Parent_Table( parent_table )
local name_and_parent_display = "\"" .. source_name .. "\" \n Parent(s) = " .. source_parent_name .."\n"
if source:type() == 'LrFolder' then
smart_coll_report = ""
-- ********* CREATE COLLECTION SETS and SMART COLLECTIONS *****************
-- create collection set hierarchy
for i = 1, #parent_table do
MyHWLibraryItem.outputToLog( "STEP = " .. i )
if i==1 then -- root
--do nothing
else
--create collection set
if parent_table[i-1] == false then
MyHWLibraryItem.outputToLog( "parent table = FALSE." )
parent = nil
else
--parent = parent_table[i-1]
MyHWLibraryItem.outputToLog( "parent name = " .. parent:getName() )
end
catalog:withWriteAccessDo( "Create Collection Set 2" , function( context )
parent = catalog:createCollectionSet( parent_table:getName() , parent , true )
end)
MyHWLibraryItem.outputToLog( "collection set created. Name = " .. parent:getName() )
end
end
catalog:withWriteAccessDo( "Create Collection Set 1" , function( context )
-- Create new collection set
collection_set = catalog:createCollectionSet( source_name , parent )
if collection_set ~= nil then
smart_coll_report = smart_coll_report .. " Collection Set '"..source_name.."' created OK\n"
else
smart_coll_report = smart_coll_report .. " Collection Set '"..source_name.."' ALREADY EXISTS!\n"
end
-- create Smart Collections for ratings
if collection_set ~= nil then
local smart_collection_set_1 = catalog:createSmartCollection( "<2", {{criteria="rating",operation="<",value=2},{criteria="folder",operation="all",value=source_name}}, collection_set )
local smart_collection_set_2 = catalog:createSmartCollection( "2+", {{criteria="rating",operation=">=",value=2},{criteria="folder",operation="all",value=source_name}}, collection_set )
local smart_collection_set_3 = catalog:createSmartCollection( "3+", {{criteria="rating",operation=">=",value=3},{criteria="folder",operation="all",value=source_name}}, collection_set )
local smart_collection_set_4 = catalog:createSmartCollection( "4+", {{criteria="rating",operation=">=",value=4},{criteria="folder",operation="all",value=source_name}}, collection_set )
if smart_collection_set_1 ~= nil then smart_coll_report = smart_coll_report .. " Smart Collection '<2' created OK\n" end
if smart_collection_set_2 ~= nil then smart_coll_report = smart_coll_report .. " Smart Collection '2+' created OK\n" end
if smart_collection_set_3 ~= nil then smart_coll_report = smart_coll_report .. " Smart Collection '3+' created OK\n" end
if smart_collection_set_4 ~= nil then smart_coll_report = smart_coll_report .. " Smart Collection '4+' created OK\n" end
end
end ) -- end of catalog:withWriteAccessDo FUNCTION
-- ************************************************************************
-- create display string
source_type = source_type .. i .. " Folder: " .. name_and_parent_display .. smart_coll_report .. "\n"
elseif source:type() == 'LrCollectionSet' then
smart_coll_report = ""
source_type = source_type .. i .. " Collection Set: " .. name_and_parent_display .. smart_coll_report .. "\n"
elseif source:type() == 'LrCollection' then
smart_coll_report = ""
source_type = source_type .. i .. " Collection: " .. name_and_parent_display .. smart_coll_report .. "\n"
elseif source:type() == 'LrPublishedCollection' then
smart_coll_report = ""
source_type = source_type .. i .. " Published Collection: " .. name_and_parent_display .. smart_coll_report .. "\n"
elseif source:type() == 'LrPublishedCollectionSet' then
smart_coll_report = ""
source_type = source_type .. i .. " Published Collection Set: " .. name_and_parent_display .. smart_coll_report .. "\n"
end
end
display_string = source_type
-- create view hierarchy for dialog box
local f = LrView.osFactory() -- get the view factory object
local c = f:column { -- the root node
f:row { -- Display contents of active sources Array
f:static_text {
text_color = LrColor( 0, 0, 0 ),
alignment = "Left",
-- add title with binding later
title = display_string
},
},
}
local result = LrDialogs.presentModalDialog(
{
title = "Create Rating Smart Collection Sets",
contents = c, -- the view hierarchy we defined
}
)
end )
end
LrTasks.startAsyncTask(function()
MyHWLibraryItem.showCustomDialog()
end)
Copy link to clipboard
Copied
Looks good, but I wrapped it in a plugin and tried it, and I can't tell what happened (couldn't find any new collections, nor was there a UI message presented (after I approved the initial prompt I mean), nor any logged messages). I'm not sure what was supposed to happen.
?
R
Copy link to clipboard
Copied
Hmmm interesting. Works fine here ....
What should happen is for any sources you select the routine will create an identical structure of collection sets and smart collections based upon ratings of pics in those sources as:
-- create Smart Collections for ratings
if collection_set ~= nil then
local smart_collection_set_1 = catalog:createSmartCollection( "<2", {{criteria="rating",operation="<",value=2},{criteria="folder",operati on="all",value=source_name}}, collection_set )
local smart_collection_set_2 = catalog:createSmartCollection( "2+", {{criteria="rating",operation=">=",value=2},{criteria="folder",operat ion="all",value=source_name}}, collection_set )
local smart_collection_set_3 = catalog:createSmartCollection( "3+", {{criteria="rating",operation=">=",value=3},{criteria="folder",operat ion="all",value=source_name}}, collection_set )
local smart_collection_set_4 = catalog:createSmartCollection( "4+", {{criteria="rating",operation=">=",value=4},{criteria="folder",operat ion="all",value=source_name}}, collection_set )
So for the red ticked slected folder source Dubau LR then the red encircled collection set/smart collection structure is created:
Copy link to clipboard
Copied
Thanks,
I tried it using a folder source and it worked. Previous test was using a collection as source.
Unfortunately, for me, the smart collection folder criteria casts too wide a net (sometimes includes photos from other folders). Same will be true for other users. This is why I changed FolderCollections to use dumb collections instead - there is no way to reliably define smart collection criteria to limit photos to those of a single corresponding folder, or at least no way that John Ellis or I could figure.
Otherwise, nice job!
Cheers,
Rob
Copy link to clipboard
Copied
Thanks Rob.
"there is no way to reliably define smart collection criteria to limit photos to those of a single corresponding folder,"
In my working catalogues ( not the test catalogue shown in the screenshots ) all my folders have unique names starting with the Date and then a 2 digit number ( for multiple shoots on the same day ). then a decription i.e yyyy-mm-dd_xx_description
And then using smart collections which with a rule: "Folder -> Contains All - > yyyy-mm-dd_xx_description" you always ensure you only get photos from that folder
Copy link to clipboard
Copied
Right-o: unique folder names will do it. And, I may resort to unique folder names at some point, just for this reason (assuming Adobe does not robusten the SDK enough come Lr5). Just thought you should know, in case you plan on making this plugin available to others...
Cheers,
Rob
Copy link to clipboard
Copied
It would be nice if the Object ID of the folder was available to Smart Collections. After all this would allow the user to rename a folder and without hving to rename any relevantSmart collection rules
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi guys, do anybody has got the source of Rob Cole's FolderCollections plugin?
Copy link to clipboard
Copied
You might post a new thread in the main LR forum: Lightroom Classic CC — The desktop-focused app . There are many more users of Rob's plugins there than in this forum. Include a link to the discussion here about Rob's download agreement: Re: Rob Cole has passed away . (Questions about Rob's licensing will inevitably arise.)
Copy link to clipboard
Copied
You might post a new thread in the main LR forum: Lightroom Classic CC — The desktop-focused app . There are many more users of Rob's plugins there than in this forum. Include a link to the discussion here about Rob's download agreement: Re: Rob Cole has passed away . (Questions about Rob's licensing will inevitably arise.)
You can find a number of Rob's plugins, including FolderCollections, here: RobColeLr · GitHub
Copy link to clipboard
Copied
Thank you very much!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now