Page 1 of 1

See what groups a publication belongs to.

Posted: Sun Oct 04, 2020 5:11 pm
by Wobble
Hi there,

I am expanding Zach’s (Aliases zvh) “Autolinking Bookends and DEVONthink records” script to create tags in Devonthink that correspond to the Bookends groups that a given publication item belongs to. For that I need a list of all of those groups.

It is possible to see list I need in Bookends as a groups column

I have written a script to do this, by searching through each group for the publication item.

Code: Select all

tell application "Bookends"
	tell front library window
		set theAllBEGroupIDs to get (id of group items)
		set BEGroupList to {"ASTest1"}
		repeat with BEGroup in BEGroupList
			set theBEIDs to get (id of publication items of group item BEGroup whose date modified comes after lastRunTime)
			if theBEIDs is not {} then
				repeat with theBEID in theBEIDs
						set thisReference to first item of (publication items whose id is theBEID)
						set {theBEID, theBEPaths, theBEAuthor, theBEEditor, theBETitle, theBEPublicationDate} to {id, path of attachment items, authors, editors, title, publication date string} of thisReference
						-- get a list of groups that the reference belongs to
						set theGroupsThatReferenceBelongsToList to {}
						repeat with theBEGroupID in theAllBEGroupIDs
								set currentGroup to first item of (group items whose id is theBEGroupID)
								--search Bookends Group to see if the current publication item belongs to it
								set inCurrentGroup to first item of (publication items of currentGroup whose id is theBEID)
								if inCurrentGroup is not {} then
									set end of theGroupsThatReferenceBelongsToList to currentGroup
								end if
							end try
						end repeat
					end try
				end repeat
			end if
		end repeat
	end tell
end tell
Is there a more efficient way to get this information?

Thanks in advance,


Re: See what groups a publication belongs to.

Posted: Sun Oct 25, 2020 10:02 am
by ComplexPoint
Not sure if this is any faster (I would personally tend to do this in JS, which makes some of these things a bit easier and faster), but here FWIW is a variant approach in AppleScript:

Code: Select all

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

-- Rob Trew @2020

on run
    set groupIDLists to itemIDGroupZip()
    tell application "Bookends"
        tell front library window
            set publication to item 1 of ((its selected publication items) as list)
            my groupsForReference(groupIDLists, publication)
        end tell
    end tell
end run

------------------------- BOOKENDS -----------------------

-- itemIDGroupZip :: Bookends () -> [[(String, [String])]]
on itemIDGroupZip()
    -- A list of group names paired with lists of reference IDs
    tell application "Bookends"
        tell front library window
            tell (a reference to group items)
                my zip(name, id of publication items)
            end tell
        end tell
    end tell
end itemIDGroupZip

-- groupsForReference :: [[(String, [String])]] -> 
-- Publication -> [String]
on groupsForReference(groupZip, publication)
    -- A list of names of the groups of which
    -- the given publication is a member
    set idString to id of publication
    script f
        on |λ|(pair)
            if item 2 of pair contains idString then
                {item 1 of pair}
            end if
        end |λ|
    end script
    concatMap(f, groupZip)
end groupsForReference

------------------------- GENERIC ------------------------

-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
    set lng to length of xs
    set acc to {}
    tell mReturn(f)
        repeat with i from 1 to lng
            set acc to acc & (|λ|(item i of xs, i, xs))
        end repeat
    end tell
    if {text, string} contains class of xs then
        acc as text
    end if
end concatMap

-- min :: Ord a => a -> a -> a
on min(x, y)
    if y < x then
    end if
end min

-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    -- 2nd class handler function lifted into 1st class script wrapper. 
    if script is class of f then
            property |λ| : f
        end script
    end if
end mReturn

-- zip :: [a] -> [b] -> [(a, b)]
on zip(xs, ys)
    -- A list of step-wise pairs drawn from xs and ys
    -- up to the length of the shorter of those lists.
    set lng to min(length of xs, length of ys)
    set zs to {}
    repeat with i from 1 to lng
        set end of zs to {item i of xs, item i of ys}
    end repeat
    return zs
end zip