2 Replies Latest reply on Jun 30, 2015 11:31 AM by gandalf44

    how to use withWriteAccessDo and AsycTasks


      I have a bit of code for my service where I

      1. retreive photo_id (gids) on the remote side,
      2. see if they're in the catalog/published already..
      3. if not, download the photos
      4. import the photos to the catalog
      5. add those photos to my published collection
      6. once added to the published collection, add RemoteId's to them which are the service's photo gids


      I am getting stuck with only one withWriteAcccessDo occurring, then nothing.  So in the code below, x = executed, which is the first WriteAccessDo  I'm sure I am doing this wrong in the postAsyncTaskWithContext.  I'll post the whole function here, obfuscating my service name, so you guys can try and get the full scope of what I am trying to do.  This is for a publishing service, so it's when the user updates the service for a 2-way sync (.updateCollectionSettings)


      function publishServiceProvider.updateCollectionSettings( publishSettings, info )
          local catalog = LrApplication.activeCatalog()
          logger:debug ("*******************************")
          logger:debug ("current catalog is: ", catalog)
          logger:debug ("*******************************")
          local collectionSettings = assert( info.collectionSettings )
          local publishedCollection = assert( info.publishedCollection )
          --logger:debug ("publishedCollection exists --> ", publishedCollection)
          local function Set (list)
             local set = {}
             for _, l in ipairs(list) do
                set[l] = true
             return set
          logger:debug ("isDefaultCollection is: ", info.isDefaultCollection)
          logger:debug ("enable_2way_sync is", collectionSettings.enable_2way_sync)
          if collectionSettings.enable_2way_sync == 'checked' then
              -- if this is the default published collection (aka, All  Albums) we need to perform
              -- different logic then if it is a published collection of type " Album".  For instance,
              -- there is no album gid to compare with for sync logic
              if info.isDefaultCollection then
                  -- Get a list of all photos on the  so we know which ones we can replace and which have
                  -- to be re-uploaded entirely.
                  local all_bevy_gids = API.getAllExistingGids ( prefs.bevy_ip, prefs.token_str )
                  logger:debug ("all_bevy_gids is: ", all_bevy_gids)
                  if all_bevy_gids == nil then
                      logger:debug (" has no photos")
                  LrFunctionContext.postAsyncTaskWithContext ( 'Sync Photos', function( context )
                      local progressScope = LrDialogs.showModalProgressDialog({
                               title = "Syncing  photos to Lightroom..",
                               caption="Please wait...",
                               cannotCancel = false,
                               functionContext = context
                      local all_published_photos = publishedCollection:getPublishedPhotos()
                      -- We need to build a table of previously uploaded & published photos
                      local published_remote_ids = {}
                      for i=1, #all_published_photos do
                          local remote_id = all_published_photos[i]:getRemoteId()
                          table.insert (published_remote_ids, remote_id)
                          logger:debug ("building the current published remote id table: ", remote_id)
                      local published_remote_ids_set = Set (published_remote_ids)
                      if next(published_remote_ids_set) == nil then
                          logger:debug ("published_remote_ids is empty")
                          for i=1, #published_remote_ids_set do
                              logger:debug ("published_id in the table is ", published_remote_ids[i])
                      -- iterate thru all the exsiting  gifs table.  If the remote_id =  gid,
                      -- we already published the photo.  Otherwise, because we have enabled 2-way
                      -- sync, download it, and set the photo as published in the "All  Photos"
                      --  default published collection
                      local total_gids = #all_bevy_gids
                      for i=1, #all_bevy_gids do
                          logger:debug ("now processing bevy_gid:  ", all_bevy_gids[i])
                          if published_remote_ids_set[all_bevy_gids[i]] then
                              logger:debug ("this gid has been published already")
                              logger:debug ("did not find  gid in published photos, we should download and mark it published")
                              local fileName = "bevy_photo_" .. i .. ".jpg"
                              logger:debug ("fileName is ", fileName)
                              local fileData = API.downloadPhoto ( prefs.bevy_ip, prefs.token_str, all_bevy_gids[i], fileName )
                              local f = io.open(LrPathUtils.child(LrPathUtils.getStandardFilePath("temp"), fileName),"w")
                              local filePath = LrPathUtils.child(LrPathUtils.getStandardFilePath("temp"), fileName)
                              logger:debug ("downloaded filePath is: ", filePath)
                              logger:debug ("")
                              local photos_to_publish = {}
                              x = catalog:withWriteAccessDo( "Add  Photos to Catalog", function( context )
                                  imported_photo = catalog:addPhoto ( filePath )
                                  logger:debug ("imported_photo is: ", imported_photo)
                              logger:debug ("x = ", x)
                              table.insert( photos_to_publish, imported_photo)
                              logger:debug ("synced photo to publish is: ", imported_photo)
                              y = catalog:withWriteAccessDo( "Add Synced  Photos to Published Collection", function( context )
                                  publishedCollection.addPhotos( photos_to_publish )
                              logger:debug ("y = ", y)
                              local published_photos = publishedCollection:getPublishedPhotos()
                              for i=1, #all_published_photos do
                                  if published_photos[i]:getRemoteId() == nil then
                                     z = catalog:withWriteAccessDo("Add RemoteIds to Synced  Photos", function( context )
                                          published_photos[i]:setRemoteId ( all_bevy_gids[i] )
                                       logger:debug ("z = ", z)
                              --progressScope:setPortionComplete( ( i - 1 ) / total_gids )
        • 1. Re: how to use withWriteAccessDo and AsycTasks
          johnrellis Most Valuable Participant

          The SDK is quite inconsistent with regards to which tasks and callbacks will trap errors and display an error dialog and which won't.  In particular, a task created by LrFunctionContext.postAsyncTaskWithContext() does not have an error dialog attached to it, and any errors in that task will just silently terminate it.  Use LrDialogs.attachErrorDialogToFunctionContext() to enable error dialogs for the task and you should then find out what's going on.


          In general, I highly recommend that you invest a couple hours in your debugging environment:


          1. Somewhere in this forum is a post describing how to attach an IDE's debugger to the LR Lua environment.  I've never tried it but others report that it works.

          2. Use my lightweight Lightroom Debugging Toolkit.


          Both of these will take a bit of effort, but how many hours have you already spent tracking down silly errors with inscrutable error messages?

          • 2. Re: how to use withWriteAccessDo and AsycTasks
            gandalf44 Level 1



            Makes total sense, I have burnt many hours already on this problem (being a Lua newbie didn't help...).

            I'll try your suggestions, and your debugging toolkit, didn't know it existed.  I figured by showing my code there would be something strikingly wrong