Database selection in Applescript ignored when adding or moving a file

Hi there!

Recently I have had to move away from Evernote and have chosen DevonThink 3 to facilitate my electronic archive. I have migrated all my EN notes to DNTP using my own Applescript, because the built-in option did not fit my needs. All has worked out just fine, except for one little detail: somehow DNTP does not seem to always put the records in the specified database. For some reason it seems to keep using the database that has been chosen by the app on startup.

My solution for the EN notes was to only have one database open in DNTP while running the script to import them and make sure the script was only processing EN notes that had to go in that particular database.

But now I have created a smart rule that fires as soon as I assign a tag ‘2archive’ that is supposed to put the record in the correct database based on its tags. There I am running into the same issue again, but this time it is unworkable to have only database open.

I guess I am doing something wrong in selecting the desired database and telling DNTP to use that selected database, but I cannot seem to find what.

Here’s my script:

on performSmartRule(theRecords)
tell application id "DNtp"
	log "Archiving started..."
	repeat with theRecord in theRecords
		
		# Process tagList
		set theTags to tags of theRecord
		set dntpLocations to {}
		set dntpDbNames to {}
		set tagList to {}
		repeat with theTag in theTags
			if texts 1 thru 3 of ("" & (theTag)) is "su." then
				set dntpLocations to dntpLocations & texts 4 thru -1 of ("" & (theTag))
			end if
			if texts 1 thru 3 of ("" & (theTag)) is "cl." then
				set dntpLocations to dntpLocations & texts 4 thru -1 of ("" & (theTag))
			end if
			if ("" & (theTag)) is in {"st.zero", "st.one", "st.two", "st.three"} then
				if "Private" is not in dntpDbNames then
					set dntpDbNames to dntpDbNames & "Private"
				end if
			else if ("" & (theTag)) is in {"st.company"} then
				set dntpDbNames to dntpDbNames & "Company"
		end repeat
		
		# Start processing prepped Note
		set dntpDbName to null
		set dntpLocation to null
		set replicateLocations to {}
		
		if (count of dntpLocations) is not 0 then
			set dntpLocation to first item of dntpLocations
			set replicateLocations to rest of dntpLocations
		end if
		
		repeat with dntpDbName in dntpDbNames
			set dBase to database dntpDbName
			set theLocation to (create location dntpLocation) in dBase
			move record theRecord to theLocation
			
			repeat with dntpLoc in replicateLocations
				set theLocation to (create location dntpLoc) in dBase
				replicate record theRecord to theLocation
			end repeat
			
		end repeat
	end repeat
end tell
end performSmartRule

Using the logging option in the AppleScript Editor I have managed to check whether the dBase got properly set and if I could retrieve its name, and that showed the expected result, but still the record gets moved to a different database.

Any help would be highly appreciated!

Thanks/Jeroen

You should use characters, not texts.

It seems you are reusing variable names.

Perhaps your parenthesis in the create location lines are off. I don’t use AppleScript, but I’d try to include in dBase in the parenthesis.

Aside: what happens if your dntpLocations are empty? If that can’t happen, why do you check for it? If it can happen, why does the script continue in that case?

Edit: the whole “stuff something in a list, but I’m only interested in the first of its element anyway” looks weird. The checks for tag names should terminate once a match is found.

Why is this

so contrived? Wouldn’t
if (texts 1 thru 3 of theTag) is "su."
do the same thing? And why don’t you factor out
(texts 1 thru 3 of theTag)
in a variable before the tests? That would make the code more readable and marginally more efficient.
Also, chaining ifs that test for disjunctive conditions is irritating – using else would make the code clearer (a lot)

Why do you care if “Private” occurs more than once in you database name list, but ignore that issue for the other databases?

It’s just over-careful programming. The first initialization is quite pointless.

Thanks for your thoughts and comments. I agree that I could clean up and optimise the code a little resulting both simpler and more readable code. But those parts do not seem to cause the issue with the record being put in the wrong database…

@chrillek:
I have changed the parenthesis in the ‘create location’ instruction and that seems to do the trick! Good catch: apparently I was creating the location in the active database before telling DNTP the target database.

Many thanks for your help and fast response, highly appreciated!

Cheers/Jeroen

In my mind, unclean code reflects a less than complete understanding of the process. And if you want other people to read your code, you should make it as easy as possible for them. That would include adding comments to explain your intentions.

And I’m still confused as to what you’re doing there. Do you want to move and replicate the same record to different databases, duplicating it? Why? And is that even possible with move – the verb seems to indicate that the record leaves one place and goes to another one.
If you want to move the record only to one database, why all that list stuff?

Thanks for making that point. To be frank, I am completely new to posting on forums, so I will need to learn a couple of things here and there. Next time I will put some serious effort in cleaning and explaining my code before posting.

To elaborate my use case a little more: I am saving all invoices that I receive and create in PDF format in a dedicated folder. That folder is being watched by Hazel. Hazel has some rules to put these PDFs in DNTP. Depending on the situation each PDF can end up in:

  • the general Inbox of DNTP, or
  • in the inbox of my Private database, or
  • in the inbox of my Company database

My code is intended to be used to process all these inboxes after a record has been tagged using my tagging system. The idea is that any record tagged with ‘st.zero’, ‘st.one’, ‘st.two’ or ‘st.three’ relates to one of for stakeholders that I consider to be private and therefore needs to moved to the Private database.

Next, any tag that starts with ‘su.’ is supposed to represent a ‘supplier’ of some sort and implies that the record needs to be filed in a location with the name of that supplier. A similar rule applies to any tag that starts with ‘cl.’, which is supposed to represent a ‘client’. In my situation I actually do have invoices that relate both to a supplier and a client (sounds funny, I know, but it happens), or to multiple clients (for example when I need to invoice a client via a broker).

In those cases I want to replicate the record to additional locations in the same database. Up till now I do not have situations where a record has to go into two databases. But I do realise now that the code actually contains the option to process the record into multiple databases. And that there is a flaw in the code now, because of the ‘move’ that I do. The end result would either be that the record would only sit in the last database that would be in the dntpDbNames array, or the code would throw an error because a replica of the record cannot stay behind in one database when the record is being moved to another database.

My smart rule fires the code after tagging the record with ‘2archive’, which I manually do after I have finished renaming and tagging the record.

Anyway, I hope this clarifies a little. I will improve my code in the coming days, include additional comments and post the result

Thanks for educating me!

Perhaps you’re making it more complicated that necessary.

  • you could easily have Hazel send the files to the correct DT group
  • or have DT do the tagging (is that needed for anything but to determine which group the file goes to?) and grouping itself.

I’ve written a sample script for the second approach sike time ago

A more readable version is if theTag begins with "su." then

1 Like

I am still in a transition from Evernote to DNTP. With EN I have been running one big AppleScript to perform a whole lot of automated recognitions and classification. But the documents that cannot be fully recognised and classified will need to go through one of the inboxes for manual processing.

For now I have just changed the target system for storing from EN to DNTP. I am expecting that in time I will be moving my AppleScript from Hazel to DNTP. Now that you have helped me fixing the problem in my archiving smart rule, I can start focussing on eliminating Hazel.

Thanks for the link to your post ‘Using a single smart rule instead of Hazel’. I will definitely take a look at that!

Here is a simplifed automation of the core you seem to be describing.

  • Folder in the Finder receives files.
  • DEVONthink picks them up, examines the tags, and moves each to the Inbox of their respective database.

There is no scripting involved in this screencast.

1 Like