20140418

Applescript notes

My pay stubs come in via ADP's portal, which is frightfully annoying to use on a Mac.  Basically, it doesn't work for crap in Firefox, and you can't use 1Password (or keychain, come to that) to enter your credentials.

But it's been bugging me, so I've been working to automate it.  I've actually got it mostly working (I can go to the newest pay stub, and open that in its own window (it normally opens via an embed), but haven't yet gotten it to save), and just wanted to mention a few things I did to it there.

I should mention, too, that this is my first Applescript.  In fact, I was going to try to do the entire process via Automator, but that proved impossible (well, I couldn't manage to come close, anyway), so I fell back to using Applescript.

The script opens Safari, goes to the portal URL, and enters credentials via
tell application "System Events"
  keystroke "userid"
  keystroke tab
  keystroke "pw" -- yes, this is not terribly secure; using the keychain would be better
  keystroke return
  delay 4 -- needed before next step
end tell

Yes, this is horrible syntax (this is what happens when you have a programming language written for non-programmers), but it is pretty powerful.

Then, it gets really interesting, as I start embedding javascript:

tell application "Safari"
  tell current tab of window 1
    do JavaScript "document.getElementById (\"menuHit.node2\").onmouseover();"
    do JavaScript "for (var i = 0; i < document.links.length; i++) {
        if (document.links[i].textContent == 'Pay Statements') {
          document.links[i].onclick();
          break;
        }
    }"
    delay 4

    -- you'd think I'd be used to it from java, but I hate these
    -- doubled backslashes
    set linkScript to do JavaScript "function getLink() {
      var pat = /\\d{2}\\/\\d{2}\\/\\d{4}/;
      for (var i = 0; i < document.links.length; i++) {
        if (document.links[i].textContent.search (pat) >= 0) {
          return i;
        }
      }
    }

    getLink();"
    set docName to do JavaScript "document.links[" & linkScript & "].textContent.replace (/(\\d{2})\\/(\\d{2})\\/(\\d{4})/, '$3$1$2');"



The interesting parts to, there, are that
  1. You can do javascript
  2. You can get values back from javascript (note that the whole purpose of that function, getLink(), is to enable returning a value via return.  Supposedly (I didn't try it), you can't just return from the javascript.  I thought for loops had a return value, implicitly, but that didn't seem to be the case from the slight experimentation I did.
  3. You can embed applescript variables into your javascript calls
  4. You can use javascript to get regular expression processing in your applescript
Anyway, just thought I'd post about this.  It's kind of interesting to me.  Dunno if I'll keep doing things in AppleScript; hopefully I can find better ways to do things.

Update: I was finally able to save the file by forcing safari to just save it to disk by doing
defaults write com.apple.Safari WebKitOmitPDFSupport -bool YES
defaults write com.apple.Safari AutoOpenSafeDownloads -bool NO
(The second of those was optional, but kept Preview from opening.)

Then I just used a shell script (after saving the file name from the embed src) to move the file from Downloads to my target directory.

Oh, getting the filename separated out was a little interesting:
set fileName to do shell script "basename `dirname " & docUrl & "`"

Update 2: Just noticed, with some amusement, that I had about ten tabs open for looking up various applescript oddities.

No comments:

Post a Comment