Move | Duplicate| Replicate selected records [+LaunchBar]

I was running the script perfectly for several months, and it is very, very helpful!

I just upgraded to Growl through the AppStore, and now I am getting the same message, the the variable strReport is not defined, error -1763.

Any thoughts?

I uninstalled Growl, then reinstalled from the App Store. Now all seems back to normal.

Hello,

Have been using your script for a while and I wonder if you can post an updated version because in this thread there are many different updates and additions.

So if you don’t mind can you post the full version of the script again?

Thanks,

I think this is the version which I am using myself (attached).
DTMoveRecords-015.scpt.zip (461 KB)

Holy smokes! I’ve been manually replicating articles to groups using drag and drop or the contextual menu. I said, “There MUST be an easier way to do this!” and found your script a few moments ago. I threw it into my scripts folder, indexed in Launchbar, and WOW!

Thanks a bunch for sharing!

Great script, houthakker.

can it be modified to do the following:
a) ask for “Move”, “Duplicate” or “Replicate” before asking for the target folder.
b) Not show the result folder after success. and retain the same view as before running the script.
c) do not include folders/tags in the trash as a target.

Thanks!

This script is very interesting and powerful. Does anyone have more updated version that the one posted by OP above?

Just wanted to say that I found your script as a new user of DTPO and love it. This version is running fine on 10.9.3 without Growl installed. Thank you so much for sharing this functionality.

@houthakker – Many thanks for this great script. I’m having trouble getting it to run, no doubt through my own script ignorance.

I’ve saved the complete text in the Apple Script Editor, and invoke it from there by hitting the “Run” button, after having selected a record in DT.

I get the following error:
Syntax Error
Expected end of line but found “’’”

Note: the first of the 3 quotation marks appears to be an opening “smart quote”, while the other 2 are plain vanilla.

The Script Editor highlights the quotation mark that appears between register as application and houtkakker scripts, at the following point in the code:
" & strNames

tell application id “com.apple.systemevents”
– USE GROWL IF IT’S RUNNING
if (count of (every process whose name is “GrowlHelperApp”)) > 0 then
tell application id “com.Growl.GrowlHelperApp”
register as application “houthakker scripts” all notifications {pTitle} default notifications {pTitle} icon of application “DEVONthink Pro”
notify with name pTitle title strGrowlTitle application name “houthakker scripts” description strGrowlBody
end tell
else

Any thoughts?

Many thanks again.
Tom

The script in the zip that Rob posted six postings above this one (here) works without problems when opened in AppleScript Editor and Script Debugger. It appears, Tom, you might have inadvertently deleted part of the script or typed a character into the script that does not belong there. Things like that are easy to do in AppleScript Editor. On the possibility that an error might have been saved to the downloaded instance, I suggest quitting AppleScript Editor, deleting the bad copy of the script, and downloading a new instance.

Open the new instance in AppleScript Editor, compile it, and save it to a location in the Scripts menu of either DEVONthink

~/Library/Application Support/DEVONthink Pro 2/Scripts/… [add a folder of your own making to the end of the path]

or the system scripts menu

~/Library/Scripts/Applications/DEVONthink Pro

In the latter case, you might need to create the “DEVONthink Pro” folder. Then, you can use the script as Rob describes in this thread without needing AppleScript Editor.

(FWIW, Editor is an OK environment for writing and debugging scripts, but is not needed for day-to-day use of scripts. With Editor, it’s easy to introduce errors without noticing, and difficult to find their cause, sometimes.)

Korm - I’m grateful for your prompt, thorough and crystal clear reply.

I followed your instructions, and the script works like a charm. (The only glitch is the following error message, which comes after the script has successfully done what it was designed to do, and which I suspect has to do with some oddment in my Growl setup: error “The variable strReport is not defined.” number -2753 from “strReport”)

Thanks also for your observations on Apple Script Editor. I’ll be extra vigilant in the future, when I meddle with scripts in that environment.

Cheers,
Tom

Well, looks like there’s a bug in Rob’s script after all. It’s easy to fix. Open the script in AppleScript Editor and change this line


display dialog strReport & "

to this


display dialog "Notice:" & "

Note the double quotes at the end of the line. They introduce a string that spans several lines – make sure you leave the end-of-line double quotes.

Many thanks, korm - works perfectly now.

Quick question. I cannot edit the .scpt file in either Applescript Editor or Textmate. Although the script is brilliant and includes duplicate and replicate on the fly with d[space] or r[space], I was working on my database yesterday and was replicating like a storm and wanted to temporarily switch the default functions in the script.

I have upgraded to Yosemite 10.10 and cannot confirm whether I had the ability to edit the .scpt file. Any ideas?

The cause should be most probably the lacking of Growl on your system (that the script needs for reporting the outcome of the action).

Here is a copy where I commented out the reporting section


property pMove : "Move"
property pDup : "Duplicate"
property pRep : "Replicate"

property pDefaultVerb : pMove -- Default verb: may be switched to Duplicate (pDup) or Replicate (pRep) at run-time

-- ver 1.0		Allows double dot (..) as short-hand for parent group 
--				(to facilitate moving selected records up one level in the group hierarchy)
-- ver 0.9		Fixed a big involving search strings which include a space
-- ver 0.8		Clarified the Growl message: bold header: [Verb]d [N] records to:, body:[Destination]/n[List of records]
-- ver 0.7		Enhanced the "Group not Found" message for replication to remind user that replication
--				is only possible within a single database.
-- ver 0.6		The default verb (Move) can be overridden by prefixing the search string with "d " or "r "
--				(for "Duplicate" or "Replicate") in LaunchBar or the standard dialog
--				(a single verb letter followed by a single space before the search string itself)
-- ver 0.5		Can get the search string from LaunchBar
-- ver 0.4		Allows target databases (where their names match) as well as target folders
--				(the default incoming group of the database is used as the destination)

property pVer : "1.0"
property pTitle : "  to target group" & "    " & pVer

property pstrDelim : "    "

on run
	set lstSelns to GetDevnSelns()
	if lstSelns ≠ {} then
		set strNames to GetNameList(lstSelns)
		set strCmd to GetSearchString(pDefaultVerb, strNames)
		if strCmd ≠ "" then
			set {strVerb, strFind} to ParseCmd(strCmd)
			if strFind ≠ "" then ProcessSelns(lstSelns, strNames, strVerb, strFind)
		end if
	end if
end run

-- GET THE TARGET GROUP SEARCH STRING FROM LAUNCHBAR
on handle_string(strCmd)
	if strCmd ≠ "" then
		set lstSelns to GetDevnSelns()
		if lstSelns ≠ {} then
			set {strVerb, strFind} to ParseCmd(strCmd)
			if strFind ≠ "" then
				set strNames to GetNameList(lstSelns)
				ProcessSelns(lstSelns, strNames, strVerb, strFind)
			end if
		end if
	end if
end handle_string

on ParseCmd(strCmd)
	set {strVerb, strFind} to {pDefaultVerb, ""}
	set text item delimiters to space
	set lstParts to text items of strCmd
	if length of lstParts > 1 then
		set strFirst to first item of lstParts
		ignoring case
			if strFirst is in {"m", "d", "r"} then
				if strFirst = "m" then
					set strVerb to pMove
				else if strFirst = "d" then
					set strVerb to pDup
				else if strFirst = "r" then
					set strVerb to pRep
				end if
				set strFind to (items 2 thru end of lstParts) as string
			else
				set strFind to strCmd
			end if
		end ignoring
	else
		set strFind to strCmd
	end if
	{strVerb, strFind}
end ParseCmd

on ProcessSelns(lstSelns, strNames, strVerb, strFind)
	-- CHECK THAT A KNOWN VERB IS SPECIFIED AT THE TOP OF THE SCRIPT
	if strVerb is not in {pMove, pDup, pRep} then
		tell application id "com.apple.systemevents"
			activate
			display dialog "\"" & strVerb & "\": unknown value for pDefaultVerb" & return & return & "Expected Move | Duplicate | Replicate"
		end tell
		return
	end if
	
	tell application id "com.devon-technologies.thinkpro2"
		-- GET FILTERED SET OF POSSIBLE DESTINATIONS
		if strVerb ≠ pRep then
			-- BOTH OPEN DATABASES WITH MATCHING NAMES
			set lstParent to (incoming group of databases where name contains strFind)
			
			-- AND FOLDERS WITH MATCHING NAMES
			repeat with oDb in databases
				set lstParent to lstParent & (parents of oDb where name contains strFind)
			end repeat
		else -- OR, IN THE CASE OF REPLICATION, IN CURRENT DATABASE 
			set lstParent to (parents of current database where name contains strFind)
		end if
		
		-- ALLOW FOR DOUBLE DOT (..) AS REFERENCE TO PARENT DIRECTORY OF SELECTED ITEMS
		if strFind = ".." then set end of lstParent to first item of parents of (first item of lstSelns)
		
		-- BUILD NUMBERED MENU OF DESTINATION NAMES
		set lngParents to length of lstParent
		if lngParents > 0 then
			set lngDigits to length of (lngParents as string)
			set lstMenu to {}
			repeat with i from 1 to lngParents
				tell item i of lstParent
					set strName to (name of its database) & its location & its name
				end tell
				if strName = "Inbox/Inbox" then set strName to "Global Inbox"
				set end of lstMenu to my PadNum(i, lngDigits) & pstrDelim & strName
			end repeat
			
			-- CHOOSE DESTINATION
			tell application id "com.apple.systemevents"
				activate
				set varTargets to choose from list lstMenu with title strVerb & pTitle with prompt strVerb & ":
			
" & strNames & "

to target group:" default items {first item of lstMenu} without multiple selections allowed
			end tell
			if varTargets is not false then
				
				-- 	RETRIEVE CHOSEN DESTINATION BY NUMERIC INDEX
				set my text item delimiters to space
				set oTarget to item ((first text item of (first item of varTargets)) as integer) of lstParent
				
				-- MOVE | DUPLICATE | REPLICATE SELECTED ITEMS TO DESTINATION
				if strVerb = pMove then
					repeat with oRec in lstSelns
						move record oRec to oTarget
					end repeat
				else if strVerb = pDup then
					repeat with oRec in lstSelns
						duplicate record oRec to oTarget
					end repeat
				else if strVerb = pRep then
					repeat with oRec in lstSelns
						replicate record oRec to oTarget
					end repeat
				end if
				
				-- NOTIFY RESULT BY GROWL (IF INSTALLED) OR WITH DIALOG BOX
				my Announce(oTarget, strVerb, (length of lstSelns), strNames)
				open window for record oTarget
				activate
			end if
		else
			if strVerb ≠ pRep then
				set strRepNote to ""
			else
				set strRepNote to "
				
(If you were attempting to replicate to another open database, note that DevonThink only supports replication within a single database)"
			end if
			tell application id "com.apple.systemevents"
				activate
				display dialog "No open groups contain the string:" & "
	
		" & strFind & strRepNote buttons {"OK"} default button "OK" with title strVerb & pTitle
			end tell
		end if
	end tell
end ProcessSelns

on GetDevnSelns()
	tell application id "com.devon-technologies.thinkpro2"
		return selection
	end tell
end GetDevnSelns

on GetSearchString(strVerb, strNames)
	set strFind to ""
	-- GET  SUB-STRING TO FILTER LIST OF TARGETS
	tell application id "com.apple.systemevents"
		activate
		set strFind to text returned of (display dialog strVerb & ":" & return & return & strNames & return & ¬
			"Enter search string to list target groups:" default answer "" buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel" with title strVerb & pTitle)
	end tell
	return strFind
end GetSearchString

on GetNameList(lstSelns)
	-- BUILD BULLETED LIST OF SELECTION NAMES
	set strNames to ""
	repeat with i from 1 to count of lstSelns
		set strNames to strNames & "• " & name of (item i of lstSelns) & return
	end repeat
	return strNames
end GetNameList

-- REPORT RESULT
(*
on Announce(oGroup, strVerb, lngRecords, strNames)
	tell application id "com.devon-technologies.thinkpro2" to set {strDb, strPath, strFolder} to {name of database, location, name} of oGroup
	set strGrowlTitle to strVerb & "d " & (lngRecords as string) & " records to:"
	set strGrowlBody to strDb & strPath & strFolder & "
	
" & strNames
	
	tell application id "com.apple.systemevents"
		-- USE GROWL IF IT'S RUNNING
		if (count of (every process whose name is "GrowlHelperApp")) > 0 then
			tell application id "com.Growl.GrowlHelperApp"
				register as application "houthakker scripts" all notifications {pTitle} default notifications {pTitle} icon of application "DEVONthink Pro"
				notify with name pTitle title strGrowlTitle application name "houthakker scripts" description strGrowlBody
			end tell
		else
			-- (OR USE A STANDARD DIALOG)
			tell application id "com.apple.systemevents"
				activate
				display dialog strReport & "
				
(This script works best if Growl is installed)" buttons {"OK"} with title pTitle
			end tell
		end if
	end tell
end Announce
*)

-- GET A DIGIT STRING OF MINIMUM WIDTH (LEFT-PADDING WITH ZEROS WHERE NEEDED)
on PadNum(lngNum, lngDigits)
	set strNum to lngNum as string
	set lngGap to (lngDigits - (length of strNum))
	repeat while lngGap > 0
		set strNum to "0" & strNum
		set lngGap to lngGap - 1
	end repeat
	strNum
end PadNum

If you want you can add reporting based on OS X notification center.

johseb, that did the trick. Thank you for taking the time to edit the script for me. I have not heard of scripts being unable to be opened due to lack of Growl.

FWIW I’ll take a look at that in the next week or two and remove the Growl dependency from the Github copy.

OS X notifications make more sense now.

Is anybody else having trouble running this script since the 2.8.4 release of DTPO?

I am able to enter a search string in the box but then no feedback after hitting Enter. I get the following errors when running repeatedly from either LaunchBar or the AppleScript editor:

[b]Error Number: -2763

No result was returned from some part of this expression.[/b]

or

Can’t make «class DTpr» id 16323 of «class DTkb» id 3 of application “DEVONthink Pro” into type vector.
When run from Script Editor.app, the focus turns to the word “database” in the script as “this expression.”

You can tell from my post that I am an AppleScript neophyte. I’d appreciate any help, since this script is my primary tool for shuffling items around my databases.

Yes, I am having the same issue.

Its a great script, and the one I absolutely use the most.

Also inexperienced with AppleScript, so working hard to figure it out without much luck.

I’ve found that if I use a search string of one or two characters, AND those characters are in the open databases’ names, it works and opens every group with those characters.

If I use three characters, I get the error.

If I use one or two characters that are not in the name of an open database, I get the error.

I have been trying to dissect the script to figure out why the number of characters matters and the relationship to the open databases matters, but just don’t know enough to figure it out yet.