Highlighted

photo:addKeyword( keyword ) by several photos

Nov 14, 2019

Copy link to clipboard

Copied

Hello! Faced with such a problem. The value of metadata trying to make keywords.

If one photo is selected, then everything works out correctly.. But if you choose 2 or more photos, the error falls out  "Внутренняя ошибка: assertion failed!" 

 

 

local photos = catalog.targetPhotos
local countPhotos = #photos
local keywords = catalog:getKeywords()
local keywordCategory
for k, keyword in ipairs(keywords) do
	if  keyword:getName() == "PERSON" then
		keywordCategory = keyword
	end
end
for i, photo in ipairs(photos) do
	local participant = photo:getFormattedMetadata("licensor") or ""
	local participantCount = #participant
	keywordPerson = catalog:createKeyword( photo:getFormattedMetadata ("licensor")[1].LicensorName, nil, false, keywordCategory, true )
	photo:addKeyword( keywordPerson )
end

 

 

Tell me what I'm missing. Like in a loop should run through all the photos. Metadata in the same way inserts...

Most Valuable Participant
Correct answer by johnrellis | Most Valuable Participant

"On every action generated its step history, otkatyvaemyy on CTRL+Z. And this means, that if I wrong suddenly call its script on 500 photo, then me 500 times press CTRL+Z."

 

I think the workaround is to use a more complicated method of doing this that avoids calling catalog:createKeyword() with returnExisting = true, which I think is the cause of the problem:

 

1. Loop over the photos and build a table that maps LicensorName to existing LrKeyword objects.  Also build an array of LicensorNames that don't currently have keywords.

 

2. Inside catalog:withWriteAccessDo(), first create the keywords for the LicensorNames that currently don't have them, updating the table that maps LicensorName to LrKeyword as you go.  Then loop through all the photos, assigning the keywords to photos (using that table).

 

I have a plugin that uses this method without any issues.

 

Topics

Problem or error, SDK

Views

208

Likes

Translate

Translate

Report

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

photo:addKeyword( keyword ) by several photos

Nov 14, 2019

Copy link to clipboard

Copied

Hello! Faced with such a problem. The value of metadata trying to make keywords.

If one photo is selected, then everything works out correctly.. But if you choose 2 or more photos, the error falls out  "Внутренняя ошибка: assertion failed!" 

 

 

local photos = catalog.targetPhotos
local countPhotos = #photos
local keywords = catalog:getKeywords()
local keywordCategory
for k, keyword in ipairs(keywords) do
	if  keyword:getName() == "PERSON" then
		keywordCategory = keyword
	end
end
for i, photo in ipairs(photos) do
	local participant = photo:getFormattedMetadata("licensor") or ""
	local participantCount = #participant
	keywordPerson = catalog:createKeyword( photo:getFormattedMetadata ("licensor")[1].LicensorName, nil, false, keywordCategory, true )
	photo:addKeyword( keywordPerson )
end

 

 

Tell me what I'm missing. Like in a loop should run through all the photos. Metadata in the same way inserts...

Most Valuable Participant
Correct answer by johnrellis | Most Valuable Participant

"On every action generated its step history, otkatyvaemyy on CTRL+Z. And this means, that if I wrong suddenly call its script on 500 photo, then me 500 times press CTRL+Z."

 

I think the workaround is to use a more complicated method of doing this that avoids calling catalog:createKeyword() with returnExisting = true, which I think is the cause of the problem:

 

1. Loop over the photos and build a table that maps LicensorName to existing LrKeyword objects.  Also build an array of LicensorNames that don't currently have keywords.

 

2. Inside catalog:withWriteAccessDo(), first create the keywords for the LicensorNames that currently don't have them, updating the table that maps LicensorName to LrKeyword as you go.  Then loop through all the photos, assigning the keywords to photos (using that table).

 

I have a plugin that uses this method without any issues.

 

Topics

Problem or error, SDK

Views

209

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Most Valuable Participant ,
Nov 14, 2019

Copy link to clipboard

Copied

I see a couple of things:

local participant = photo:getFormattedMetadata("licensor") or ""

 If the photo doesn't have any "licensor" metadata, then "participant" gets assigned the empty string, and then the following statements try to index "participant" as an array. You'll need to check for a nil value for "licensor".

 

photo:addKeyword( keywordPerson )

photo:addKeyword() needs to be called inside a call to catalog:withWriteAccessDo().

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 14, 2019

Copy link to clipboard

Copied

To be honest, I am not a programmer and do not understand what "catalog:with Write Access Do" means, but the description for "photo:set Raw Metadata( key, value)" says the same. And setRawMetadata works for me...

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 14, 2019

Copy link to clipboard

Copied

At least one value in "licensor" to be sure!

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 14, 2019

Copy link to clipboard

Copied

Here's what my code looks like in more detail:

function showDialog(context)
  local props = LrBinding.makePropertyTable(context)
    local fillFormat = props.fillFormat
    prefs.fillFormat = fillFormat
    updateFill(fillFormat)
end

function updateFill(fillFormat)
  LrTasks.startAsyncTask(function()
    catalog:withWriteAccessDo("&Инициализация данных об участниках", function()
      local photos = catalog.targetPhotos
      local countPhotos = #photos
      local ProgressBar = LrProgressScope({
        title = "Инициализация данных об участниках для " .. tostring(countPhotos) .. " файла(ов)"
      })
	    local keywords = catalog:getKeywords()
	    local keywordCategory
	    for k, keyword in ipairs(keywords) do
		    if  keyword:getName() == "PERSON" then
			    keywordCategory = keyword
		    end
	    end
      for i, photo in ipairs(photos) do
	      local participant = photo:getFormattedMetadata("licensor") or ""
	      local participantCount = #participant
	      for c = 1, participantCount do
		    keywordPerson = catalog:createKeyword( photo:getFormattedMetadata ("licensor")[с].LicensorName, nil, false, keywordCategory, true )
			photo:addKeyword( keywordPerson )
	      end      
        ProgressBar:setPortionComplete(i, countPhotos)
      end
      ProgressBar:done()
    end)
  end)
end

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Most Valuable Participant ,
Nov 14, 2019

Copy link to clipboard

Copied

It's not readily apparent where the "assertion failed" is coming from.   You'll have to insert logging print statements (see the SDK Guide) or use a debugger (e.g. my Debugging Toolkit or ZeroBrane IDE) to narrow down exactly where it's failing.

 

[Use the reply button under the first post to ensure replies sort properly.]

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 15, 2019

Copy link to clipboard

Copied

Thanks for the hint! Installed your plugin and found this error... The variable "keyword Person" on the first photo had an object inside, and on the second photo it was false...2019-11-15 120832.png

Only until I understood why...

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 15, 2019

Copy link to clipboard

Copied

 

Return value

(LrKeyword) The new keyword object, or false if a keyword already exists with the same name and parent, assuming that 'returnExisting' is not specified or false. If 'returnExisting' is true and the keyword with the same name and parent already exists, that keyword object will be returned.

Judging by the description in the SDK, when passed "return Existing = true", false cannot be returned...

keywordPerson = catalog:createKeyword( photo:getFormattedMetadata ("licensor")[c].LicensorName, nil, false, keywordCategory, true )

In my case, the "LrKeyword" object should return, and False is returned (((

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Most Valuable Participant ,
Nov 15, 2019

Copy link to clipboard

Copied

"In my case, the "LrKeyword" object should return, and False is returned ((("

 

Not sure what might going on.  I ran this slightly modified script with two photos selected, and it created two keywords under PERSON with names corresponding to the Licensor Name fields in the metadata. 

 

Try saving this exact script to a file and running it, using File > Plug-in Extras > Debugging Toolkit > Debug Script:

local Require = require 'Require'.path ("../common").reload ()
local Debug = require 'Debug'.init ()
require 'strict'

local LrApplication = import "LrApplication"
local LrProgressScope = import "LrProgressScope"
local LrTasks = import "LrTasks"

local catalog = LrApplication.activeCatalog ()

function showDialog(context)
  local props = LrBinding.makePropertyTable(context)
    local fillFormat = props.fillFormat
    prefs.fillFormat = fillFormat
    updateFill(fillFormat)
end

function updateFill(fillFormat)
  LrTasks.startAsyncTask(function()
    catalog:withWriteAccessDo("&Инициализация данных об участниках", function()
      local photos = catalog.targetPhotos
      local countPhotos = #photos
      local ProgressBar = LrProgressScope({
        title = "Инициализация данных об участниках для " .. 
          tostring(countPhotos) .. " файла(ов)"
      })
      local keywords = catalog:getKeywords()
      local keywordCategory
      for k, keyword in ipairs(keywords) do
        if  keyword:getName() == "PERSON" then
          keywordCategory = keyword
        end
      end
      for i, photo in ipairs(photos) do
        local participant = photo:getFormattedMetadata("licensor") or ""
        local participantCount = #participant
        for j = 1, participantCount do
        local keywordPerson = catalog:createKeyword( 
          photo:getFormattedMetadata ("licensor")[j].LicensorName, 
          nil, false, keywordCategory, true )
        photo:addKeyword( keywordPerson )
        end      
        ProgressBar:setPortionComplete(i, countPhotos)
      end
      ProgressBar:done()
    end)
  end)
end

updateFill (nil)

   

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 15, 2019

Copy link to clipboard

Copied

2019-11-16 004726.pngStill the same(((

Are the values in the Licensor Name the same? I do.

If I perform on one, then everything is correct!

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 15, 2019

Copy link to clipboard

Copied

lr_noproblem.giflr_problem.gifWith two and one photo

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Most Valuable Participant ,
Nov 15, 2019

Copy link to clipboard

Copied

I also got the "assertion failed" when I used two photos with the same LicensorName.  Below is a version that works correctly in that case. The problem seems to be calling catalog:createKeyword() more than once in a single invocation of catalog:withWriteAccessDo().   I don't know why that causes problems, but rewriting the code to do only one call to catalog:createKeyword() inside catalog:withWriteAccessDo() avoids the problem.

 

local Require = require 'Require'.path ("../common").reload ()
local Debug = require 'Debug'.init ()
require 'strict'

local LrApplication = import "LrApplication"
local LrProgressScope = import "LrProgressScope"
local LrTasks = import "LrTasks"

local catalog = LrApplication.activeCatalog ()

function showDialog(context)
    local props = LrBinding.makePropertyTable(context)
    local fillFormat = props.fillFormat
    prefs.fillFormat = fillFormat
    updateFill(fillFormat)
end

function updateFill(fillFormat)
    LrTasks.startAsyncTask(function()
        local photos = catalog.targetPhotos
        local countPhotos = #photos
        local ProgressBar = LrProgressScope({
            title = "Инициализация данных об участниках для " .. 
            tostring(countPhotos) .. " файла(ов)"})
        local keywords = catalog:getKeywords()
        local keywordCategory
        for k, keyword in ipairs(keywords) do
            if  keyword:getName() == "PERSON" then
                keywordCategory = keyword
            end
        end
        for i, photo in ipairs(photos) do
            local participant = photo:getFormattedMetadata("licensor") or ""
            local participantCount = #participant
            for j = 1, participantCount do
                catalog:withWriteAccessDo("&Инициализация данных об участниках", 
                function()
                    local keywordPerson = catalog:createKeyword( 
                      photo:getFormattedMetadata ("licensor")[j].LicensorName, 
                      nil, false, keywordCategory, true )
                    photo:addKeyword( keywordPerson )
                end)
            end      
        ProgressBar:setPortionComplete( i, countPhotos )
        end
        ProgressBar:done()
    end)
end

updateFill (nil)

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 15, 2019

Copy link to clipboard

Copied

Yes, thank you! This helps to avoid the problem! But creates another problem. On every action generated its step history, otkatyvaemyy on CTRL+Z. And this means, that if I wrong suddenly call its script on 500 photo, then me 500 times press CTRL+Z.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 15, 2019

Copy link to clipboard

Copied

Question then, and I can call catalog:createKeyword () inside catalog:withWriteAccessDo() write to another script, and call it from the current? I don't know is that allowed here? To have my keywords assigned first and then my actions executed, which was step 1 of the story?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 16, 2019

Copy link to clipboard

Copied

I am now trying to create a smart collection based on "licensor".

local Require = require 'Require'.path ("../common").reload ()
local Debug = require 'Debug'.init ()
require 'strict'

local LrApplication = import "LrApplication"
local LrProgressScope = import "LrProgressScope"
local LrTasks = import "LrTasks"

local catalog = LrApplication.activeCatalog ()

function showDialog(context)
    local props = LrBinding.makePropertyTable(context)
    local fillFormat = props.fillFormat
    prefs.fillFormat = fillFormat
    updateFill(fillFormat)
end

function updateFill(fillFormat)
    LrTasks.startAsyncTask(function()
        local photos = catalog.targetPhotos
        local countPhotos = #photos
        local ProgressBar = LrProgressScope({
            title = "Инициализация данных об участниках для " .. 
            tostring(countPhotos) .. " файла(ов)"})
        local keywords = catalog:getKeywords()
        local keywordCategory
        for k, keyword in ipairs(keywords) do
            if  keyword:getName() == "PERSON" then
                keywordCategory = keyword
            end
        end
        for i, photo in ipairs(photos) do
            local participant = photo:getFormattedMetadata("licensor") or ""
            local participantCount = #participant
            for j = 1, participantCount do
                catalog:withWriteAccessDo("&Инициализация данных об участниках", 
                function()				
					local foundPhotos = catalog:findPhotos {
						 searchDesc = {
							{
								criteria = "keywords",
								operation = "all",
								value = photo:getFormattedMetadata ("licensor")[j].LicensorName,
								value2 = "",
							},
							combine = "intersect",
						}
					} 
					local collectionPerson = catalog:createSmartCollection( photo:getFormattedMetadata ("licensor")[j].LicensorName, foundPhotos, nil, true )
                    local keywordPerson = catalog:createKeyword( photo:getFormattedMetadata ("licensor")[j].LicensorName, nil, false, keywordCategory, true )
                    photo:addKeyword( keywordPerson )
                end)
            end      
        ProgressBar:setPortionComplete( i, countPhotos )
        end
        ProgressBar:done()
    end)
end

updateFill (nil)

 But the following error falls out: "Assertion failed: packed". What am I doing wrong here? 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 16, 2019

Copy link to clipboard

Copied

And another question..."catalog:createKeyword( keyword Name, synonyms, includeOnExport, parent, return Existing)" - I did not find here an opportunity to manage all parameters of keywords, as, for example, People And export of synonyms. How is it possible to specify otherwise that this word takes the parameter PEOPLE?

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Most Valuable Participant ,
Nov 16, 2019

Copy link to clipboard

Copied

"On every action generated its step history, otkatyvaemyy on CTRL+Z. And this means, that if I wrong suddenly call its script on 500 photo, then me 500 times press CTRL+Z."

 

I think the workaround is to use a more complicated method of doing this that avoids calling catalog:createKeyword() with returnExisting = true, which I think is the cause of the problem:

 

1. Loop over the photos and build a table that maps LicensorName to existing LrKeyword objects.  Also build an array of LicensorNames that don't currently have keywords.

 

2. Inside catalog:withWriteAccessDo(), first create the keywords for the LicensorNames that currently don't have them, updating the table that maps LicensorName to LrKeyword as you go.  Then loop through all the photos, assigning the keywords to photos (using that table).

 

I have a plugin that uses this method without any issues.

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...