views:

1104

answers:

3

I have written a ruby script which opens up dlink admin page in firefox and does a ADSL connection or disconnection.

I could run this script in the terminal without any problem. But if I put it as cron job, it doesn't fire up firefox.

This is the entry I have in crontab

# connect to dataone
55 17 * * * ruby /home/raguanu/Dropbox/nettie.rb >> /tmp/cron_test

I see the following entries in /tmp/cron_test. So it looks like the script indeed ran.

PROFILE: 
i486-linux
/usr/bin/firefox -jssh

But I couldn't figure out why I didn't see firefox opening up, for this automation to work. Here is /home/raguanu/Dropbox/nettie.rb

#!/usr/bin/ruby -w

require 'rubygems'
require 'firewatir'
require 'optiflag'

module Options extend OptiFlagSet
    character_flag :d do
     long_form 'disconnect'
     description 'Mention this flag if you want to disconnect dataone'
    end

    flag :l do 
     optional 
     long_form 'admin_link'
     default 'http://192.168.1.1'
     description 'Dlink web administration link. Defaults to http://192.168.1.1'
    end

    flag :u do
     optional 
     long_form 'user'
     default 'admin'
     description 'Dlink administrator user name. Defaults to "admin"'
    end

    flag :p do 
     optional 
     long_form 'password'
     default 'admin'
     description 'Dlink administrator password. Defaults to "admin"'
    end

    flag :c do 
     optional 
     long_form 'connection_name'
     default 'bsnl'
     description 'Dataone connection name. Defaults to "bsnl"'
    end

    extended_help_flag :h do
     long_form 'help'
    end

    and_process!
end

class DlinkAdmin
    include FireWatir 

    def initialize(admin_link = "http://192.168.1.1", user = 'admin', pwd = 'admin')
     @admin_link, @user, @pwd = admin_link, user, pwd
    end

    def connect( connection_name = 'bsnl' ) 
     goto_connection_page connection_name

     # disconnect prior to connection
     @browser.button(:value, 'Disconnect').click

     # connect
     @browser.button(:value, 'Connect').click

     # done!
     @browser.close
    end

    def disconnect( connection_name = 'bsnl' )
     goto_connection_page connection_name

     # disconnect
     @browser.button(:value, 'Disconnect').click

     # done!
     @browser.close  
    end

    private
    def goto_connection_page( connection_name = 'bsnl')
     @browser ||= Firefox.new
     @browser.goto(@admin_link)

     # login
     @browser.text_field(:name, 'uiViewUserName').set(@user)
     @browser.text_field(:name, 'uiViewPassword').set(@pwd)
     @browser.button(:value,'Log In').click

     # setup > dataone
     @browser.image(:alt, 'Setup').click
     @browser.link(:text, connection_name).click
    end
end

admin = DlinkAdmin.new(Options.flags.l, Options.flags.u, Options.flags.p)

unless Options.flags.d?
    admin.connect( Options.flags.c )
else
    admin.disconnect( Options.flags.c )
end

Any help is appreciated.

A: 

the crontab entry is wrong

it is like

#min  hour  day  month  dow  user                command
55    17    *    *      *    ur_user_is_missing  ruby /home/raguanu/Dropbox/nettie.rb >> /tmp/cron_test
mana
The user field is only required for the system crontab, not for each user's individual crontab.
Douglas Leeder
@mana: Douglas is right. I could run cron jobs okay without username. Also as you see in the question, I could get the cron job running. Just that I couldn't see firefox in the display.
ragu.pattabi
+1  A: 

Programs run from cron don't have your interactive environment. Therefore they don't have and DISPLAY variable, and so you can't run any X (graphical) programs, e.g. Firefox.

I would suggest doing the HTTP connections yourself, in ruby, rather than trying to automate Firefox.

Douglas Leeder
+2  A: 

You need to have a DISPLAY environment pointing at a valid X-server. This could either involve setting it to the value ":0.0" (without quotes), such that it refers to your local standard DISPLAY.

There's a few things to keep in mind though: You could run an X virtual frame buffer (xvfb), so that Firefox simply uses that as it's display. This would mean that Firefox would be able to do all its graphical operations, but that it would be independent of your standard graphical environment. You'll have to set the DISPLAY variable appropriately so that it points to the xvfb instance. For instance, if you invoke xvfb as follows:

Xvfb :1 -screen 0 1600x1200x32

Then you'll be able to use this by setting the DISPLAY variable to :1

You're starting a full-blown firefox instance to simply connect or disconnect your modem. You would most likely be able to use "curl" to send the appropriate HTTP requests to the server, such that it performs a connect or disconnect for you. One way to trivially see what you should recreate would be to install a Firefox plugin such as LiveHTTPHeaders and note down the most important HTTP requests as you perform the actions manually.

There's even a ruby binding for curl: libcurl for Ruby. The resulting script should be much smaller than your current script.

Roshan
Also note that just setting the DISPLAY variable may not be enough to join an existing display, as there can be configuration files, and authority files that have to be located via environment variables. e.g. XAUTHORITY
Douglas Leeder
@Roshan and @Douglas: DISPLAY = :0.0 in crontab solved the problem. I do agree that I could have done it in lighter approach. I was experimenting with FireWatir, so this seemed to be useful for me at the moment. I will try out lighter approach when I get a chance. Thanks again.
ragu.pattabi