I was increasingly getting annoyed by having to handle various filing tasks and was looking for a way to automate it. The two most regular and straight-forward ones to handle were my credit-card statements as they came monthly and had a bunch of steps (listed below) that needed to be followed for each one:
- Download the statement PDF from email
- Decrypt it using the appropriate password
- Save the decrypted version so that I don't have to fuss with that password in the future
- Rename the file to reflect statement date
- Connect to my NAS and locate/create the appropriate folder for that statement
- Copy the statement to NAS directory
- Delete the files from my local machine
Since this was a long process it regularly got pushed back and when once automated had a high-probability of both reducing my cognitive/time burden as well as chances of human-errors in the process.
And thus emerged valet. Before writing the program I had managed to do a lot of the above tasks using individual commands rather than using any graphical interface, this way I was inching myself toward automating it.
When I first started storing decrypted statements I used to use Mac's Preview utility to open the encrypted PDF file and then print from it to another PDF file thus removing the password encryption from the new PDF. I eventually moved to using the nifty little program called qpdf
to remove this encryption.
qpdf --decrypt --password="your password here" /path/to/encrypted.pdf /path/to/store/decrypted.pdf
To mount my NAS to my local machine I needed to open it in Finder which would in-turn mount it and thus I would be able to transfer files to/from it. I learnt of an applescript command mount volume
which can be used to mount SMB shares which can then be used for file-transfer. Eventually in valet
I had to use a different (non-applescript) command mount_smbfs
to achieve the same thing.
# The applescript way
on run argv
try
mount volume "smb://varun@delphinus/Legal Documents"
on error
return false
end try
return true
end run
# The normal shell way
# Ensure the directory `/Volumes/Legal Documents` exists and is empty
mount_smbfs "//varun@delphinus/Legal%20Documents" "/Volumes/Legal Documents"
I had atleast two things which I had not foreseen that I would end up learning:
- Accessing password(s) from Mac's Keychain Access programmatically. I ended up learning both how to do it from terminal and from within a rust program.
- Using a custom build-script to access variables in my rust program at run-time whose values were passed as environment variables at compile-time.
I would write about both of those in coming days.
Some other things which I sort of expected to learn and actually ended up learning were:
- How to run shell commands from within a rust program
- Encoding both parts for a URL and the complete URL to ensure no non-permitted character messes up the mounting URL for SMB share
- Finding files in rust from a directory based on the filename matching a regex
- Date-time parsing/handling in rust
The current version of valet only handles a couple of my credit card statements but already some other things are coming to my mind which I can slowly take on and move to automate with valet.
- The bills that I create for my consulting clients
- Some of the bills that I receive (for example from my ISP)