13 Replies Latest reply on Jun 26, 2010 2:40 PM by petez

    LrCatalog.getCollections() ?

    petez

      For the LrCollection class, the documentation says:
      "Retrieve the objects for all the collections by calling LrCatalog.getCollections()."
      but there is no other info about it. What does it return?

       

      I have:
      local LrApplication = import "LrApplication"
      local LrCatalog = LrApplication.activeCatalog()
      local collections = LrCatalog:getCollections()

       

      I get:
      internal error.... attempt to call method getCollections (a nil value)

       

      What am I doing wrong?

      Pete

        • 1. Re: LrCatalog.getCollections() ?
          johnrellis Most Valuable Participant

          That part of the documentation is wrong.  Here's a correct code fragment:

           

          local LrApplication = import 'LrApplication'
          local catalog = LrApplication.activeCatalog ()

          local topLevelCollections = catalog:getChildCollections ()

          local topLevelCollectionSets = catalog:getChildCollectionSets ()

           

          The documentation for the two catalog:get* methods is correct.

          • 2. Re: LrCatalog.getCollections() ?
            petez Level 1

            Thanks for the quick reply.

             

            Now I get "We can only wait from within a task", so I changed it to:

             

            local topLevelCollections = LrTasks.startAsyncTask(catalog:getChildCollections(), "getChildCollections")

             

            but I still get the same  can only wait from within a task error.

             

            PS: I removed the line for collections sets.

             

             

             

             

             

            • 3. Re: LrCatalog.getCollections() ?
              johnrellis Most Valuable Participant

              local topLevelCollections = LrTasks.startAsyncTask(catalog:getChildCollections(), "getChildCollections")

              startAsyncTask requires the first argument to be a function that takes one argument, a function context:

               

              local topLevelCollections = LrTasks.startAsyncTask (

                   function (context)

                        return catalog:getChildCollections()

                        end)

              • 4. Re: LrCatalog.getCollections() ?
                johnrellis Most Valuable Participant

                Oops, I misspoke slightly.  The function passed to startAsyncTask doesn't take any arguments:

                 

                local topLevelCollections = LrTasks.startAsyncTask (

                     function ()

                          return catalog:getChildCollections()

                          end)

                • 5. Re: LrCatalog.getCollections() ?
                  petez Level 1

                  OK...that gets me the collections.

                  The doc says "LrTasks.startAsyncTask( func, optName )",

                  Parameters

                  1. func
                  (function) The function to start.
                  2. optName
                  (string, optional) A name to assign to the task, for debugging only.

                   

                   

                  so thanks for that help too, I never would have guessed it.

                  • 6. Re: LrCatalog.getCollections() ?
                    johnrellis Most Valuable Participant

                    Some resources I found handy when starting out with the SDK:

                     

                    - Look at the sample plug-ins.  They provide more examples than what's described in the SDK Guide.

                     

                    - For the Lua lanuage, I found this tutorial quick and easy:

                     

                    http://lua-users.org/wiki/TutorialDirectory

                     

                    The Lua language is conceptually simple but much different than the typical scripting languages like Python, Perl, or Visual Basic.  (It's most like Scheme, a language that used to be taught in some computer-science departments years ago.)

                    1 person found this helpful
                    • 7. Re: LrCatalog.getCollections() ?
                      petez Level 1

                      Thanks for the link.

                      The documentation has other issues w/ consistency too. For example, catalog:getChildCollections says it returns:

                      (array of LrCollection) The collection objects.

                       

                      while catalog:getAllPhotos says it returns:

                      (table) An array of LrPhoto objects

                       

                      I'm assuming that both methods return a table of their respective objects. Now onto ipairs!

                      • 8. Re: LrCatalog.getCollections() ?
                        petez Level 1

                        Well, I'm not getting any errors, but topLevelCollections==nil, catalog returns the .lrcat so, I'm confused.

                        • 9. Re: LrCatalog.getCollections() ?
                          johnrellis Most Valuable Participant

                          What you quoted is technically correct, though inconsistent in its use of terminology.  In Lua, an "array" is just a table whose keys are numeric.  So "(table) An array of LrPhoto objects" is technically correct. 

                          • 10. Re: LrCatalog.getCollections() ?
                            johnrellis Most Valuable Participant

                            Why don't you post the entire code, and maybe it will be apparent what's going on.

                            • 11. Re: LrCatalog.getCollections() ?
                              petez Level 1

                              Thanks for looking at this:

                               

                              MyCollections = {}

                              local LrTasks = import "LrTasks"
                              local LrApplication = import "LrApplication"
                              local LrLogger = import "LrLogger"

                              local myLogger = LrLogger('myLog') -- the log file name
                              local catalog = LrApplication.activeCatalog()


                              local topLevelCollections = LrTasks.startAsyncTask (
                                   function ()
                                    return catalog:getChildCollections()
                                   end)

                               

                              function MyCollections.outputToLog( message )
                              myLogger:trace( message )
                              end

                               

                              myLogger:enable( "logfile" )
                              MyCollections.outputToLog(topLevelCollections==nil) --<--outputs true


                              -- this is what I'm working on.. which errors due to topLevelCollections==nil

                              for _, lrcollection in ipairs( topLevelCollections ) do
                              collectionNames = collectionNames .. "," .. LrTasks.startAsyncTask (
                                           function()
                                           return lrcollection:getName()
                                           end)
                              end --for

                              • 12. Re: LrCatalog.getCollections() ?
                                johnrellis Most Valuable Participant

                                Oh, silly me, I gave you a code fragment that didn't actually make sense -- very sorry about that.

                                 

                                The problem with this:

                                 

                                local topLevelCollections = LrTasks.startAsyncTask (

                                     function (context)

                                          return catalog:getChildCollections()

                                          end)

                                 

                                is that startAsyncTask does exactly that -- it creates an asynchronous task (i.e. a thread) that executes the function in parallel with the task that called startAsyncTask.   It always returns nil, which is why topLevelCollections is always nil.

                                 

                                You'll need to put all of the work manipulating collections (and many other methods on catalogs) into a function that's invoked by startAsyncTask.  E.g. your plugin could have the structure:

                                 

                                local function main ()

                                    ...access the catalog and collections...

                                    ...show the main dialog...

                                    end

                                 

                                LrTask.startAsyncTask (main)

                                • 13. Re: LrCatalog.getCollections() ?
                                  petez Level 1

                                  Got it.

                                  Thanks for getting me started.

                                   

                                  Pete