Cannot call a ruby script that calls back into DEVONagent?

I wrote a script to control DA using appscript, which allows you to drive Applescriptable apps using Ruby. I have a one-line applescript that calls out to my ruby script. I’ve run my ruby script from the command line, and using Applescript Editor I’ve run the one-line script that calls it, and those work fine. When I add it to the scripts folder and call it, DEVONagent just hangs until (presumably) the script times out. I’ve put in some logging statements and it appears to hang right when I ask the DA app object for one of its windows. My guess is that since DA is calling out to the script, it’s blocking until it gets a result. The script however is trying to make a call back into DA to get data from it, which hangs because DA is waiting for the script to end.

Does that make sense? Am I not allowed to do what I’m trying to do?

That’s hard to tell without having a look at the script. Could you please post it here? Or send it to cgrunenberg - at - devon-technologies.com? Thanks in advance!

Sure. It’s a set of three scripts. The Ruby script is the workhorse. It looks at a portal.acm.org result, then logs in, fetches the PDF, and imports it to DEVONthink. For it to work you need a portal.acm.org account, and it loads the login info from ~/.acm_credentials which should contain the credentials in the format username:password

require 'rubygems'
require 'mechanize'
require 'fileutils'
require 'appscript'

ACM_USERNAME, ACM_PASSWORD = File.read(File.expand_path("~/.acm_credentials")).strip.split(":")

def do_log(text)
  puts text
  `echo "#{text}" >> /tmp/acm_downloader.log`
end


def fetch_paper(unclean_url, &block)
  return unless unclean_url =~ /(http:\/\/portal\.acm\.org\/citation\.cfm\?id=\d+\.\d+)/
  url = $1
  attributes = {:URL => url}
  a = Mechanize.new

  puts(url + '&preflayout=flat')
  a.get(url + '&preflayout=flat') do |page|
    article_title = page.title
    login_page = a.click(page.link_with :text => /Buy this Article|SIGN IN to get this Article/)

    article_page = login_page.form_with(:action => /(purchase|signin)\.cfm/) do |f|
      f.uname = ACM_USERNAME
      f.pword = ACM_PASSWORD
    end.click_button

#    puts article_page.send(:html_body)
    full_article = a.click(article_page.link_with :text => 'Pdf')
    download_dir = File.expand_path("~/Downloads/acm")
    FileUtils.mkdir download_dir unless File.directory?(download_dir)
    download_file = "#{download_dir}/#{article_title}.pdf"
    if page.send(:html_body) =~ /(\d{4}) Article/
      attributes[:comment] = "Published: #{$1}"
    end
    full_article.save_as download_file
    do_log "downloaded #{url}"
    block.call(download_file, attributes)
  end
  
end

include Appscript

class DevonAgent
  def initialize(app)
    @app = app
  end

  def current_items
    return [current_browser_item] if current_browser && current_browser.index.get == 1
    return current_selected_results if current_results_window && current_results_window.index.get == 1 && current_selected_results.size > 0
    do_log "should never get here"
    raise "no selected items"
  end

  private
  def current_browser
    @app.browsers.get.first
  end

  def current_browser_item
    current_browser.tabs.get.first
  end

  def current_results_window
    @app.search_windows.get.first
  end

  def current_selected_results
    current_results_window.selection.get
  end

  def method_missing(m, *args, &block)
    @app.send m, *args, &block
  end
end

dagent = DevonAgent.new app('DEVONagent')
dthink = app('DEVONthink Pro')

dagent.current_items.each do |da_result|
  do_log da_result.inspect
  fetch_paper(da_result.URL.get) do |saved_file_path, attributes|
    dt_record = dthink.import(saved_file_path, :name => (da_result.title.get rescue da_result.name.get))
    attributes.each do |key, val|
      dt_record.send(key).set(val)
    end
  end
end

I have a bash script which sets up the environment, since applescript runs scripts with a barebones env setup. It may not be necessary if you’re not using RVM:

#!/bin/sh

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
`cat .rvmrc`
ruby acm_downloader.rb

And finally here’s the applescript which simply calls out to my ruby script:


tell application "DEVONagent" to do shell script "cd ~/code/devonagent_proxy && ./acm_downloader.sh"

The ruby script works fine when run from the command line. And I can call my import script using launchbar and it works fine too. It’s just calling it from within DA that it hangs.

Are you able to execute the last script successfully via Apple’s Script Editor or via the script menu extra?

Yes it runs when I execute it from the applescript editor, as well as from the system script menu. It’s only when I move it to DA’s scripts folder and run it from DA’s script menu that it freezes.

Then it’s indeed a locking issue (script A waiting for B waiting for A). I’d suggest to use the script menu extra instead of DEVONagent’s own script menu.