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

    how to use withWriteAccessDo and AsycTasks

    gandalf44

      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
             end
             return set
          end
      
      
          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")
                  end
      
      
                  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)
      
      
                      end
      
      
                      local published_remote_ids_set = Set (published_remote_ids)
      
      
                      if next(published_remote_ids_set) == nil then
                          logger:debug ("published_remote_ids is empty")
                      else
                          for i=1, #published_remote_ids_set do
                              logger:debug ("published_id in the table is ", published_remote_ids[i])
                          end
                      end
      
      
      
      
                      -- 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")
                          else
                              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")
                              f:write(fileData)
                              f:close()
      
      
                              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)
                              end)
                              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 )
      
      
                              end)
                              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] )
      
      
                                      end)
                                       logger:debug ("z = ", z)
      
      
                                  end
      
      
                              end
      
      
                              --progressScope:setPortionComplete( ( i - 1 ) / total_gids )
      
      
                          end
      
      
                      end
      
      
                      progressScope:done()
      
      
      
      
                  end)
      
      
              end
      
      
          end
      end
      
      
      
        • 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

            John,

             

            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

             

            -Brian