Most recently changed item in a group

Hi there,

maybe it’s just me being new to DT and AppleScript …

Is there a way to look up the most recently changed item in a group?

search “” age:3600 is not what I am looking for …

(I want to use its modification date when calling an API, telling the API only to return data newer than this.)


Here’s a simple example:

tell application id "DNtp"
	set theGroup to current group
	set theChildren to children of theGroup
	set theLatestRecord to missing value
	repeat with theRecord in theChildren
		set theDate to modification date of theRecord
		if (theLatestRecord is missing value or theDate > theLatestDate) then
			set theLatestRecord to theRecord
			set theLatestDate to theDate
		end if
	end repeat
end tell

Hi Christian,

thank you!

The group I will be using this for will have +5k records. At first glance, a bubble sort approach doesn’t seem like a feasible solution?

Currently I use the modification date of the group itself, and that’s good enough until I copy it or otherwise modify it.

Another idea cloud be to create a distinct record _Last Modifiction. Upon receiving the APIs response, I’d touch it to reflect the datetime of the last call to the API.

From DTs point of view, which (or which else) would be good practise?


Sorting isn’t necessary if you’re only interested in the latest modification date. And bubble sort is probably the slowest sorting algorithm, its performance is O(n*n) whereas the above snippet requires O(n).

Which API are you referring to?

You’re right, we’d only need to step through all records once.

I am working on a script that imports and then regularly updates a DT group from Pinboard. It’s of course based off yours, but has some, for my usecase, usefull additions. In case you want to have a look, go ahead.

You could also add the date as a comment to the group, this would be more user friendly.

and if the group contains subGroups, then you may want to walk the tree, e.g.

-- lastModifiedInGroup :: DTGroup -> 
--        {recName :: String, rec :: DTRecord,  changed :: DateTime }
on lastModifiedInGroup(dtGroup)
    using terms from application "DEVONthink Pro"
        script laterMod
            on |λ|(a, x)
                set dte to modification date of x
                if dte > changed of a then
                    {recName:name of x, rec:x, changed:dte}
                end if
            end |λ|
        end script
        set xs to children of dtGroup
        if xs ≠ {} then
            my foldlTreeDT(laterMod, ¬
                {changed:modification date of (item 1 of xs)}, dtGroup)
            missing value
        end if
    end using terms from
end lastModifiedInGroup

-- TEST  ------------------------------------------------------------
on run
    tell application id "DNtp"
        my lastModifiedInGroup(current group)
    end tell
end run

-- DT TRAVERSAL ------------------------------------------------------

-- foldlTreeDT :: (a -> DTItem -> a) -> a -> DTItem -> a
on foldlTreeDT(f, acc, dtItem)
    using terms from application "DEVONthink Pro"
        script go
            property mf : mReturn(f)'s |λ|
            on |λ|(a, x)
                foldl(go, mf(a, x), children of x)
            end |λ|
        end script
        |λ|(acc, dtItem) of go
    end using terms from
end foldlTreeDT

-- GENERIC FUNCTIONS --------------------------------------------------

-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
    tell mReturn(f)
        set v to startValue
        set lng to length of xs
        repeat with i from 1 to lng
            set v to |λ|(v, item i of xs, i, xs)
        end repeat
        return v
    end tell
end foldl

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

:bulb: Thanks, I’ll use that!

Thanks, bookmarked :slight_smile: