preload
Mar 09

My friendly oil change person taught me the trick to resetting my oil change light on my 2007 Saturn VUE:

  • 1. Turn the ignition on
  • 2. Press the gas pedal all the way down three times
  • 3. The Oil Change light and the Airbag light will alternately blink for about 15-20 seconds, then go out.
  • 4. Turn the car off.
  • When you turn the car back on, the Oil Change light will stop coming on.

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Mar 07

    While doing a quick search for Ruby code that could catch and print out the Beacon packet that Tivo machines send out on the local network, I was shocked to not find anything….tons of stuff in Perl….but nothing Ruby! Unbelievable! So I went and figured out what the code would be in Ruby. Here’s what I got:

    require 'socket'
    require 'exo/xdump'
    
    trap("INT") do
       puts "---[Ctrl-C: Exiting]---\n\n"
       Kernel.exit(0)
    end
    
    BasicSocket.do_not_reverse_lookup = true
    s = UDPSocket.new
    s.bind("0.0.0.0", 2190)
    
    loop do
       flg = IO.select([s], nil, nil, 5)
       if flg
          text, sender = s.recvfrom_nonblock(1024)
          puts "[#{Time.now}] #{sender[3]} sent beacon packet:"
          puts "[#{Time.now}]\n#{text.hexdump}"
       end
    end
    

    Nothing too fancy. The beacon is sent out as a UDP packet to port 2190. The code looks for data on the socket, then retrieves the the data and prints it out in a hex dump format like so:

    [Sun Mar 07 20:37:53 -0800 2010] 10.11.12.52 sent beacon packet:
    [Sun Mar 07 20:37:53 -0800 2010]
    000000: 7469 766f 636f 6e6e   6563 743d 310a 7377 |tivoconnect=1.sw|
    000010: 7665 7273 696f 6e3d   392e 332e 3262 2d30 |version=9.3.2b-0|
    000020: 312d 322d 3134 300a   6d65 7468 6f64 3d62 |1-2-140.method=b|
    000030: 726f 6164 6361 7374   0a69 6465 6e74 6974 |roadcast.identit|
    000040: 793d 3234 3030 3030   30Xx XxXx XxXx XxXx |y=2400000XXXXXXX|
    000050: Xx0a 6d61 6368 696e   653d XxXx XxXx XxXx |X.machine=XXXXXX|
    000060: 0a70 6c61 7466 6f72   6d3d 7463 642f 5365 |.platform=tcd/Se|
    000070: 7269 6573 320a 7365   7276 6963 6573 3d54 |ries2.services=T|
    000080: 6956 6f4d 6564 6961   5365 7276 6572 3a38 |iVoMediaServer:8|
    000090: 302f 6874 7470 0000   0000 0000 0000 0000 |0/http.         |
    

    The identity and the machine values have been changed just to be safe :)

    A big issue that a lot of folks have with UDP sockets in Ruby is trying to get a non-blocking read working correctly. The use of the IO.select above seems to be the best answer that I’ve seen…but its still not perfect. Some folks have been trying out eventmachine (See the “Non-Blocking UDP” thread over on Ruby Forum), but for this simple test, the IO.select should work just fine.

    I covered the hexdump function in a previous post.

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Mar 04

    Ever wanted to have a spell check function in your Ruby Program? As long as you have MS Word installed, you can use the Spellcheck function from your program. Here’s the code:

    require 'exo/iswindows'
    
    if not RUBY_PLATFORM.isWindows?
       puts "This program only runs under Windows!"
       exit
    end
    
    require 'win32ole'
    
    def spellcheck(scstring)
       word = WIN32OLE.new('Word.Application')
       doc = word.Documents.Add     ## Blank document
    
       word.Selection.Text = scstring
       word.Dialogs(828).Show
    
       ### return the corrected text
       if not scstring[/ /]      ## only one word with no spaces in the string
         # highlight the word first,
         word.Selection.MoveLeft( 'Unit'=>2,
                'Count'=> 1,
                'Extend'=>2)
       end
       ## multiple words end up already selected after the spell check
       # then retrieve.
       correct = word.Selection.Text
       doc.close(0)
       word.Quit
       return correct
    end
    
    if __FILE__ == $0
       puts "Corrected => #{spellcheck(ARGV[0])}"
    end
    

    The program opens a new document, pastes the text to check into the document, and then brings up the spellcheck dialog box with any words it can’t find in the dictionary and prompts you to correct the mistakes. Here’s an sample output:

    C:\Server6\Dev\Ruby>ruby spellcheck.rb "this is a test srting to seee how the slpell check is working"
    Corrected => This is a test string to see how the spell check is working
    
    C:\Server6\Dev\Ruby>ruby spellcheck.rb  antidisestablishmenttarianism
    Corrected => antidisestablishmentarianism
    

    For some reason, if you check multiple words, the dialog auto-closes after the last ‘fix’ …but if its just one word, it stays open until you click the close button. Conversely, multiple words stay selected in the Word doc after the dialog closes, but with only one word, it does not stay selected, and you have to selected it back in order to read it off the page of the document.

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Feb 16

    First off, let me say that there is not an original thought in any of this code, since it has all been taken from a number of different articles out on the Internet. The Daemonizing code was taken from the Active State Code Recipes area.

    One of my customers has a number of database servers that we would like to monitor and see what the state of the clusters are. The problem is that the clustat command — that used to be run-able by everyone in a lesser version of RHEL — is now only usable by root in RHEL v5.3!. Not wanting to give out root access to everyone, we decided that a quick little custom server that provided the output of the clustat command in XML format would do the trick. Then I just wrote a Ruby program to query all the Clustat XML servers and display the results in a readable format. If there is enough interest, I can post a public version of that program.

    Here’s the code: Continue reading »

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Feb 11

    When I want to distribute a Ruby script to a customer, sometimes its just easier to use something like Ocra to package up all the files needed into one nice .exe file that I can send over. Since I use Rake a lot, I wanted to figure out a way to automate the process. Here’s a simple example:

    ...
    desc "List available Tasks"
    task :default do
       sh %{ rake -T }
    end
    
    desc "Make BI_Competition_Status_Report.exe file"
    task :exe do
       sh %{ cd lib && rake exe }
       sh %{ move lib\\BI_Competition_Status_Report.exe .}
    end
    ...
    

    This is in your main project Rakefile. Since I’m using NetBeans, it places my Ruby files in a ./lib directory. The first sh command simply CD’s down to lib, and runs a second Rakefile located there:

    desc "Make BI_Competition_Status_Report.exe file"
    task :exe do
       sh %{ ocra --windows --icon C:/Server12/Dev/Ruby/Exonets.ico BI_Competition_Status_Report.rb}
    end
    

    This is the actual Ocra command that packages up the Ruby app into a single .exe file. When this rake command ends, the last command in the previous Rakefile moves the completed .exe file up to the current directory.

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Feb 10

    Anyone who has ever worked with networks at one point or another always ends up running a telnet or ping command over and over again to generate traffic and check if one computer can talk to another. After running that command a couple dozen times, one starts to think that maybe it would be better to write a program to do this instead.

    One of my customers has a number of RedHat servers that I’m not allowed to install any programing language like Ruby or Perl on that I would normally use to write such a program…however, they have a complete Python installation for some reason. Not to argue with fate, I wrote the following script to run my tests with:

    #
    # nettest.py
    #
    import sys
    import socket
    import time
    
    host = sys.argv[1]
    port = int(sys.argv[2])
    # type => ["tcp" or "udp"]
    type = sys.argv[3]
    test = ""
    if len(sys.argv) > 4 :
     test = sys.argv[4]
    
    while 1 :
      if type == "udp":
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      else:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      s.settimeout(5)
      try:
        if type == "udp":
          s.sendto("--TEST LINE--", (host, port))
          recv, svr = s.recvfrom(255)
          s.shutdown(2)
          print "Success connecting to " + host + " on UDP port: " + str(port)
        else:
          s.connect((host, port))
          s.shutdown(2)
          print "Success connecting to " + host + " on TCP port: " + str(port)
      except Exception, e:
        try:
          errno, errtxt = e
        except ValueError:
          print "Cannot connect to " + host + " on port: " + str(port)
        else:
          if errno == 107:
            print "Success connecting to " + host + " on UDP port: " + str(port)
          else:
            print "Cannot connect to " + host + " on port: " + str(port)
            print e
      if test != "C" :
        sys.exit(0)
    
      s.close
      time.sleep(1)
    

    This is run like so: Continue reading »

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Feb 01

    I found it a bit odd that there doesn’t seem to be any tutorials on how to automate Microsoft Visio using Ruby. Most of the other Office apps have a bunch of pages on automation, but none on Visio….that or my Google Fu is leaving me ;)

    So…. Here’s a brief tutorial on how to automate Visio using Ruby. First thing you need to do is bring in the WIN32OLE module and create a new instance of the Visio application

    require 'win32ole'
    visio = WIN32OLE.new('Visio.Application')
    

    If you already have Visio running, you can connect to it with this line instead

    visio = WIN32OLE.connect('Visio.Application')
    

    Once you have your instance, its usually best to load in all the constants from the application. Visio has tons and tons, so if you are going to try and convert any VBA or C++ code over, you will need these.

    class VisioConst
       # Empty class to hold constants
    end
    ...
    WIN32OLE.const_load(visio, VisioConst)
    

    Be sure to put the class declaration below the ‘require’ statements so your code will read better. Now we will load in a Visio template just to make things easier on us. Continue reading »

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Jan 31

    I’ve been working with Visio lately and noticed that when my programs start it up, Visio was not coming up maximized. Since I wanted to be able to see my work full screen, I started looking for a way to force it to maximized mode. I quickly learned that there is no convenient ‘visio.Maximize’ method to use. Bummer. Other Office apps have a ‘.WindowState’ parameter that can be set to minimize, maxamize, restore, or hide the application window, but not Visio. Guess that would make it too easy ;)

    For Visio, you can use the ‘ShowWindow’ function from the user32.dll to do the work:

    require 'Win32API'
    
    ##Possible cmd values:
    # Hidden => 0
    # Restored => 1
    # Minimized => 2
    # Maximized => 3
    
    def ShowWindow(wndHandle, cmd)
       wndShowWindow = Win32API.new("user32", "ShowWindow", ["p","i"], "i")
       wndShowWindow.call(wndHandle, cmd)
    end
    

    wndHandle‘ is the infamous Window Handle used in the lower-level Windows APIs. At least Visio has a way to return the handle. So in your program:
    Continue reading »

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Jan 28

    One of my customers has these Cisco 4900M Switches and we had to figure out what the baud rate/stop bits/parity settings were. In the hopes that this one day helps some other Cisco IOS newbie, here’s how you find it:

    Log into the switch, and at the command prompt, enter this command:

    show line con 0
    

    You should see something similar to this:
    Continue reading »

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with:
    Jan 27

    With all those neat Wingdings characters available, its nice to be able to insert them into an Excel spreadsheet programatically. The easiest way to go about it is to Record a Macro of the character being inserted, then use the resulting VBA code as a reference for your Ruby code.

    Working on a checklist application for a customer, I needed to insert checkmarks, and X-out characters into a column of the list. First step was to record the macro in Excel, then look at the resulting macro (To look at the macro in Excell 2003, click on Tools > Macro > Macros… then highlight the macro and click the ‘Edit’ button). For my checkmark, the code looked like this:

    ActiveCell.FormulaR1C1 = "P"
        With ActiveCell.Characters(Start:=1, Length:=1).Font
            .Name = "Wingdings 2"
            .FontStyle = "Bold"
            .Size = 10
            .Strikethrough = False
            .Superscript = False
            .Subscript = False
            .OutlineFont = False
            .Shadow = False
            .Underline = xlUnderlineStyleNone
            .ColorIndex = xlAutomatic
        End With
        Range("I23").Select
    

    So for my insertCheckmark function, my code looks like this:
    Continue reading »

    SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
    Tagged with: