So have I… so. have. I.
Thanks to everyone’s help, and a lot of tinkering, I feel like I’m getting pretty close, but I’m still stuck on a few small things. In short, I’d like to create two versions of the script: (1) that opens the file or group in DEVONthink’s current viewer window (selecting/highlighting the file and previewing it, or in the case of groups, showing their contents), and (2) another that reveals the file or group, similar to how “reveal” works from the context menu of a search result.
Unfortunately, with both scripts, I keep getting hung up on two core things:
First, is it possible to get @ngan’s wonderful script to search all databases? I only have one big database, and two relatively small ones, but I’d love to be able to search all of them at once, similar to @korm’s great KM script. I tried just setting a variable for them, which works well when you just want to open the file. However, I can’t seem to get it to work when you want to reveal the file in your current viewer window
In any event, here’s a copy of the “reveal” script (the second one from above), which combines aspects of @ngan and @korm’s scripts. It will reveal files and groups appropriately, but doesn’t seem to search every database:
tell application "Finder"
set theSelection to selection as alias list
end tell
if theSelection ≠ {} then
set theFile to first item of theSelection
set theFilePath to POSIX path of (contents of theFile)
end if
tell application id "DNtp"
try
set theDatabases to databases
set theResults to {}
repeat with thisDatabase in theDatabases
set thisDatabasesResults to lookup records with path theFilePath in thisDatabase
set theResults to theResults & thisDatabasesResults
end repeat
if theResults = {} then
display notification "Pfad nicht in offenen Datenbanken enthalten!" with title "Lookup DEVONthink"
return
else
set root of viewer window 1 to (parent 1 of item 1 of theResults)
set selection of viewer window 1 to theResults
activate
end if
end try
end tell
As for the second problem, I could never get the “open” script from above to properly open the file or folder/group in the current DEVONthink viewer window. In other words, I couldn’t figure out how to adapt @ngan’s script so that instead of opening a new window, that it would do something similar in the viewer window that’s already open.
As always, thanks for any help you can lend. I’d be completely lost without everyone’s support. Also, apologies if I’ve butchered any DEVONthink verbiage above (or the English language, for that matter - Ha). Thanks again!
I only have a quick look at the script and my beginners’ comment as follows:
(1) remind you that DT only look up records in “databases” that are opened. So u need to make sure that all databases remain opened when u run the script or the script will only search in the currently opened database.
(2) logic: if file/s are index into different databases and your script is telling the viewer window to display the file/group in current window. And if you have more than one records in theResults (or same finder’s file in different databases), the script won’t know which one or where to open? You will need to look into the variable theResults to see what items have you retrieved by using the lookup command (I rarely used it) to get a better feel. Use “script debugger” with a free trial period for 15 days (I think) for debugging. The app can run script step-by-step and show the values/records/items in each var in the process in a user-friendly manner.
(3) if you have tagged ur item/s in DT, parent 1 of theResults can be a tag or a group (AFAIMA, there is no fixed rule to determine which one is parent 1, probably based on the time of the creation of each replicant?). That’s why I open a document window for theResults. You may need some code to find all parents of theResults and find the first Parents n that is a group. (This I am not 100% sure)
Might it be possible (via script) for DT to cache a list of all indexed files in a database on close or modification? Then the script can read that file to find files that aren’t open.
@ngan Thanks a ton for the helpful feedback. My intention was to only use the script with one file at time (via a file action in Alfred, which I’ve restricted to a single input). However, you hit the nail on the head with your third point! That explains the weird behavior that I noticed with the “reveal” script that I posted above. In short, occasionally it will errantly reveal the file or group in the Sidebar’s Tags (Globals section) or from the Favorites section (when the group is also located there). Do you know how to restrict it to only selecting the parent (group) from the Open Databases section?
Thanks again to everyone for all of your help!
@korm would have suggested to learn the trick by reading the dictionary or from other script… (for good intention).
Look for one line of code in this post as a starting point?
Find & Goto parent groups of all replicants of an item
Take a look at A script library to get the path of the frontmost document
And maybe this Script: Open DEVONthink record for PDF Expert tab
@pete31 - Thanks for your help. Ironically, your PDF Expert script was super helpful for fixing a different issue. I created a far more simplistic version of your script a few years ago to work with Alfred for shifting between active PDF documents (PDF Expert, Preview, Adobe Acrobat). I could never figure out how to do it efficiently with PDF Expert (because of its lack of Apple Script support) without running it through Alfred’s search, which never worked particularly well (because it was GUI-based). In any case, your solution with PDF Expert was genius (LSOF - etc.)! It completely solved that problem. Now that script works amazing!
As for this issue, while I’m probably overlooking something, it’s the later part of the problem that I’m struggling with (i.e., how to reveal what you’ve found). Instead of opening the file in DEVONThink, how do I consistently reveal it in the same active window (without opening a new window)? The script that I posted above works in most situations, but will sometimes select the file from the sidebar if its group is located in the Tags or Favorites sections (not the Open Databases section, where it should). Any ideas how to get it to reveal the file or group (instead of open it)?
Thanks again to everyone for all of their help!
This version shows the contents of a group or previews a record
-- opens the file or group in DEVONthink’s current viewer window (selecting/highlighting the file and previewing it, or in the case of groups, showing their contents)
tell application "Finder"
set theSelection to selection as alias list
end tell
if theSelection ≠ {} then
set theFile to first item of theSelection
set theFilePath to POSIX path of (contents of theFile)
end if
tell application id "DNtp"
try
set theDatabases to databases
set theResults to {}
repeat with thisDatabase in theDatabases
set thisDatabasesResults to lookup records with path theFilePath in thisDatabase
set theResults to theResults & thisDatabasesResults
end repeat
if theResults = {} then
display notification "Pfad nicht in offenen Datenbanken enthalten!" with title "Lookup DEVONthink"
return
else
set theRecord to (item 1 of theResults)
if type of theRecord = group then
set root of viewer window 1 to theRecord
set selection of viewer window 1 to theRecord
activate
else
set root of viewer window 1 to (parent 1 of theRecord)
set selection of viewer window 1 to (theRecord as list)
activate
end if
end if
end try
end tell
And this reveals a record
-- reveals the file or group, similar to how “reveal” works from the context menu of a search result
tell application "Finder"
set theSelection to selection as alias list
end tell
if theSelection ≠ {} then
set theFile to first item of theSelection
set theFilePath to POSIX path of (contents of theFile)
end if
tell application id "DNtp"
try
set theDatabases to databases
set theResults to {}
repeat with thisDatabase in theDatabases
set thisDatabasesResults to lookup records with path theFilePath in thisDatabase
set theResults to theResults & thisDatabasesResults
end repeat
if theResults = {} then
display notification "Pfad nicht in offenen Datenbanken enthalten!" with title "Lookup DEVONthink"
return
else
set theRecord to (item 1 of theResults)
set root of viewer window 1 to (root of (database of theRecord))
set selection of viewer window 1 to (theRecord as list)
activate
end if
end try
end tell
For testing I used a folder which I indexed in two databases but without tagging or replicating the group. It seems the scripts will always use the record in the database that was last used.
Have you tried the script library? With this it’s possible to open a DEVONthink record from a lot of apps, not only Finder
@pete31 Thanks a ton! These scripts are amazing, and I can now see what I was screwing up in the “reveal” script previously. I can’t thank you enough!
In the reveal script, by chance, is it possible to have DEVONthink select the parent folder/group in the Sidebar, too? At the moment, it selects the database - which fixes the problem I mentioned above about errantly selecting from the Tags or Shortcuts sections of the Sidebar - however, it doesn’t drill down any further in the Sidebar to let the user know they’re at in the hierarchy (based on the Sidebar alone - i.e., obviously you can still see it in the main window, however).
While I understand that you can’t select the actual file or group in the Sidebar (or else it would open the group, instead of just revealing it), I like the idea of quickly seeing where I’m at from the Sidebar by at least selecting its parent folder. In addition, it also makes it easier to subsequently run a search on a group that is in close proximity to the file/group you just revealed (which, in DT3, from what I understand, always requires you to actually select the group in the sidebar).
To accomplish this, I tried adding the “parent” line from your “open” script, but that didn’t change it’s end result:
set theRecord to (item 1 of theResults)
set root of viewer window 1 to (parent of (database of theRecord)) -- ADDED !!
set root of viewer window 1 to (root of (database of theRecord))
set selection of viewer window 1 to (theRecord as list)
activate
The hope was that it would first select the parent folder/group from the sidebar, leaving it expanded, before revealing the actual file/group. However, it seems to behave the same way (never expanding the database from sidebar). Is this possible?
I haven’t tried your script library yet. It’s probably a little beyond my skill set at the moment (AppleScript and DEVONthink). However, I’ll definitely take a look at it now!!! Thanks for sharing! Another part of the reason that I haven’t, is that I’m not quite as dependent on Finder, as this script might seem. I included Finder because I felt like it would be most helpful for other DT newbies, like myself. In fact, I’m still pretty surprised there isn’t a MacOS service included in DT3 that does the same thing (at least for those who prefer to go the index route, it feels like a must). In any case, as an Alfred user, it’s not as difficult to do similar things from other apps, like HoudahSpot, etc. Thanks again for all of your help!! I really appreciate it.
It’s only UI scripting (as I didn’t find another way) and it’s a little bit slow… But maybe that helps if your folder hierarchy isn’t “too deep”
-- reveals the file or group, similar to how “reveal” works from the context menu of a search result
-- expands the sidebar (but only with UI scripting so it's quite slow)
tell application "Finder"
set theSelection to selection as alias list
end tell
if theSelection ≠ {} then
set theFile to first item of theSelection
set theFilePath to POSIX path of (contents of theFile)
end if
tell application id "DNtp"
try
set theDatabases to databases
set theResults to {}
repeat with thisDatabase in theDatabases
set thisDatabasesResults to lookup records with path theFilePath in thisDatabase
set theResults to theResults & thisDatabasesResults
end repeat
if theResults = {} then
display notification "Pfad nicht in offenen Datenbanken enthalten!" with title "Lookup DEVONthink"
return
else
set theRecord to item 1 of theResults
set root of viewer window 1 to root of database of theRecord
set selection of viewer window 1 to theRecord as list
activate
set thisParent to parent 1 of theRecord
set theParents to {} & name of thisParent
repeat until thisParent = root of database of theRecord
set thisParent to parent 1 of thisParent
set beginning of theParents to name of thisParent
end repeat
if type of theRecord = group then
set isGroup to true
else
set isGroup to false
end if
tell application "System Events" -- expand sidebar with UI scripting
tell process "DEVONthink 3"
try
repeat with thisGroup in theParents
set thisGroupName to contents of thisGroup
set theUIElement to (a reference to (UI element 2 of UI element 1 of (first row of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1 whose value of static text 1 of UI element 1 is thisGroupName)))
if value of theUIElement = 0 then -- database / group is closed
click theUIElement
delay 0.15
end if
end repeat
if isGroup = true then
select (first row of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1 whose value of static text 1 of UI element 1 is (name of theRecord))
else
select (first row of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1 whose value of static text 1 of UI element 1 is (item -1 in theParents))
end if
on error
if isGroup = true then
select (first row of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1 whose value of static text 1 of UI element 1 is (name of theRecord))
else
select (first row of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1 whose value of static text 1 of UI element 1 is (item -1 in theParents))
end if
end try
end tell
end tell
end if
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
end try
end tell
Perhaps @cgrunenberg would consider this a feature request?
@pete31 Thanks for taking a crack at it. I really appreciate it.
Unfortunately, I think it might be time to throw in the towel on this one. I added a couple of short delays to help get rid of the errors, but the new script only seems to work intermittently. It also clicks the wrong things in the sidebar sometimes (e.g., Tags or Favorites sections, instead of Open Databases). Thanks for trying though. Can’t tell you how much I appreciate it!!
Assuming it’s not possible to do what I described previously, how do people quickly search within a given group?
It seems odd to require selection in the sidebar to search within a specific group (using search prefix - scope:selection), if you can’t also script it (or at least rely on the selection within main viewer (i.e., instead of sidebar’s selection). While I prefer to see the sidebar expand when revealing the file/folder/group anyways - to have a better sense of location or geography in the database’s hierarchy - it seems to make even more sense, given its importance to subsequent searches. I’ll keep my fingers crossed they address this one in the next beta…
Thanks again!
But that’s what you experienced before. While testing with a real database (no indexed files) I’ve also found that I couldn’t figure out which replicant would reveal. That’s something the DEVONthink people could comment on (would be very interesting to learn the logic behind it).
+1
Wonder how do you even set this up in KM……
The macro is triggered from a conflict menu that appears only in Finder. The script I posted is located inside the “Execute Applescript” action in the macro shown below.
The macro loops through each selected file in a selection (the “collection”). Of course a collection can have one member – the single selected file – or multiple.
Thank you.
Looks interesting k o r m.
Im new to KM so I have to find my way around. I thought it was just adding the script to Keyboard Maestro lol
I was wondering if I could get the group’s help with this script again? By way of reminder, one of the scripts that I originally posted was intended to “reveal” files from Finder in a new DEVONthink window (first, find the file in DEVONthink; then, open a new window for its parent folder/group in DEVONthink; finally, select the file in the new DEVONthink window). However, I’ve never been able to figure out how to get this particular script to work with more than one file at a time.
In the script below, it seems clear to me that the problem lies in the way that I’ve set the window (when opening it and setting its selection). However, I’ve never understood how to deal with this issue in DEVONthink. Because I’ve set the window’s name, in order to make a selection, when there is more than one file, they all open in the same window. Does anyone know how to fix those last couple lines of code, so that each file opens in its own window and is selected appropriately (i.e., the lines beginning with “set theWindow…”)?
Thanks again for all of your help!! To make things easy for everyone, I’ve also uploaded the script here: Download Script.
tell application "Finder"
set theSelection to selection as alias list
end tell
if theSelection ≠ {} then
set my text item delimiters to tab
set theFilePaths to {}
repeat with i in theSelection
set end of theFilePaths to POSIX path of (contents of i)
end repeat
end if
if theFilePaths ≠ {} then
repeat with i in theFilePaths
tell application id "DNtp"
try
set theDatabases to databases
set theResults to {}
repeat with thisDatabase in theDatabases
set thisDatabasesResults to lookup records with path i in thisDatabase
set theResults to theResults & thisDatabasesResults
end repeat
if theResults is not {} then
set theResultsParent to (first parent of first item of theResults)
set theWindow to open window for record theResultsParent
set theWindow's selection to theResults
else
display alert "the file/group does not exist in the current DT database"
end if
end try
end tell
end repeat
end if
I’ve no idea at the moment why your script doesn’t work over here but maybe using a “dummy” record in your global inbox to create new windows will do what you want to do
set newWindow to open window for record (get record with uuid "1A2A6304-21C2-4B7F-9932-3956C799462B") -- "dummy" record uuid
set record of newWindow to theResultsParent -- https://discourse.devontechnologies.com/t/set-record-for-window-random-article/8256/2?
activate
Hi @pete31 - Thanks for taking a look at this for me. It’s had me puzzled, in large part, because it seems like it should be easy enough to do in DEVONthink (especially since I can do it with one file without any problems).
I tried your suggestion but, unfortunately, was not able to have any luck with it. I might be doing something wrong, but, on my end, your amendment to the script just opens the dummy file (i.e., it doesn’t open the parent group in a new window and then select/highlight the file in the window - similar to how you might “reveal” it from search results, etc.). Thanks for taking a crack at it though.
Sorry I missed that you want a selection. This should work (but I didn’t try it in a repeat loop)
set newWindow to open window for record incoming group
set root of newWindow to root of (database of theResultsParent)
set selection of newWindow to theResultsParent as list
activate