SitePoint Sponsor

User Tag List

Results 1 to 17 of 17
  1. #1
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Howto Go About Possible Ruby Application

    hi all,

    i'm delving into RoR a bit. i'm learning, but still have a ways to go.

    anyway, my friend approached me about coding an app with the following criteria:

    1. check modem's external ip at regular intervals
    2. send email with new ip address when it changes.

    i suppose this could be done via RoR and using ajax to check this info on a wbe page, but i think we can agree that's hackish.

    can i program something like this as a standalone ruby app and make it cross platform.

    it seems like a cool project b/c, in theory, it is trivial and i'd get to learn how to work with ruby on a standalone app.

    if this is possible, can anyone lead me to some resources explaining how to get it done?

    tia...

  2. #2
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skeeterbug
    hi all,

    i'm delving into RoR a bit. i'm learning, but still have a ways to go.

    anyway, my friend approached me about coding an app with the following criteria:

    1. check modem's external ip at regular intervals
    2. send email with new ip address when it changes.

    i suppose this could be done via RoR and using ajax to check this info on a wbe page, but i think we can agree that's hackish.

    can i program something like this as a standalone ruby app and make it cross platform.

    it seems like a cool project b/c, in theory, it is trivial and i'd get to learn how to work with ruby on a standalone app.

    if this is possible, can anyone lead me to some resources explaining how to get it done?

    tia...
    I've written almost an identical app to keep my server synced with a dynamic DNS service. I did most of the work using the standard library's HTTP classes. I made an HTTP connection outbound to a site that returned my external IP (this was important because thanks to NAT my machines IP is not truly external). I then took that result, parsed it into an IP address, and then submitted another request to the dyndns service telling it to update my record.

    The entire script, including comments, command line help, and whitespace is 60 lines. I'm sure with what i've learned since I wrote it I could cut that way down, but regardless its a pretty simple, but good learning project.

    [edit]I spent the last 5 minutes making some minor style tweaks, and a little general cleaning. I dropped a good 5 or 6 lines without hurting readability. In fact I improved the performance a bit

  3. #3
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sgarissta
    I've written almost an identical app to keep my server synced with a dynamic DNS service. I did most of the work using the standard library's HTTP classes. I made an HTTP connection outbound to a site that returned my external IP (this was important because thanks to NAT my machines IP is not truly external). I then took that result, parsed it into an IP address, and then submitted another request to the dyndns service telling it to update my record.

    The entire script, including comments, command line help, and whitespace is 60 lines. I'm sure with what i've learned since I wrote it I could cut that way down, but regardless its a pretty simple, but good learning project.
    Sqarissta, is there a way to create a self contained ruby executable or does ruby need to be installed on the system? i'll have to look through the http classes to see what they allow me to do.

    i'll try and script it on my home linux box. i suppose i could cron the file, which is something i need to learn, too. when i get it running, i'll have to learn how to schedule a task on windows.

    i guess it is time to learn even more stuff.

  4. #4
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skeeterbug
    Sqarissta, is there a way to create a self contained ruby executable or does ruby need to be installed on the system? i'll have to look through the http classes to see what they allow me to do.
    You can look into RubyScript2Exe, it creates an executable containing your script, its dependant libraries, and the ruby executable itself. When you run it it unpacks this behind the scenes, and executes it. The end result is that you have a single exe that allows you to distribute and run a ruby script.
    i'll try and script it on my home linux box. i suppose i could cron the file, which is something i need to learn, too. when i get it running, i'll have to learn how to schedule a task on windows.

    i guess it is time to learn even more stuff.
    The scriptable equivilent of cron on windows is the 'at' command.

  5. #5
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sgarissta
    You can look into RubyScript2Exe, it creates an executable containing your script, its dependant libraries, and the ruby executable itself. When you run it it unpacks this behind the scenes, and executes it. The end result is that you have a single exe that allows you to distribute and run a ruby script.

    The scriptable equivilent of cron on windows is the 'at' command.
    Sgarissta, thanks for the information. RubyScript2Exe sounds cool.

    i don't think i need to worry about a NAT. i found the following ruby script that is alledged to work:

    Code:
    ruby -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    if this works (i can't test until later), then all i need to do is assign the ip to a variable, check against the prior ip and then email it off if they aren't the same...

  6. #6
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skeeterbug
    Sgarissta, thanks for the information. RubyScript2Exe sounds cool.

    i don't think i need to worry about a NAT. i found the following ruby script that is alledged to work:

    Code:
    ruby -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    if this works (i can't test until later), then all i need to do is assign the ip to a variable, check against the prior ip and then email it off if they aren't the same...
    That code goes around the NAT by doing what my script does, which is go out to a public website that displays your IP address.

  7. #7
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    can someone explain what this does?

    Code:
    ruby -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    ruby #call ruby interpretter
    -ropen-uri -e "URI.parse('http://www.whatismyip.com') #some syntax to get
    # open a uri
    .read =~ #syntax to read a regular expression
    /((\d+\.?){4})/ # a regex of some sort. i'm guessing it matches the format
    # of the ip address
    ; # separates the line of code
    puts $&" # i get the puts, but the $&" looks voodoo to me.

    can i assign the ip address to a variable "current_ip" like so...

    Code:
    ruby current_ip = -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/
    tia...

  8. #8
    SitePoint Addict
    Join Date
    Jan 2006
    Posts
    268
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    if I recall correctly (which is a gamble) $& is a variable that will be holding the results of the regex expression.
    the " closes the " started in "URI.parse....

    the regex says you will have 4 groups of the following: 1 or more digits followed by 0 or 1 periods

    It would be better if it specified a range of digits, rather than accepting an IP like 29292.29239213.123993.1 but I might have read it wrong..

    edit:
    I was right.
    $& holds the String of the last Match whenever you use regex

  9. #9
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i tried this under irb...

    Code:
    ruby -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    it didn't work. i tried it with and without "ruby" at the front.

    the error returned w/o a leading ruby is:

    SyntaxError: compile error
    (irb):9: parse error, unexpected tUMINUS, expecting kDO or '{' or '('
    -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    ^
    from (irb):9

    the error received with a leading "ruby" is:

    SyntaxError: compile error
    (irb):10: parse error, unexpected tUMINUS, expecting kDO or '{' or '('
    ruby -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    ^
    from (irb):10

    any ideas?

    tia...

  10. #10
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skeeterbug
    i tried this under irb...

    Code:
    ruby -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    it didn't work. i tried it with and without "ruby" at the front.

    the error returned w/o a leading ruby is:

    SyntaxError: compile error
    (irb):9: parse error, unexpected tUMINUS, expecting kDO or '{' or '('
    -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    ^
    from (irb):9

    the error received with a leading "ruby" is:

    SyntaxError: compile error
    (irb):10: parse error, unexpected tUMINUS, expecting kDO or '{' or '('
    ruby -ropen-uri -e "URI.parse('http://www.whatismyip.com').read =~ /((\d+\.?){4})/; puts $&"
    ^
    from (irb):10

    any ideas?

    tia...
    Okay, lets start buy non-golfing (breaking this code into multiple lines)
    Code:
    require 'open-uri' # include openuri to allow us to open a website
    data = URI.parse('http://www.whatismyip.com').read # read the data
    ip = data.match/((\d+\.?){4})/)[0] # Do the regex match, and pull the first result

  11. #11
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sgarissta
    Okay, lets start buy non-golfing (breaking this code into multiple lines)
    Code:
    require 'open-uri' # include openuri to allow us to open a website
    data = URI.parse('http://www.whatismyip.com').read # read the data
    ip = data.match/((\d+\.?){4})/)[0] # Do the regex match, and pull the first result
    the first two lines run brilliantly. the first line returns true and the second line returns som html stuff with my ip in it twice.

    when i run the third line, though, crrrrrrack.

    the error code i entered plus the returned error is:

    irb(main):013:0> ip = data.match/((\d+\.?){4})/)[0] # Do the regex match, and pull the first result
    SyntaxError: compile error
    (irb):13: parse error, unexpected $undefined.
    ip = data.match/((\d+\.?){4})/)[0] # Do the regex match, and pull the first result
    ^
    from (irb):13
    irb(main):014:0>

    thanks for the help.

  12. #12
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sgarissta
    Okay, lets start buy non-golfing (breaking this code into multiple lines)
    Code:
    require 'open-uri' # include openuri to allow us to open a website
    data = URI.parse('http://www.whatismyip.com').read # read the data
    ip = data.match/((\d+\.?){4})/)[0] # Do the regex match, and pull the first result
    this doesn't look right to me:

    Code:
    /((\d+\.?){4})/)[0]
    shouldn't there be a "/" after the "[0]"? the "(" and ")" appear out of whack, too.

    i'm going to update the regex to

    Code:
    /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
    and try it again.

  13. #13
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skeeterbug
    this doesn't look right to me:

    Code:
    /((\d+\.?){4})/)[0]
    shouldn't there be a "/" after the "[0]"? the "(" and ")" appear out of whack, too.
    Sorry I made a bit of a typo, change it to
    Code:
    data.match(/(\d+\.?){4})/)[0]
    In Ruby a string deliminated by / / is automatically of type RegExp. So what that line does is say call the match function of the data object, and pass in the regular expression (\d+\.?){4}), and then give me the first element of the MatchData object that is returned ([0]).

  14. #14
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    it choked on the original regex, but i got it to work with the new regex i tried.

    here are the results:

    Code:
    irb(main):003:0> ip = data.match(/(\d+\.?){4})/)[0]
    SyntaxError: compile error
    (irb):3: unmatched ): /(\d+\.?){4})/
            from (irb):3
    irb(main):004:0> ip = data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
    => #<MatchData:0xb7e6bc60>
    irb(main):005:0> puts ip
    xx.xx.xx.xx # changed to protect the innocent
    => nil
    irb(main):006:0>
    i'm curious as to why it outputs "=> nil" after displaying the ip address.

  15. #15
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skeeterbug
    it choked on the original regex, but i got it to work with the new regex i tried.

    here are the results:

    Code:
    irb(main):003:0> ip = data.match(/(\d+\.?){4})/)[0]
    SyntaxError: compile error
    (irb):3: unmatched ): /(\d+\.?){4})/
            from (irb):3
    irb(main):004:0> ip = data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
    => #<MatchData:0xb7e6bc60>
    irb(main):005:0> puts ip
    xx.xx.xx.xx # changed to protect the innocent
    => nil
    irb(main):006:0>
    i'm curious as to why it outputs "=> nil" after displaying the ip address.
    This is because IRB displays the return result of any command as well. So puts ip, outputs the variable ip, and also the return value of puts, which happens to be nil. Try it, go into irb, and just type puts, you'll get => nil. For another fun experiment, repeat the above code, but try it without the puts, at the irb prompt just type ip. It will display the value of ip.

  16. #16
    SitePoint Evangelist
    Join Date
    Apr 2005
    Posts
    485
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sgarissta
    This is because IRB displays the return result of any command as well. So puts ip, outputs the variable ip, and also the return value of puts, which happens to be nil. Try it, go into irb, and just type puts, you'll get => nil. For another fun experiment, repeat the above code, but try it without the puts, at the irb prompt just type ip. It will display the value of ip.
    getting external IP: Check

    now i need to be able to create (in not exist) or open my old_ip.xml file (if exists).

    will...

    File.open("old_ip.xml", "rw")

    ...create old_ip.xml if it doesn't currently exist?

    i'm looking to create an xml file with the following structure:

    <check_ip_app>
    <old_ip>111.222.333.444</old_ip>
    <send_email>send_email_here@your_email.com</send_email>
    <check_minutes>15</check_minutes>
    </check_ip_app>

    will...

    ip_xml = Document.new(File.open("old_ip.xml", "rw"))

    create a file if it doesn't already exist? if not, how can i create a file (i didn't see how in the pickaxe book File reference).

    i'm also looking for a method to allow the user to input their email address and the number of minutes between ip address checks. how does one go about doing this?

    tia...

  17. #17
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skeeterbug
    getting external IP: Check

    now i need to be able to create (in not exist) or open my old_ip.xml file (if exists).

    will...

    File.open("old_ip.xml", "rw")

    ...create old_ip.xml if it doesn't currently exist?

    i'm looking to create an xml file with the following structure:

    <check_ip_app>
    <old_ip>111.222.333.444</old_ip>
    <send_email>send_email_here@your_email.com</send_email>
    <check_minutes>15</check_minutes>
    </check_ip_app>

    will...

    ip_xml = Document.new(File.open("old_ip.xml", "rw"))

    create a file if it doesn't already exist? if not, how can i create a file (i didn't see how in the pickaxe book File reference).
    http://ruby-doc.org/core/classes/File.html#M000050
    i'm also looking for a method to allow the user to input their email address and the number of minutes between ip address checks. how does one go about doing this?

    tia...
    http://ruby-doc.org/core/classes/Ker...c/M002976.html


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •