Automatic Filing of PDFs by Keywords

Get help. Get answers. Let others lend you a hand.

Moderator: Mr_Noodle

Automatic Filing of PDFs by Keywords Sat Dec 29, 2012 11:00 pm • by Bryan
I have been attempting to come up with a set of rules to file PDFs by their associated keywords. I have the ScanSnap that allows me to assign keywords by highlighting certain terms. I then want to have those files matched up with client subfolders in my Clients folder. I have hit a bit of a snag with an embedded Applescript. I am simply trying to determine how to get the keywords out in an applescript, and the closest I can come is to get the files properties. I stubbed out a bit of code to throw up a dialog with the properties in it just so I could see what I was working with. The code is as follows:

Code: Select all
try
   tell application "Finder"
      set displayProperties to (get properties of theFile)
   end tell
   display dialog displayProperties
on error
   display dialog "Didn't Work"
end try


However, I get an error. The console messages are as follows:

Code: Select all
2012-12-29 20:51:18.644 hazelworker[50217] Processing folder Clients (forced)
2012-12-29 20:51:20.721 hazelworker[50217] 2012_12_26_14_24_19.pdf: Rule Change Name to Keywords matched.
2012-12-29 20:51:21.726 hazelworker[50217] [Error] AppleScript failed: Error executing AppleScript on file /Volumes/Snow Leprd/Data/Clients/2012_12_26_14_24_19.pdf.
2012-12-29 20:51:21.728 hazelworker[50217] AppleScript error: {
    NSLocalizedDescription = "No user interaction allowed.";
    NSLocalizedFailureReason = "No user interaction allowed.";
    OSAScriptErrorAppAddressKey = "<NSAppleEventDescriptor: [0x0,2 \"hazelworker\"]>";
    OSAScriptErrorAppNameKey = hazelworker;
    OSAScriptErrorBriefMessageKey = "No user interaction allowed.";
    OSAScriptErrorMessageKey = "No user interaction allowed.";
    OSAScriptErrorNumberKey = "-1713";
    OSAScriptErrorRangeKey = "NSRange: {0, 0}";
}
2012-12-29 20:51:22.047 hazelworker[50217] Done processing folder Clients


Ultimately, I would like to know what is causing the error so I don't make the same mistake in the future, as well as what code I would actually need for this rule. For the rule, I see the most straightforward way is to make the name of the file reflect the keywords, and then see if the name of the file matches up with another folder in another rule. I would be really happy if I could sort into the appropriate subfolder directly with the keywords, but I don't think I could do that directly.

Thank you for any help.

Bryan
Bryan
 
Posts: 25
Joined: Wed Jan 11, 2012 4:34 pm
Location: Maryland

Re: Automatic Filing of PDFs by Keywords Sun Dec 30, 2012 11:27 am • by a_freyer
The reason that AppleScript is crashing is that the display dialog block is not allowed to be called in that way. The short story is that OSX does not permit Hazel to run applescripts in the way you see them run from AppleScript editor. Luckily, there is an easy solution:

Code: Select all
try
   tell application "Finder"
      set displayProperties to (get properties of theFile)
   end tell
   tell application "System Events"
       activate
       display dialog displayProperties
   end tell
on error
   tell application "System Events"
       activate
       display dialog "Didn't work"
   end tell
end try
a_freyer
 
Posts: 631
Joined: Tue Sep 30, 2008 9:21 am
Location: Colorado

Re: Automatic Filing of PDFs by Keywords Sun Dec 30, 2012 11:41 am • by a_freyer
As far as your keyword sorting, you will be able to sort directly if you can retrieve the keywords from the applescript. Look into hazelExportTokens and Sort into Subfolder
a_freyer
 
Posts: 631
Joined: Tue Sep 30, 2008 9:21 am
Location: Colorado

Re: Automatic Filing of PDFs by Keywords Wed Jan 02, 2013 1:53 pm • by Bryan
a_freyer

Thanks, that got me past the error, but I am still not seeing the file properties. I just got the "Didn't work." I have tried to get the properties through both the Finder and System Events. It is impossible to search for this answer since when you mention "keywords" in the search, you get all this info about Applescript Keywords, which obviously is not what I am looking for.

I agree, hazelExportTokens are the way to go, but I have to get something into them. Does anyone know how to access the keywords property? There has to be some dictionary key to get to them, but I can't even get all of the property information yet.

Thanks,
Bryan
Bryan
 
Posts: 25
Joined: Wed Jan 11, 2012 4:34 pm
Location: Maryland

Re: Automatic Filing of PDFs by Keywords Wed Jan 02, 2013 2:11 pm • by a_freyer
I posted the previous script without testing or giving much thought to what you're extracting. What your script is trying to do is display an object in a dialog box - that's what's crashing AppleScript.

What you should do is this:
Code: Select all
   get comment of theFile as string


Or in the full block:

Code: Select all
try
   tell application "Finder"
      set displayProperties to (get comment of theFile ) as string
   end tell
   display dialog displayProperties
on error
   display dialog "Didn't Work"
end try


If your keywords are not within the spotlight comments, then you'll have to use a shell script with mdls
a_freyer
 
Posts: 631
Joined: Tue Sep 30, 2008 9:21 am
Location: Colorado

Re: Automatic Filing of PDFs by Keywords Thu Jan 03, 2013 8:41 pm • by Bryan
Somehow I knew when I started this that shell scripting was going to rear it's head in this. The keywords are not returned in the Spotlight comments, but they do pop up in mdls. I have redone my applescript, and still get a "didn't work" from my error block. It is obviously not happy with my shell script (which I was trying to avoid in the first place).

Here is my code:
Code: Select all
tell application "Finder"
   
   set posixPath to POSIX path of ((item theFile) as text)
   
end tell


try
   set returnKeywords to last paragraph of (do shell script "mdls -name kMDItemKeywords " & posixPath) as text
   
on error
   
   tell application "System Events"
      activate
      display dialog "Didn't work"
   end tell
   
end try

-- Now dig out the file keywords
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "kMDItemKeywords                     = ("
set E to text item 2 of returnKeywords
set AppleScript's text item delimiters to space
set F to text items of E

tell application "System Events"
   activate
   display dialog returnKeywords
end tell


I am obviously trying to restrict the mdls to my specific lookup of the keywords. I am not sure that the rest of the code is not causing part of the error, but it is definitely kicking an error from the first part.

Here is the Console log:
Code: Select all
2013-01-03 18:31:40.216 hazelworker[79815] Processing folder Clients (forced)
2013-01-03 18:31:42.266 hazelworker[79815] 2012_12_26_14_24_19.pdf: Rule Change Name to Keywords matched.
2013-01-03 18:33:42.678 hazelworker[79815] [Error] AppleScript failed: Error executing AppleScript on file /Volumes/Snow Leprd/Data/Clients/2012_12_26_14_24_19.pdf.
2013-01-03 18:33:42.679 hazelworker[79815] AppleScript error: {
    NSLocalizedDescription = "System Events got an error: AppleEvent timed out.";
    NSLocalizedFailureReason = "AppleEvent timed out.";
    OSAScriptErrorAppAddressKey = "<NSAppleEventDescriptor: [0x0,1f8af89 \"System Events\"]>";
    OSAScriptErrorAppNameKey = "System Events";
    OSAScriptErrorBriefMessageKey = "AppleEvent timed out.";
    OSAScriptErrorMessageKey = "System Events got an error: AppleEvent timed out.";
    OSAScriptErrorNumberKey = "-1712";
    OSAScriptErrorRangeKey = "NSRange: {0, 0}";
}
2013-01-03 18:33:43.200 hazelworker[79815] Done processing folder Clients


Again, any help would be greatly appreciated.

Bryan
Bryan
 
Posts: 25
Joined: Wed Jan 11, 2012 4:34 pm
Location: Maryland

Re: Automatic Filing of PDFs by Keywords Fri Jan 04, 2013 3:39 pm • by Mr_Noodle
Well, the error reported is that the script is timing out which isn't helpful. I suggest printing out different variables at different points in the script to isolate where it's failing. That said, you do already know that the shell script part is failing so try running the script in the shell and also try using AppleScript Editor to do edit and test.
Mr_Noodle
Site Admin
 
Posts: 11951
Joined: Sun Sep 03, 2006 1:30 am
Location: New York City

Re: Automatic Filing of PDFs by Keywords Fri Jan 04, 2013 6:27 pm • by a_freyer
You're also probably going to have to wrap your posixPath var in quotes when you pass to the do shell script block
a_freyer
 
Posts: 631
Joined: Tue Sep 30, 2008 9:21 am
Location: Colorado

Re: Automatic Filing of PDFs by Keywords Mon Jan 07, 2013 7:30 pm • by Bryan
That solved the error pretty quickly, thank you. So, I was able to make a great deal of headway after that. Now, I have the next issue to get fixed. I need to return 3 custom tokens name1, name2 & name3. I was hoping to create and assign those on the fly in a repeat with loop, but I have run into an issue. My code is as follows:
Code: Select all
tell application "Finder"
   
   set posixPath to POSIX path of ((item theFile) as text)
   
end tell


try
   set returnKeywords to (do shell script "mdls -name kMDItemKeywords " & quoted form of posixPath) as text
   
   
on error
   
   tell application "System Events"
      activate
      display dialog "Didn't work"
   end tell
   
end try


-- Now dig out the file keywords
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "kMDItemKeywords = (
    \":   "
set E to text item 2 of returnKeywords

set ETextCount to number of text in E

set AppleScript's text item delimiters to (text (ETextCount - 2) thru ETextCount of E)

set F to text item 1 of E

set AppleScript's text item delimiters to space
set numberKeywords to number of text items in F

if numberKeywords < 4 then
   repeat with Counter from 1 to numberKeywords
      make new variable with properties {name:"Name" & Counter as text, value:(text item Counter of F)}
   end repeat
end if

set AppleScript's text item delimiters to tid
return {hazelExportTokens:{Name1:Name1, Name2:Name2, Name3:Name3}}


The offending line is the "make new variable" line towards the bottom in the repeat with loop. (I have included everything so that other users who come along later can see the progression and learn from my mistakes.) While various sites say I can use "make new variable with properties" command, Applescript is treating the word variable as an undeclared variable, and not part of a command line, and throws an error. Any clue on how I do this?

Bryan
Bryan
 
Posts: 25
Joined: Wed Jan 11, 2012 4:34 pm
Location: Maryland

Re: Automatic Filing of PDFs by Keywords Mon Jan 07, 2013 7:52 pm • by a_freyer
First, you have multiple variables named Name1 & Name2 - there is no way that Applescript/Hazel can tell what you mean by Name1:Name1. If your keyword is "Awesome" then you're going to be outputting "Awesome:Awesome" which means you would have had to enter "Awesome" in your Hazel keyword list, at which point you might as well have hardcoded it in the first place.

Second, I think that you are going way overboard with the variable creation block. If you know that you are going to return 3 different variables, then I would extract them intentionally:

Code: Select all
   set name1 to (do shell script "mdls -name kMDItemKeywords " & quoted form of posixPath & "| grep  \\\" | sed 's/\"//g' | awk -F ' ' '{print $1}'") as text

   set name2 to (do shell script "mdls -name kMDItemKeywords " & quoted form of posixPath & "| grep  \\\" | sed 's/\"//g' | awk -F ' ' '{print $2}'") as text

   set name3 to (do shell script "mdls -name kMDItemKeywords " & quoted form of posixPath & "| grep  \\\" | sed 's/\"//g' | awk -F ' ' '{print $3}'") as text



Although you may need to experiment a bit (since I don't have your keyword files to test) this should output the first second and third word (space delimited) stored in your kMDItemKeywords entries. I assume from your text delimiter blocks that your basic mdls output for kMDItemKeywords looks like this:
'
mdls -name kMDItemKeywords "$1" wrote:kMDItemKeywords = (
"keyword1 keyword2 keyword3"
)


If that is the case, then the above should work great for you. Here is an explanation of what each pipe does:

mdls -name kMDItemKeywords " & quoted form of posixPath & " - we know what this does already...
grep \\\" - trim the output of the previous command to ONLY the lines that contain a quotation. We have to backslash the quote three times. Twice for applescript and once for grep.
sed 's/\"//g' - using sed to do text replace (e.g. 's/{replace this}/{with this}/g') we delete the quote at the beginning and end of the line. We only need one backslash here because sed does not treat the quote as a special character.
awk -F ' ' '{print $1}'" - lastly we ask awk to set its delimiter to space, then print the first returned match. Note in the second and third the only difference is $1 $2 and $3. If you want a fourth, just $4.

Each of the $1-$whatevernumber will return blank if they do not match anything.

So, in sum:

Code: Select all
tell application "Finder" to  set posixPath to POSIX path of ((item theFile) as text)
try
   set name1 to (do shell script "mdls -name kMDItemKeywords " & quoted form of posixPath & "| grep  \\\" | sed 's/\"//g' | awk -F ' ' '{print $1}'") as text

   set name2 to (do shell script "mdls -name kMDItemKeywords " & quoted form of posixPath & "| grep  \\\" | sed 's/\"//g' | awk -F ' ' '{print $2}'") as text

   set name3 to (do shell script "mdls -name kMDItemKeywords " & quoted form of posixPath & "| grep  \\\" | sed 's/\"//g' | awk -F ' ' '{print $3}'") as text
on error
   tell application "System Events"
      activate
      display dialog "Didn't work"
   end tell
end try
return {hazelExportTokens:{"FirstKeyword":name1,"SecondKeyword":name2, "ThirdKeyword":name3}}

a_freyer
 
Posts: 631
Joined: Tue Sep 30, 2008 9:21 am
Location: Colorado

Re: Automatic Filing of PDFs by Keywords Mon Jan 07, 2013 10:13 pm • by Bryan
Thanks for the advice. Part of my problem is I am trying to limit it to no more than 3, but it could reasonably be 2. Also, there is a possibility that a date may get thrown in there eventually. I am using a ScanSnap and I can highlight items on the scanned item and it will put whatever I highlight into keywords. This may be a client's first and last names, or first, last and middle initial. I would like the script to handle that elegantly, so I am trying to avoid hardwired blocks. Right now, I am not going to be handling more than three names, but an artifact may creep in and be an additional keyword.

The last line was a quick, and unfinished attempt to do the outputting of the custom tokens. My script hadn't reached that point yet so I wasn't worried about that. (Fix that error when I come to it). Any further advice? I would love to take what you have done, put it into a loop to iterate through the possibilities and deal with varying numbers of keywords if I can. Thanks.
Bryan
 
Posts: 25
Joined: Wed Jan 11, 2012 4:34 pm
Location: Maryland

Re: Automatic Filing of PDFs by Keywords Mon Jan 07, 2013 10:33 pm • by a_freyer
Hazel requests that you fix the names and number of output tokens. There is no reason to sweat how many tokens to limit if you're hardwired by hazel anyhow.
a_freyer
 
Posts: 631
Joined: Tue Sep 30, 2008 9:21 am
Location: Colorado

Re: Automatic Filing of PDFs by Keywords Thu Jan 10, 2013 4:25 pm • by Bryan
I do greatly appreciate the help. I ended up sticking with the Applescript, even though sed would be more efficient simply because sed is too obtuse for me to parse the separators. Essentially your code had an extra couple of characters in it, and I didn't know how to change the search parameters.

The code below works so I wanted to share it for others:
Code: Select all
tell application "Finder"
   
   set posixPath to POSIX path of ((item theFile) as text)
   
end tell


try
   set returnKeywords to (do shell script "mdls -name kMDItemKeywords " & quoted form of posixPath) as text
   
   
on error
   
   tell application "System Events"
      activate
      display dialog "Didn't work"
   end tell
   
end try


-- Now dig out the file keywords
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "kMDItemKeywords = (
    \":   "
set E to text item 2 of returnKeywords

set ETextCount to number of text in E

set AppleScript's text item delimiters to (text (ETextCount - 2) thru ETextCount of E)

set F to text item 1 of E

set AppleScript's text item delimiters to space
set numberKeywords to number of text items in F

if numberKeywords < 4 then
   repeat with Counter from 1 to numberKeywords
      make new variable with properties {name:"Name" & Counter as text, value:(text item Counter of F)}
   end repeat
end if

set AppleScript's text item delimiters to tid
return {hazelExportTokens:{Name1:Name1, Name2:Name2, Name3:Name3}}


I did take your suggestion that since Hazel has to be hardwired to just deal with it. Because of the fact that I don't know how many keywords I would have (though probably no more than three for the time being) I had to make sure each of the variable supplying the custom tokens with their values were initiated.

I am going to leave this thread the way it is. a_freyer, thank you for all the assistance. I really appreciate it!

Bryan
Bryan
 
Posts: 25
Joined: Wed Jan 11, 2012 4:34 pm
Location: Maryland

Re: Automatic Filing of PDFs by Keywords Thu Jan 10, 2013 4:30 pm • by a_freyer
No problem, happy organizing!
a_freyer
 
Posts: 631
Joined: Tue Sep 30, 2008 9:21 am
Location: Colorado


Return to Support