EagleFiler - Hazel Script Integration... Import into EF and let EF check duplicates

I use Hazel to copy files into the EagleFiler (EF) folder structure based on rules that scan for keywords and then target corresponding folders. For instance the Hazel looks at file that contains my checking account number, a rule fires that renames the files, changes the dat created to a date prepended in the filename, and then copies the file into EagleFiler, and then tells EF to scan for new files.

But I’ve found that duplicate files can get in. The Hazel rules are set to “Throw away if duplicate”. But this doesn’t seem to work.

EF has a great system to prevent duplicates, but it only runs when a file is imported into EF directly. IE via Option Function F1 in my case.

So I’m thinking of modifying my Hazel import rules to run an AppleScript that taps the EF scripting API. My thinking is, instead of telling Hazel to copy the file to the right folder based on the keyword matching rules, I could tell Hazel to run an AppleScript to tell EagleFiler to import the file. And thus hopefully leverage the databased checksum duplication checking inherent in EagleFiler.

EagleFiler scripts show many import scripts as examples. And Hazel support injecting Applescripts in the import workflow, with “inputAttributes” that potentially could be used to read imported attributes to automate the destination folder designation. Or I could edit the script to define the destination folder for each matching keyword rule…

Can anyone with mad apple scripting skills suggest a script that can be embedded into Hazel rules to do these things?

All of this is only worthwhile if EagleFiler will be given a chance to scan for duplicates and reject the import if a duplicate is found.

Thanks if you can help with both EagleFiler and Hazel integration.

-DaveB

Right, EagleFiler’s duplicate checking works for all cases except if you manually save a file into its folder.

That sounds like a good idea. Importing via AppleScript honors the setting for duplicates (unless you override it with the allowing duplicates argument).

I don’t have Hazel installed right now, but looking at the documentation, I think it would work to have a rule action script that looks something like this:

on hazelProcessFile(_file, _inputAttributes)
    -- Get the folder name that you set in Hazel
    set _folderName to item 1 of _inputAttributes
    
    -- Change these to the library that you want to use
    set _libraryName to "EagleFilerTest.eflibrary"
    set _libraryFolder to "/Users/mjt/Documents/EagleFilerTest/"
    
    tell application "EagleFiler"
        set _libraryPath to _libraryFolder & _libraryName
        open POSIX file _libraryPath
        tell library document _libraryName
            set _folderRecord to library record _folderName of root folder
            set {_record} to import files {_file} container _folderRecord
        end tell
    end tell
end hazelProcessFile

I’ve finally had a chance to experiment with import applescripts into EF from Hazel. To recap, we’re doing this to leverage duplicate checking muscles in EF. But my import script is erring on the POSIX path to EagleFiler. And I’m a newbie to POSIX paths and AppleScript.

(note I’ve short circuited the combined _libraryName and _LibraryFolder in this example as part of my testing.). I’m using an external AppleScript during testing. When it works I plan to embed the script into each Hazel rule, and hard code the destination folder in EagleFiler.)

The error is that my path to the EF library seems to be invalid.

"EagleFiler got an error: Can't get POSIX file \"/Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary\".";

I got the path by dragging the EagleFiler file into Terminal. Then I created a nifty “Quick Action” to Copy paths to the clipboard just for these types of issues. But the path doesn’t seem to work. I’m using iCloud and wonder if that’s an issue.

Here is my script :

on hazelProcessFile(_file, _inputAttributes)
    -- Get the folder name that you set in Hazel
    -- "Documents/Employment-Dave"
    -- set _folderName to item 1 of _inputAttributes
    set _folderName to "Documents/Employment-Dave"
    -- Change these to the library that you want to use
    set _libraryName to "Paperless-Library_local.eflibrary"
    set _libraryFolder to "/Users/dbartholomew/Documents/Paperless-Library_local"
    -- /Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary
    tell application "EagleFiler"
        set _librarypath to "/Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary"
        -- set _librarypath to _libraryFolder & _libraryName
        open POSIX file _librarypath
        tell library document _libraryName
            set _folderRecord to library record _folderName of root folder
            set {_record} to import files {_file} container _folderRecord
        end tell
    end tell
end hazelProcessFile

And here are the resulting log files:

2019-12-06 14:22:45.736 hazelworker[49504] Running worker (v4.4.2) for folder with identifier: 16777223-3143399.
2019-12-06 14:22:45.737 hazelworker[49504] ###main load address: 0x107b98000
2019-12-06 14:22:45.737 hazelworker[49504] ###Noodle load address: 0x107cb1000
2019-12-06 14:22:45.737 hazelworker[49504] ###CK load address: 0x107c77000
2019-12-06 14:22:45.763 hazelworker[49504] Processing folder Automate-Hazel (forced)
2019-12-06 14:22:47.867 hazelworker[49504] 2019-12-01--Rumplestiltskin.pdf: Rule Test EF Import Script matched.
2019-12-06 14:22:51.920 hazelworker[49504] [Error] AppleScript failed: Error executing AppleScript on file /Users/dbartholomew/Desktop/Scan Target/Automate-Hazel/2019-12-01--Rumplestiltskin.pdf.
2019-12-06 14:22:51.920 hazelworker[49504] OSAScript error: {
    NSLocalizedDescription = "EagleFiler got an error: Can\U2019t get POSIX file \"/Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary\".";
    NSLocalizedFailureReason = "Can\U2019t get POSIX file \"/Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary\".";
    OSAScriptErrorAppAddressKey = "<NSAppleEventDescriptor: [0x0,41f41f \"EagleFiler\"]>";
    OSAScriptErrorAppNameKey = EagleFiler;
    OSAScriptErrorBriefMessageKey = "Can\U2019t get POSIX file \"/Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary\".";
    OSAScriptErrorMessageKey = "EagleFiler got an error: Can\U2019t get POSIX file \"/Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary\".";
    OSAScriptErrorNumberKey = "-1728";
    OSAScriptErrorOffendingObjectKey = "<NSAppleEventDescriptor: \"file:///Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary\">";
    OSAScriptErrorRangeKey = "NSRange: {0, 0}";
}
2019-12-06 14:22:51.921 hazelworker[49504] Received abort event.
2019-12-06 14:22:51.922 hazelworker[49504] Done processing folder Automate-Hazel
2019-12-06 14:23:08.255 HazelHelper[698] Attempted to run worker on undeployed folder: /Users/dbartholomew/Desktop/Scan Target/Automate-Hazel.

Any suggestions? I’m almost there if I can just get the path issue resolved.

Thanks,

-Dave

I reformatted your script. I think it will work better if you use Edit ‣ Paste and Match Style and then format it with:

```applescript
Your script here
```

Otherwise the forum will insert ** markup for the bold keywords, which doesn’t work inside Markdown code blocks.

I think the error -1728 is a weird AppleScript issue where you have to create the POSIX file outside of the tell block so that it sends this command to the system rather than to EagleFiler.

Secondly, the:

set _folderName to "Documents/Employment-Dave"

wont’t work because the name as to be a single level. If you want two levels you would need another variable.

Something like this should work better:

on hazelProcessFile(_file, _inputAttributes)
    -- Get the folder name that you set in Hazel
    -- "Documents/Employment-Dave"
    -- set _folderName to item 1 of _inputAttributes
    set _parentFolderName to "Documents"
    set _folderName to "Employment-Dave"
    
    -- Change these to the library that you want to use
    set _libraryName to "Paperless-Library_local.eflibrary"
    set _libraryFolder to "/Users/dbartholomew/Documents/Paperless-Library_local"
    -- /Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary
    set _libraryPath to "/Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary"
    -- set _libraryPath to _libraryFolder & _libraryName
    set _libraryFile to POSIX file _libraryPath

    tell application "EagleFiler"
        open _libraryFile
        tell library document _libraryName
            set _folderRecord to library record _folderName of library record _parentFolderName of root folder
            set {_record} to import files {_file} container _folderRecord
        end tell
    end tell
end hazelProcessFile

Thank you, thank you… It works!

Then when I run it a second time on a duplicate file a notification pops up say its a duplicate, just as I want.

Here’s the log file results from the original import and the failed duplicate import.
This is golden, thank you very much!

2019-12-06 19:54:29.405 HazelHelper[698] Attempted to run worker on undeployed folder: /Users/dbartholomew/Desktop/Scan Target/Automate-Hazel.
2019-12-06 19:54:58.515 hazelworker[51318] Running worker (v4.4.2) for folder with identifier: 16777223-3143399.
2019-12-06 19:54:58.516 hazelworker[51318] ###main load address: 0x108f68000
2019-12-06 19:54:58.516 hazelworker[51318] ###Noodle load address: 0x109088000
2019-12-06 19:54:58.516 hazelworker[51318] ###CK load address: 0x10904b000
2019-12-06 19:54:58.542 hazelworker[51318] Processing folder Automate-Hazel (forced)
2019-12-06 19:55:00.644 hazelworker[51318] 2019-12-01--Rumplestiltskin.pdf: Rule Test EF Import Script matched.
2019-12-06 19:55:06.377 hazelworker[51318] [File Event] File moved: 2019-12-01--Rumplestiltskin.pdf moved from folder /Users/dbartholomew/Desktop/Scan Target/Automate-Hazel to folder /Users/dbartholomew/.Trash.
2019-12-06 19:55:06.379 hazelworker[51318] Received abort event.
2019-12-06 19:55:08.414 hazelworker[51318] Received abort event.
2019-12-06 19:55:08.414 hazelworker[51318] Done processing folder Automate-Hazel
2019-12-06 19:55:22.761 HazelHelper[698] Attempted to run worker on undeployed folder: /Users/dbartholomew/Desktop/Scan Target/Automate-Hazel.
2019-12-06 19:56:15.410 hazelworker[51344] Running worker (v4.4.2) for folder with identifier: 16777223-3143399.
2019-12-06 19:56:15.411 hazelworker[51344] ###main load address: 0x1069f9000
2019-12-06 19:56:15.411 hazelworker[51344] ###Noodle load address: 0x106b12000
2019-12-06 19:56:15.411 hazelworker[51344] ###CK load address: 0x106ad9000
2019-12-06 19:56:15.465 hazelworker[51344] Processing folder Automate-Hazel (forced)
2019-12-06 19:56:17.563 hazelworker[51344] 2019-12-01--Rumplestiltskin.pdf: Rule Test EF Import Script matched.
2019-12-06 19:56:23.919 hazelworker[51344] [Error] AppleScript failed: Error executing AppleScript on file /Users/dbartholomew/Desktop/Scan Target/Automate-Hazel/2019-12-01--Rumplestiltskin.pdf.
2019-12-06 19:56:23.919 hazelworker[51344] OSAScript error: {
    NSLocalizedDescription = "Can\U2019t get item 1 of {}.";
    NSLocalizedFailureReason = "Can\U2019t get item 1 of {}.";
    OSAScriptErrorAppAddressKey = "<NSAppleEventDescriptor: null()>";
    OSAScriptErrorBriefMessageKey = "Can\U2019t get item 1 of {}.";
    OSAScriptErrorMessageKey = "Can\U2019t get item 1 of {}.";
    OSAScriptErrorNumberKey = "-1728";
    OSAScriptErrorOffendingObjectKey = "<NSAppleEventDescriptor: 'obj '{ 'form':'indx', 'want':'cobj', 'seld':1, 'from':[  ] }>";
    OSAScriptErrorRangeKey = "NSRange: {0, 0}";
}
2019-12-06 19:56:23.920 hazelworker[51344] Received abort event.
2019-12-06 19:56:25.936 hazelworker[51344] Received abort event.
2019-12-06 19:56:25.937 hazelworker[51344] Done processing folder Automate-Hazel

I’ve moved the AppleScript inside Hazel as an embedded script unique to each of my Hazel rules. I must hard code the destination folders in the source code of the script, and I added a new step to each rule to Move the source file to the Trash. The original Hazel rules used a “Move” command that both copied the file to EF and deleted the original…

I’m confused by your instruction about how to format code in a forum post.

But I wanted to share the final solution in case other users want to integrate Hazel with EagleFiler to leverage the de-duplication feature that EF provides.

Here’s the the embedded AppleScript. The only change from the external AppleScript was to replace “_file” with “theFile”.

-- set _folderName to item 1 of _inputAttributes
-- Adjust _parentFolderName and _folderName to match the destination folders in EagleFiler
-- -----------------------------------

set _parentFolderName to "Documents"
set _folderName to "MyDestinationSubFolder"
-- Change these to the library that you want to use
set _libraryName to "Paperless-Library_local.eflibrary"
set _libraryFolder to "/Users/dbartholomew/Documents/Paperless-Library_local"
set _libraryPath to "/Users/dbartholomew/Documents/Paperless-Library_local/Paperless-Library_local.eflibrary"
-- set _libraryPath to _libraryFolder & _libraryName
set _libraryFile to POSIX file _libraryPath
tell application "EagleFiler"
	open _libraryFile
	tell library document _libraryName
		set _folderRecord to library record _folderName of library record _parentFolderName of root folder
		set {_record} to import files {theFile} container _folderRecord
	end tell
end tell

The second AppleScript in my Hazel Import workflow tells EF to scan for new files. I suppose I could merge the two scripts now that I’m using an AppleScript to import the files. This allows me to see the newly imported files in the Recently Added folder in EagleFiler as soon as it’s been imported.
Here’s that code:

tell application "EagleFiler"
scan for new files document "Paperless-Library_local.eflibrary"
-- close document "Paperless-Library_local.eflibrary"
end tell