Monday, October 3, 2011

DataStage Director Client: Run-time error '13': Type mismatch

We went round and round with IBM on this for several months until they finally suggested the following which works beautifully and simply to get rid of this useful-to-no-one error message:
  1. Examine the file C:\IBM\InformationServer\Version.xml to determine the clientTagId (or this could be on your D: drive or wherever you have DataStage installed). Example: <InstallType client="true" clientTagId="0a045bd2-09cd-4b80-a158-ac1cb63c8268"
  2. Run "regedit"
  3. Navigate to "HKEY_CURRENT_USER\Software\IBM\InformationServer\DataStage Client," find the key that matches the name from step 1.
  4. Rename it to <key name>.bak
Run the Director client again. You should see that none of the previously defaulting information is filled in (host name, user name, etc). This indicates that a new key is being created. Once you authenticate, you should see that the run-time error is now gone.


Wednesday, August 24, 2011

rsnapshot on SUSE Linux 11.4

A couple of friends of mine are big "rsnapshot" users. I'm glad I took time to install and configure it. I finally have the Apple Time Machine-like backups I have always wanted on Linux. Of course, I'm not using any fancy GUI. That I don't get, but I get lots of cool backups and since rsnapshot takes advantage of "hard links" there is no unnecessary file duplication in my backups.

The install was easy: I just used Yast to find "rsnapshot" and installed it. Next I had to learn enough about it to be dangerous. I edited /etc/rsnapshot.conf, learned to run "rsnapshot configtest" to test my configuration file, set my own "intervals," added some "backup" definitions, set my "snapshot_root" directory, and above all (for me) un-commented "no_create_root" I'm backing up to a USB drive, and I don't want rsnapshot assuming it's mounted when it's not. If the rsnapshot root directory I defined does not exist, I don't want it to be created. I want rsnapshot to stop dead in its tracks.

At first I ran "rsnapshot hourly" manually just to see what it was really doing. After some experimentation (who needs online help or user manuals?), I finally realized the significance of the "intervals" and what rsnapshot is doing with them. Basically it's this: once you've created the number of "hourly" backup directories defined in your interval configuration, the next time you run "rsnapshot hourly" it will replace the oldest directory with a new one. If the next interval "up" is "daily" then I must have run the defined number of hourly backups first. So, let's say my intervals are define thus:


interval        hourly  6
interval        daily   14

If I have only 5 hourly backups then "rsnapshot daily" has nothing to do. If I have six, then the most recent one becomes my first "daily" backup directory and I then have one less hourly directory. Like this:

drwxr-xr-x 3 root root 4096 Aug 23 04:19 daily.0
drwxr-xr-x 3 root root 4096 Aug 21 18:26 daily.1
drwxr-xr-x 3 root root 4096 Aug 21 16:27 daily.2
drwxr-xr-x 3 root root 4096 Aug 21 16:22 daily.3
drwxr-xr-x 3 root root 4096 Aug 21 16:02 daily.4
drwxr-xr-x 3 root root 4096 Aug 24 23:18 hourly.0
drwxr-xr-x 3 root root 4096 Aug 24 20:18 hourly.1
drwxr-xr-x 3 root root 4096 Aug 24 05:02 hourly.2
drwxr-xr-x 3 root root 4096 Aug 24 04:19 hourly.3
drwxr-xr-x 3 root root 4096 Aug 23 19:22 hourly.4

If I run "rsnapshot daily" again, there is nothing to do, and if I look at /var/logs/rsnapshot, that's what it tells me: "hourly.5 not present (yet), nothing to copy."

The next run of "rsnapshot hourly" will create the "hourly.5" (which is number 6).

You can define whatever intervals you want. I could have weekly, monthly, and yearly, etc.

So know I know enough about rsnapshot to use it and enjoy it.




Upgrading to SUSE 11.4

Just a quick note about my recent upgrade from SUSE 11.3 to 11.4: it was darn easy, really. I used the "Network" CD which installed the update from online repositories. I normally don't "upgrade" any OS. I usually start from scratch and do a new clean install. I felt lazy and bold this time, so I just upgraded my OS (after taking images of my disk partitions just in case). I had not heard the "horror" stories of the SUSE 11.4 upgrade. I heard them afterward, and I'm glad I was blissfully ignorant, because for me the upgrade worked just fine and saved a lot of time over a fresh install. I'm now happily running 11.4. 

Dropbox on SUSE Linux 11.4

I created a Dropbox account today and had to piece together bits and pieces of how to get it up and running on SUSE Linux 11.4. Sad to say it was not obvious. The following notes will hopefully make it obvious to the reader (who will probably be me some day in the future when I'm trying to do this again).

Steps to Initial Success
  1. Download the bz2 file from the "Compile from Source (bz2)" link at https://www.dropbox.com/downloading?os=lnx
  2. Unzip and in the resulting nautilus-dropbox-0.6.9 directory, run "./configure" which told me to install "lib-nautilus" (lib-nautilus1 in YAST) and "docutil." From Yast, I installed lib-nautilus1 and nautilus-devel as well as docutil.
  3. Run "make"
  4. And then as root, "make install"
  5. The following steps are done as my standard user ...
  6. Run "dropbox" to see the dropbox command help/program usage.
  7. Run "dropbox -i start" to start it up the first time which brings up a graphical dialog confirming that I will now download the "proprietary daemon" which I did.
  8. Once downloaded, a tutorial dialog comes up and eventually (after providing dropbox login name and password) the nautilus file manager and my "Dropbox" file folder which appears under my home directory but it's a synced folder with my online dropbox file folders.
From the command line I can check the status of the dropbox daemon or stop it:
  1. dropbox status
  2. dropbox stop
Now that the "proprietary daemon" is installed, I can just give the command "dropbox start" to get it going again. And when it's running, I see a cute little open box icon in my task manager tray. If I click on it, the nautilus file browser opens again. So long as the daemon is running, the file manager shows "bold green checks" on the items that are synced and living online in Dropbox:


When the daemon is stopped, the check marks disappear to let me know that folders aren't currently live with Dropbox.

Creating rcdropboxd

I grabbed the text found there and placed it in /etc/init.d/dropboxd. I created a symbolic link to /usr/sbin/rcdropboxd for convenience. Per the text for the script, I created /etc/dropbox/dropbox.conf and added a single line:

DROPBOX_USERS="<my user name>"

Now I can start the daemon by running "rcdropboxd" and I could go into Yast->Configure runlevels and start dropbox as a system service. Of course the "dropbox" command itself as an "autostart" argument that would be used to start dropbox on login. In the end, I prefer to start it when I want it running and stop it when I don't. Note that dropbox is installed with "autostart on" by default. So, from the command line I ran: "dropbox autostart n" to turn it off.



Friday, June 3, 2011

odbcad32.exe: setting up ODBC access on Windows 7 64 bit

A long-time customer of mine bought some Windows 7 64 bit machines. I needed to set up an ODBC connection to an MS Access database for a  custom legacy Java program. When I went into ODBC the only driver available was one for SQLServer. I googled, I searched, I looked through Windows 7 books at Borders.So far no answer. No Luck.

I used my MSDN subscription to create a new Windows 7 VM and unfortunately there was no trouble there! All the usual drivers appeared. And unfortunately, I created a 32 bit machine, and the problem does not exist 32 bit Windows 7. But I did not know that at the time, and it only deepened the mystery. Why did I have no trouble creating the ODBC connection to MS Access right from the time the machine fired up for the first time?

Finally I posted the question to Windows 7 & Server 2008 R2 troubleshooters group on LinkedIn. Someone there was kind enough to clue me in and tell me to run %windir%\syswow64\odbcad32.exe. That brought up the usual ODBC dialog, but now when I created a "File DSN," I had access to the MS Access driver which I configured to use the appropriate database file (.mdb file).

Had I fired up a 64 bit Windows 7 VM I could have duplicated the problem. As it is, I did see the same issue on a number of windows 7 machines at Best Buy from several different OEMs. 

Sunday, May 15, 2011

Converting Text to PDF

Converting text to PDF is handy and can be a shortcut around the complexities of generating pdf output when your needs are simple. One way to do it is using "enscript" and "ps2pdf" as in the following command:

enscript --no-header --landscape -q -p - my_text_file.txt|ps2pdf - my_pdf_file.pdf

If you need enscript, you can get it from: http://www.iki.fi/~mtr/genscript/

Building it yourself is straightforward. Once you untar/unzip the download, you can use "./config --help" to get help in special configurations if you need it.

Saturday, April 23, 2011

Rails 3: Converting has_and_belongs_to_many to has_many :through

Reference: http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

Converting my old Rails 2 app to Rails 3 has been a great education. In this lesson, I had to convert has_and_belongs_to_many to "has_many :through," because as of Rails 3.1, has_and_belongs_to_many with attributes to join the table/model will be deprecated (see comments to this post).So, while the old helper worked fine with Rails 3.0, I decided to be proactive and modernize my app even further.

Once I found the above referenced guide and saw the example about physicians and patients, it seemed straightforward enough. So, why was mine not working? How does one go about debugging it when Rails is throwing exceptions all over the place. And what can possibly go wrong? As I found out, a lot of little things. It's easy to misspell a table reference and never know anything is wrong until the code tries to exercise the association in some way. In one case I found that ":through => 'table_name' " did not work, but ":through => :table_name" did. So, while I got away with using a string in my old code, only a symbol seemed to work in the new code. So, how do I make it easy to debug this stuff?

The first key for me was to use the rails "console," so in my app home directory, I give the command "rails console," and now I have an interactive Ruby session with all my application structures available. In particular I can call upon models to do their thing. I can, for example give the command: User.find(508) to find the user record with id 508. And don't forget about "reload!" which is invaluable for reloading your code in the console session as you're changing it in an editor.

The second key for me was to go through each association one at a time, very methodically, and make sure every necessary component is working. The most fundamental part is the table that provides the two-way association. In my app I have volunteers that attend training sessions. I want to know which training sessions users have attended, and which users have attended which training sessions. So, I have a "training_sessions_users" table. In my schema.rb, I see:

  create_table "training_sessions_users", :id => false, :force => true do |t|
    t.integer  "training_session_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "user_id"
  end

In training_sessions_user.rb then, I need the following two lines of code:
  • belongs_to :user
  • belongs_to :training_session
This creates two simple associations that are easy to test. The following must work, and I made sure I had data to test with:
  • TrainingSessionsUser.first.user
  • TrainingSessionsUser.first.training_session
This is the simplest yet most fundamental part of the whole equation. It's a logical place to start, and I made sure that much worked.

Now for my training sessions. In training_session.rb, I have first and foremost the following:
  • has_many :training_sessions_users, :dependent => :destroy
This means that the following has got to work, and that's the next thing I verified and debugged as necessary:
  • TrainingSession.first.training_sessions_users
Similarly on the user side:
  • has_many :training_sessions_users, :dependent => :destroy
Implies that the following must work, assuming I have a user with id 508:
  • User.find(508).training_sessions_users
So far so good. All of this must be working, but it does not imply that everything I had working using "has_and_belongs_to_many" is still working. So, the next step is to verify that the following found in training_session.rb:
  • has_many :users, :through => :training_sessions_user, :order => 'last_name,first_name,middle_name'
This implies that the following must work:
  • TrainingSession.first.users
Likewise in user.rb:
  • has_many :training_sessions, :through => :training_sessions_users, :order => "date_of_training desc"
Which implies that the following must work:
  • User.find(508).training_sessions
Conclusion
Once I had this verification pattern laid out after my struggles with the first conversion of has_and_belongs_to_many, the next one went relatively smoothly. There were still things to debug. It's so easy to misspell things ever so slightly -- to leave something singular when it needs to be plural, for instance. Or to spell "has_many" as "has_manu," and since you don't see that when you first fire up your application, since it only pops up at runtime, it is imperative to have some methodology to work this out ahead of time. And of course, when you have a patten like the one above, it's easy to encapsulate this in test procedures.

Tuesday, March 29, 2011

Getting my Rails3 App Up and Running for the First Time on Site5

Currently the key documentation for getting a Rails 3 application working when you're using Site5 for your hosting is: http://www.site5.com/blog/programming/how-to-enable-rails-3-0-on-site5/20101007/.

When I log into my web site at site5 at a secure shell prompt, I see the following by default:
  • Rails version 3.0.1
  • Gem version 1.3.7
  • ruby version 1.8.7 (2009-06-08 patchlevel 173) [x86_64-linux]
My application was built using Rails 3.0.5 and expects that version -- not 3.0.1. But that's not a problem. Here's what I did to get it running on my web site hosted by Site5:
  • Set my .bashrc and .bash_profile files up following the Site5 article, although I chose to put most of it in .bashrc rather than .bash_profile. I found when it was in .bashrc, it was set when I logged in at a command prompt where I wanted it to be. My .bash_profile sources .bashrc anyway.
  • Set my .gemrc file up just as the article says.
  • Renamed the existing public_html and linked my app's "public" directory to public_html as the site5 article says.
  • cd to my app directory and ran: "bundle install --path vendor/bundle" to install Rails 3.0.5 and all other dependent gems my application needed.
  • Managing my web site using the excellent Site5 web tools, I created my development MySql database and added my app's development user and set its database permissions.
  • I modified my app's "database.yml" file according to the database and user I had created. I made the configuration of "production" and "development" identical, because when Site5 runs my app, it's running in production mode. I don't care about having a separate database at the moment. I'm just looking for proof of concept.
  • In my application directory from a command line I ran "rake db:migrate" to create all my tables and indexes. This ran as usual in the default "development" configuration, but since I configured my database connections as noted above so that "development" and "production" connect in the same way, it's OK to operate in the default mode.
  • In my apps "public" directory I created the .htaccess file as the Site5 article shows.
  • And again following the Site5 article, I "restarted" my application my giving the command "touch tmp/restart.txt" -- that's how to tell the server to restart your application.
And that was all I had to do. And by the way: Site5 has excellent support ready to carry on a live conversation or respond to your support ticket -- and they respond fast! (Even on Sunday mornings US Eastern Time when I'm often working on this.)

Vern






Tuesday, March 22, 2011

Upgrading Rails 2.3.5 App to 3.0.x: Continued

This post is a work in progress. I will add to it as I progress bringing my app up-to-date.

Now that my application is working again (see my previous post). I'm going through and upgrading various bits of things that will be deprecated:


  1. RAILS_ENV becomes Rails.env, RAILS_ROOT, Rails.root.
  2. <% form_for ... %> and <% form_tag ... %> become <%= form_for ... %> and <%= form_tag %>
  3. Hour.find(:all, ...) becomes Hour.all
  4. Hour.find(:all,:conditions => ["user_name = ?",user_name],:order => 'date_of_service desc',:limit => limit) becomes Hour.where("user_name = ?",user_name).order('date_of_service desc').limit(limit)
  5. We don't need the rails_upgrade plugin any more, so remove it: rails plugin remove rails_upgrade
  6. In application.rb: "config.smtp_settings" becomes "config.action_mailer.smtp_settings"
  7. Move a class that subclasses ActionMailer::Base: mv app/models/volunteer_mailer.rb app/mailers
  8. VolunteerMailer.deliver_message_to_volunteer_coordinator() becomes VolunteerMailer.message_to_volunteer_coordinator.deliver()

Saturday, March 12, 2011

Upgrading Rails 2.3.5 App to 3.0.x: From Frustration to Initial Success

I'm migrating a tried and true Rails 2.3.5 app to Rails 3. It's been a frustrating and enlightening project. The main frustration is my impatience. It's not all that hard, but since I'm doing this in my spare time, I wanted instant gratification, and I didn't get it. However, I'm finally to the point that the app is up and running, and I'm just shaking out more of the little things as well as brining it more in compliance with future upgrades that we know will be coming. Here are some notes (My app is named "pferd", the German word for horse, which stands for the Pegasus Farm Electronic Relational Database. When you see "pferd" that's my app name). I'm sure I'll be posting more. But this much got me to a functional application.
  1. Read some key articles, like:
  2. Bought Agile Web Development with Rails. This has proven to be a great quick reference. I'll read it thoroughly soon.
  3. Made a good backup of my existing app, and then copied it to "pferd.prev" so I can continue to run it every now and then to compare with the new version.
  4. Installed the latest rails: gem install rails.
  5. In my as yet still Rails 2 application and with Rails 2.3.5 still installed on my system, I ran: script/plugin install git://github.com/rails/rails_upgrade.git
  6. Captured the notes this install process puts out.
  7. Per those instructions ran: rake rails:upgrade:check
  8. Per the same instructions ran: rake rails:upgrade:backup
  9. Captured the notes this process generates for future reference.
  10. In the root directory of my app, ran: "rails new ." and confirmed that I want to overwrite all.
  11. NOTE: at this point I now have a Rails 3 app, and the upgrade plugin rake commands are no longer guaranteed to work. But since I still have "pferd.prev" which is still a Rails 2 application, I can still run the usual commands there as long as I need to. I have a Rails 3 application, so I have to start running Rails 3 compliant commands. I run "rails sever" for instance, instead of "script/server", etc.
  12. Installed "mysql2" gem: gem install mysql2.
  13. Renamed public/index.html created by the "rails new" command above so the app starts where I want it to start.
  14. Edit "Gemfile" to get rid of reference to sqlite3 and add "gem 'mysql2'"
  15. In my Rails 2 version ("pferd.prev") ran: "rake rails:upgrade:routes" and used the output of that command in config/routes.rb in my Rails 3 application.
  16. Created a new database migration to delete column "id" from all "join" tables (tables used in many to many relationships as specified by the "has_and_belongs_to_many" helper methods). Without this you get the error: Primary key is not allowed in a has_and_belongs_to_many join table ... .
  17. Restored app/views/layouts/application.html.erb from pferd.prev.
  18. Added call to "super" in all the controllers I'd created in which I had my own "constructor" (the initialize method). Without this, ApplicationController was not properly initializing my pages. It was not calling app/views/layouts/application.html.erb. The most obvious side effect was that none of my defined styles were coming in from my pferd.css style sheets file.
  19. I use "will_paginate" to paginate lists of records. It was broken after the upgrade. To fix it, I added "gem 'will_paginate',  '>=  3.0.pre'" to the Gemfile and then ran: "bundle install" which installed "will_paginate (3.0.pre2)" for me. I guess I might have used this method for mysql2 above also, but I did not.
  20. Ran "rails plugin install git://github.com/rails/dynamic_form.git" to prevent "DEPRECATION WARNING: f.error_messages was removed from Rails and is now available as a plugin."
  21. Replaced RAILS_ENV with Rails.env and RAILS_ROOT with Rails.root everywhere.

Netbeans 6.91 and Rails 3

My long time favorite IDE for Ruby and Rails has been Netbeans. And more specifically, I really like the code editor. I rarely use anything but the editor. I don't typically call upon the IDE to do much else besides edit my code for me. I realize that support for Ruby and Rails is going away or has already gone away. However, there is an effort to keep that going. And Netbeans 6.9.1 continue to run just fine and it still has ruby and rails in it.

So now that I'm moving on to Rails 3, how is the old Netbeans doing? Superb! So far for what I've asked it to do, it just does it. And I'm glad it nags me about things like replacing RAILS_ENV with Rails.env.

BTW: I tried RubyMine, but it was not as good as Netbeans and would have cost me $60.00. Maybe I'd change my mind if I switched over to RubyMine for a week or so to really get acquainted with it, but a few minutes with the evaluation copy did not give me enough motivation to leave Netbeans.

Wednesday, March 2, 2011

Moving My Website to Site5

Over the weekend I moved my web site from myhosting.com to Site5. I wish I'd done that years ago. It's been over ten years since I did anything like this. It's a lot easier now than it was then. And Site5 is a pleasure. I get so much more for less money than I ever did before. My primary motivation is to put up a Ruby on Rails application. I could have done with my former provider -- if I'd cared to spend more money. Instead I'm spending less and getting that and other benefits (like ssh into my web site right out of the gate).

I also found out the hard way about an unfortunate policy of my former provider: you never get a refund for the service you pay if you cancel before the end of the term. So, if you were doing them and yourself a favor and happened (as I did) to pay annually, you wait till the end of that 12 month term. If you were paying monthly you're out of some money. I had been with them for years and years and had nothing bad to say about them, but that policy is very unfortunate, and there's no budging them. I get credit toward other services -- which I have no use for. The best I can do is apply the money I spent to domain renewal. That will take me a long time.

Oh well. I'm so happy with site5 I can't say I really care.

Friday, February 25, 2011

Trouble Installing Driver in Windows 7 for Network Printer

Recently I was asked to prep a new Windows 7 machine for a client. One of the things I had to do was get their Oki Data ML 390 Turbo setup on the new machine. The oki was on the network. I searched and searched for a driver for the oki, and all I found kept telling me that Windows 7 supported the printer out of the box. But it sure was not finding a driver for it when I tried to create the network printer. Finally I hit upon a formula that worked:

  1. Add the printer as if it were local. Windows 7 let me create the printer even though it was not currently connected to the machine.
  2. Go into the properties of the printer and change the port name to the network name of the printer, like: s:\\myserver\\okidata.
That was it. It should not have been so difficult, but Windows 7, while under the hood it's pretty much the same as Windows has been for years, did not want to do it any other way.

Permissions in Windows 7

If you're a Windows 7 user and you find Windows denying you access to modify files on your very own machine -- the machine for which you should have all permissions that you want -- just run whatever it is you want to run in administrator mode. If, for example, you want to edit the "hosts" file found in windows\system32\drivers\etc, choose your favorite editor, but instead of left clicking to start it, right click on the icon and choose "Run as Administrator." You'll be asked to confirm this decision and just say yes. You're on your way.

Recovering a Deleted Blog

If you're a blogspot user and delete one of your blogs, it will be available to recover for up to 90 days. To un-delete it, go to your Dashboard under the manage blog section and choose "Show All." This will blogs you recently deleted and there will be a link titled "undelete this blog."

Saturday, February 19, 2011

Adding Tables to an Existing Rails Application

I've developed some new features for an existing Rails Application. It's working in my development environment on my development machine. I'm not using any fancy tools to deploy to the production server. I simply shut the application down and re-install all application files. When I wanted to run the last two data migrations to install the new e-mail group tables, I ran something like:

rake db:migrate RAILS_ENV=production VERSION=20110113091119_create_email_groups

But this results in the error: rake aborted! Multiple migrations have the name CreateSessions


So, I had to learn more about rake. I know I don't want to run "rake db:schema:load". That would get rid of all existing data. I'm still unclear what the ideal rails-guru blessed right way to do it is. But I do see one way I can do it:

  1. Run "rake db:structure:dump" from an existing instance that has the tables I'm looking for. This creates a .sql file containing various create statements to create the tables, indexes, etc. for my application.
  2. I can take that file, make a copy of it, edit it such that all that's left are the create statements I need to add the two new tables to my production system. Let's say I name it: email_groups.sql and place it in my app's db directory.
  3. Then I can run something like this (my database is MySQL): cat db/email_groups.sql|mysql -h localhost -u my_db_user -pmy_db_password -D my_database_name
If anyone cares to comment and enlighten me on the better or proper way to do this, I'd be happy to read your comments.

Monday, February 7, 2011

Salesforce Data Loader Quick Start

Assuming you have some background in Salesforce and you want to start using Salesforce Data Loader quickly, here's what I recommend:

  1. Download Data Loader and install it. Do this by logging into your Salesforce Instance and go to Setup->Data Management->Data Loader and click on "Download the Data Loader." Then install it. (Need your own instance? Go to Developer Force and click on "Join Now" to get your free account and free instance of Salesforce.)
  2. Read through the Data Loader Developer's Guide. ** This is not a long document as tech documents go. It won't take you that long to read it. **
  3. Run the Data Loader that you installed in step 1 above and try it out. It's pretty easy to use. Not necessarily convenient, but pretty easy to try some exports and upserts.
  4. Stop here if the Data Loader GUI is all you need.
  5. Check out Informatica Cloud if all you need is a GUI interface to data loader functionality, and don't mind paying for it if you want real functionality for real data.
  6. If you want to run the Data Loader in batch or per schedule, go to CLIq and watch the Video and take it from there.
Tip: If you use CLIq for inserts or upserts, at one point you'll need a field mapping file (a .sdl) file. If you have a complex mapping or lots of fields, you might want to start by running your upsert or insert using the Salesforce Data Loader interactively. In the process you'll map your fields from your CSV file to Salesforce object fields using a drag and drop interface. And you'll end up creating the .sdl mapping file which you can use for the uploads you configure with CLIq.

One other Tip: I see a number of postings related to external ID errors. A common one is: "Error:  exceptionMessage='Field name provided,  does not match an External ID for ..." Just make sure if you are inserting or upserting data with external ids that you have an entry in your process-conf.xml file for the sfdc.externalIdField property. See the  Data Loader Developer's Guide for details.

If you follow these steps it will be relatively simple to get going with data loader. Obviously, you can dig further to become an expert or start rolling your own tools. Here are some other resources for taking this subject deeper:


IE Tab: When Sites Don't Work with Google Chrome

I really like Google Chrome, and I'm not happy when some sites refuse to work because I'm not using Internet Explorer or a version of Firefox. But I'm really happy to have found the "IE Tab" extension for Chrome. Using it, I don't have to leave Chrome to access such web sites. I just click on the "IE Tab" icon, and voila: I'm in. Fabulous. Check it out at: http://www.ietab.net/faq

How it works: when you open a URL in Chrome and get some error message or otherwise see that it does not work in Chrome, you hit the "IE Tab" extension icon. I.E. begins to run for that url within Chrome. At the top of the Chrome window where the web site is now running you'll see your IE url and to the right several icons. The first will take you into IE Tab configuration. The next will add the url to "IE Tab." This means a bookmark will be created for you in a folder called "IE Tab" on your "bookmarks bar" so that next time, you just use that bookmark and you will be taken directly into IE within Chrome so it's a simple one step process.

Saturday, February 5, 2011

Kindle Search Made Easy

Here's something I read about this week that is really handy. First of all, searching your current book, all your books, or the web with the Kindle 3 is easy and useful. You can do this wherever you are just by typing a word or words and use the dialog that comes up to search wherever you choose. The default will usually be the current book you're reading. But here's a trick: use the 5-way button to move your cursor to some term in the book you're reading you want to search for, press the center of the 5-way button, move the cursor to highlight any number of words or sentences, then, and here's the key, HIT THE SPACEBAR. That will move all text you've highlighted into the search box and then you can search for those words wherever you want. That's much easier than typing the words yourself.

And you might want to check out some kindle blogs too, like http://kindleworld.blogspot.com/

Rails ActionMailer: SMTP Settings on the Fly

Most of the information I had found for configuring the Rails ActionMailer was static: set in environment.rb at the time the web application starts up. But what if we need to change that on the fly? What if, for example, the smtp settings are governed by a preferences file and the user updates the preferences. Not an issue, once you find where this stuff is stored. Let's start with lines that are typically found in your environment.rb file:

#-----------------------------
Rails::Initializer.run do |config|

  config.action_mailer.smtp_settings = {
    :enable_starttls_auto => true,
    :address => 'smtp.gmail.com',
    :port => 587,
    :domain => "gmail.com" ,
    :authentication => :login,
    :user_name => 'my_gmail@gmail.com',
    :password => 'my_password',
  }
end
#-----------------------------

Of course if you were getting that from some preferences file, you'd not be hard coding the e-mail address and password. That's something you can easily change. But now for the answer to our problem: where are the smtp settings stored? How can you get at them to change them at runtime?

You'll find them in ActionMailer::Base.smtp_settings. So you can do things like:

ActionMailer::Base.smtp_settings[:user_name] = my_new_email

ActionMailer::Base.smtp_settings[:user_name] = my_new_password

That's it. It's that simple, though it was not that simple to dig this up.




Monday, January 31, 2011

Send to Kindle Extension to Chrome Browser

About a month ago I switched over to Google Chrome for web browsing, and I'm very happy I did. And recently a friend made me aware of the "Send to Kindle" Chrome extension. I wasn't sure how much I'd use this extension, but I installed it anyway. I find I use it a lot. It makes sending an article on the web to the Kindle a snap, and I miss it when the only option to view an article in its entirety is PDF which the extension won't send automatically to the Kindle.

But why would I want to read anything on the Kindle that I can read in my web browser? First of all, I very often want to read things of interest later. Sending the article to my Kindle lets me read it when I'm relaxing in the evening or at other convenient times. Second, the Kindle is great for reading period. It's not a great web browser, it's not a phone, but it's just great for reading. As I read it's so easy to look up unfamiliar words and add to my vocabulary. It's easy to add notes. And for longer articles, it keeps my place so I can pick up right where I left off. With my busy schedule that's important. And it keeps things "in my queue." When I read them, I either save them to some collection if they are that good or delete them and they're gone. My reading is efficient and organized.

cygwin shutdown command

cygwin (http://www.cygwin.com/) is a treasure trove of handy utilities for Windows machines -- especially useful for those of us who prefer the Unix/Linux systems but still have to use Windows. The "shutdown" command is particularly handy. My home PC is running Linux, but I "remote desktop" using the "rdesktop" into my wife's Windows machine all the time. Sometimes when I'm done I want to shut the remote machine down. That's easy with the cygwin "shutdown" command: "shutdown -s -f now" and it's on its way to shutdown without my having to walk over to it, get its attention, request a shutdown, confirm that I really really do want to shut it down, and finally start the process.

Saturday, January 22, 2011

a2pdf: Convert ASCII to PDF

I was looking for an easy way to convert text files to PDF, and a2pdf is pretty cool. I did discover one issue with multi-page documents on an HPUX server: if --nofooter or --nopage-numbers are given on the command line and exception is raised. I found that if I allow the footer with a page number, it works file. I've reported this to the developer, and if I get a response, I'll post it here. It's a pretty awesome application. See also: http://perl.jonallen.info/projects/a2pdf

Chase Bank Android Application

I tried the Chase Bank Android Application. Their mobile banking web site had always worked well. The app looks nice, but it has two issues as far as I'm concerned:

  1. Every time you switch back to the app it wants you to log in again. So, if you take 2 seconds to switch over to text messaging, password management, anything, you'll be asked to log in again. That's not very practical as far as I'm concerned.
  2. The only reason I was curious about this app was for check deposits. But the app would not recognize the dollar amount on the handwritten check,
I probably won't get much use out of this app for now at least.

Sunday, January 16, 2011

Simple Wealth/Inevitable Wealth Book

This is definitely not a technical how-to, but the book I'm writing about is absolutely a how-to book. And I do highly recommend a book that my accountant recommended (whom I also highly recommend: Jason Marsden, CPA): Simple Wealth/Inevitable Wealth by Nick Murray. This is one of those books that as I read it I find myself wishing I'd known this stuff a long time ago. However, had I read this book a long time ago, would I have been ready to learn from it? Possibly not, but the time for me has come. Mr. Murray brings this subject down to earth, makes a good case for mutual funds, but never really attempts to say it's his way or the highway. I like that. And I'm the type of person who has to know "why" before I believe it. Murray tells me why. And he explains things in such a way as to make everything very understandable. If you get the book, get the latest edition you can. It's not that important, because the principles won't change over time, but even so.

I also like the funds that my CPA recommended. They've done very well. I was impressed by the history of the company and their funds dating back to the great depression: American Funds. Mr. Marsden was right on to recommend this company, and the mix of funds he recommended for me have done very well. However, as Mr. Murray writes, the particular fund itself is less important. Nevertheless mine have done well in the past few months. But also as Murray points out: it's the long term not the short term that matters.

Friday, January 14, 2011

Saving a PDF file in Google Chrome: Work Around

There are times when it seems that I cannot save a PDF file that I'm viewing in Chrome. Sometimes the option just isn't there. I'm finding however that if I right click on the document I'm viewing and select "Open Frame in New Window," once the new window is open I can right click on the document and use "Save As." I've use this several times already to save my pdf. And it saves me going back to Firefox, and that's a good thing.

Tuesday, January 4, 2011

Ruby Find: The Pleasure of Ruby

I was a Perl enthusiast years ago when I could hardly convince anyone at my company to do Perl. They were using C and many of them were darn good at it. A number of years after I left they were bringing Perl experts in to train the staff. Perl had finally gained acceptance. But over the years I grew tired of Perl's cobbled in object orientation, it's penchant for making last minute runtime decisions about what it thought I intended my code to do, and just how easy it really was to write obfuscated Perl without really trying.

A few years ago I discovered the pleasures of Ruby (along with Ruby on Rails) and most recently I've been getting to know JRuby which lets me make Java easy by adding the power of Ruby. Why is Ruby so cool? Number one in my book is its rich set of libraries. Perl used to claim that it made difficult things possible, but Ruby very often makes difficult things easy. Take a simple recursive "find" for example: traversing various directories until you've got all of them listed along with all their content listed. It's not trivial, and there are lots of samples out there of how to do it. But why not do it the easy way. Life's too short, just use Ruby Find.The documentation for this Ruby module is sparse simply because there's not much to it. It's easy!

The other day I used two calls to find to very quickly compare mounted volumes of content and found another tidbit that was worth its weight in gold at the time: "lstat()" Now most any unix or linux programmer knows about stat(). It's been around a very long time. I used it years ago in C code. Back then it returned a structure with all sorts of tidbits about some file or directory or link or whatever. Things like the last modified date, file size, etc. Perl and Ruby have continued to offer its equivalent. The purpose of my code was to see if any file or directory on a target "mirrored" system had changed to a symbolic link on the source system or vice version. Without thinking I used "stat()" But as I was checking my results I noticed that "stat()" was returning statistics on the object the symbolic link was linked too. That's not what I wanted at all. Immediately my mind began thinking how to work around this annoyance when I discovered lstat() and found that the Ruby folks had anticipated my problem. That method does not follow the link, it returns statistics on the link, and that's exactly what I wanted. In particular I wanted to know the file system type. I wanted to compare the file system types on the two file systems and see if they were different.

That's the pleasure of Ruby: again and again I find I can be more productive and have more fun because the Ruby folks have anticipated my needs.

And there are few things better than ActiveRecord, but you won't find that documentation simple or easy. That object does way too much. But in the end it makes accessing database records a snap.

Here's my compare() method in which I use Ruby's Find module:


class Array
  # convert a hash to an array ...
  def to_h
    Hash[*enum_with_index.to_a.flatten]
  end
end

require 'find'

 def compare
    whoami = "compare"
    debug.debug(whoami,__LINE__,"Source: \"#{self.source}\"")
    debug.debug(whoami,__LINE__,"Target : \"#{self.target}\"")


    my_source = get_contents(self.source)


    my_target = get_contents(self.target)


    my_source.keys.sort.each do |path|
      if path and path.strip != ""
        if my_target.has_key?(path) # The source path is found in the target


          source_path = File.join(self.source,path)
          target_path  = File.join(self.target,path)
          if File.exists?(target_path) # The target path still exists. It's possible we already removed it if it's down in some directory


            # Note the use of "lstat()" which does not follow the last link, instead it stats the link itself, which is what we want!
            source_type = File.lstat(source_path).ftype
            target_type = File.lstat(target_path).ftype


            unless source_type == target_type
              debug.debug(whoami,__LINE__,"(path,source_type,target_type) = (#{path},#{source_type},#{target_type})")


              if self.remove
                if target_path =~ /^media\// # Special sanity check
                  debug.debug(whoami,__LINE__,"Removing: \"#{target_path}\"")
                  begin
                    File.delete(target_path)
                  rescue Errno::EISDIR
                    system("rm -r -f '#{target_path}'")
                  end
                else
                  throw "Too dangerous to remove: '#{target_path}'"
                end
              end
            end
          end
        end
      end
    end
    debug.debug(whoami,__LINE__,"Done")
  end



  private


  # Get the contents for a directory ...
  def get_contents(dir)
    list = Array.new
    Find.find(dir) do |path|
      if File.readable?(path) # If it's not readable, just skip it, example" ~/.gvfs
        list << path[dir.length .. path.length] # We only want the relative path, not the full path, so we get rid of the parent directory name
      end
    end
    return list.to_h
  end



KDE 4: Grouping/Ungrouping Programs in the Panel

I used to be rather annoyed that my various Wine programs or Java programs where all lumped together under one tab on the control panel. Then I happened to notice that if I right click on the group and choose "Do not allow this program to be grouped," I no longer saw Quickbooks lumped in with IE 7 or Freeplane lumped with Netbeans. That was easy, and it's just as easy to undo that by right clicking and choosing "Allow this program to be grouped."

I will say that grouping can be handy when there are so many programs running at once. Bu when all the Java programs are lumped together or all the Wine ones, it's a pain. But it's easily solved in KDE.

Freemind and Freeplane

I used to create all sorts of various documents that were nothing more than lists usually in outline form. Then a friend told me about Freemind -- "mind mapping" software. I tried it and liked it. I used it for years. Then I found Freeplane and liked it even better. Freeplane is a "fork" of the Freemind project and maintains file compatibility with the original Freeplane. So it was easy for me to just start using it.

The bottom line is that Freemind and Freeplane have enabled me to easily keep listed notes (usually how to's) in mind-map form. Each node is a topic and each sub node elaborates on that topic with any number of sub nodes on top of that. This is as incredibly useful as it is simple. For example:


  • Windows
    • Canon Printer Ink Type
      • Start->Printers
      • Right click on the printer and choose properties
      • Then the maintenance tab
      • Then the view printer status button
      • Then the ink details tab
    • Windows 2008
      • add/remove programs
        • control panel->programs and features
      • single click to open files and folders
        • My Computer->Open
        • Pull down "Organize" tab->Folder and Search Options, and right in front of you from the general tab, select single click
      • change your login picture
        • control panel->user accounts, choose the account, change the picture (or start and click on your icon right there)
You get the picture, except what you see is this outline in mind-map mode. I'll not try to reproduce the look and feel here. And I've found this format wonderfully practical and useful.

Amazon Kindle: E-mailing Documents to the Kindle

I got an Amazon Kindle from Santa this year. I'd been reading Kindle books for months on my Droid Eris smart phone. I wasn't sure I'd like the real deal, but I really do. One of the features of the Kindle is that you can e-mail documents to your Kindle. Your Kindle is assigned an e-mail address, <something>@kindle.com, and if you e-mail documents to that address they will be downloaded to your Kindle. OK. May be useful some day I thought. But now I find myself finding techie and other articles on the web, printing them to PDF, and e-mailing them to my kindle with the subject "convert." That asks Amazon to convert the document to a full-fledged Kindle format. Without conversion the Kindle can browse a PDF. But I rather like the Kindle format. And I'm finding I'd rather read this stuff at my leisure on my Kindle than on the web. Further I can create collections of the ones that are worth saving. It's kind of like subscribing to magazines that aren't yet available on the Kindle. I can optionally zip up a group of documents and just attach the zip file. Amazon will sort it out and convert each one of the zipped up files.

Be aware that if you use this feature, the e-mail you send from must be listed with Amazon. Log into your Amazon account, navigate to the page where you manage your Kindle, and add the e-mail address(es) or Amazon will dump your submission into the bit bucket.