Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Writing a plugin to create Smart Collections

Guest
Jun 04, 2012 Jun 04, 2012

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

TOPICS
SDK
12.4K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 07, 2012 Jun 07, 2012

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 = source_parent

           

            if parent_table ~= nil then -- parent exists

                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 = false       

            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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 08, 2012 Jun 08, 2012

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 08, 2012 Jun 08, 2012

Cheers Rob very helpful   

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 09, 2012 Jun 09, 2012

Hi peeps.

Just about finished. Seems to be working OK. Just gotta tidy up the dialog box. I'll post the code when done. 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 09, 2012 Jun 09, 2012

Standing by... (thanks).

R

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 09, 2012 Jun 09, 2012

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 = source_parent       

            if parent_table ~= nil then -- parent exists

                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 = false

            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 = parent_table

                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)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 11, 2012 Jun 11, 2012

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 11, 2012 Jun 11, 2012

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:

https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash3/523608_426639240702713_216228329_n.jpg

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 11, 2012 Jun 11, 2012

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 11, 2012 Jun 11, 2012

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 11, 2012 Jun 11, 2012

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 11, 2012 Jun 11, 2012

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jun 12, 2012 Jun 12, 2012
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 01, 2019 Mar 01, 2019

Hi guys, do anybody has got the source of Rob Cole's FolderCollections plugin?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 01, 2019 Mar 01, 2019

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.)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 01, 2019 Mar 01, 2019

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 01, 2019 Mar 01, 2019
LATEST

Thank you very much!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines