Monday, December 03, 2012

OS X Open With Out-of-date

On my Mac system I’ve noticed that, for some reason, multiple versions of a program, or even programs I no longer have installed, will show on the “Open with” menu in finder. Something like what you see in the screenshot.

http://content.screencast.com/users/TroyMurray/folders/Snagit/media/68ddf734-f134-4350-bcc3-db668d17bf12/2012-12-03_10-48-47.png

Turns out this list is a sort of internal database that needs to be cleaned once in a while, but I’m not sure why the system fails to do this on it’s own. Regardless, this can be corrected by triggering a refresh of the database system and then re-launching the Finder.

Open Terminal and paste the following exactly, it should be all on one line:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user

After that command finishes, hold down the Control + Option keys on your keyboard, then click on the Finder icon and select “Relaunch” http://content.screencast.com/users/TroyMurray/folders/Snagit/media/066851e9-1340-425a-ae07-959e3665e6b7/2012-12-03_10-54-25.png

Monday, August 13, 2012

Clean-up your Linux /boot partition

My server monitoring by New Relic told me the other day that one of my server's disk drives was full. Upon further inspection it was just the /boot partition, the actual data partition had reached less then 40% capacity. However the /boot partition was filled with old versions of the Linux kernel that hadn't been removed.

Using this great post I was able to remove the 8 older Linux kernels on my Ubuntu 10.04 LTS system.

Monday, July 30, 2012

Adding ANT SCP task support to Mac OS X

My ANT build script for a web application I’m working on is using the SCP task to use a secure shell copy from my local system to the remote server. After upgrading to Mac OS X 10.7 “Lion” and Mac OS X 10.8 “Mountain Lion” I lost my ability to use this task. I found this post comment by a member of the ANT team that pointed out that when Apple compiled the version of ANT in Mac OS X they didn’t include the optional JAR files needed for additional tasks. This means that, for me, the baked in version of ANT is missing ant-jsch.jar

To restore this functionality, first I opened a Terminal prompt (I use iTerm2, then determined the version of ANT installed on my version of Mac OS X by typing ant -version. On Mac OS X 10.8 “Mountain Lion” it reported that I was using Apache Ant(TM) version 1.8.2 compiled on June 20 2012.

Next I downloaded from the Apache ANT website the 1.8.2 binary distribution of ANT located at http://archive.apache.org/dist/ant/binaries/. After the download completed I extracted the archive and found the file ant-jsch.jar that I needed.

To determine the correct path to place this file, I executed ant -diagnostics | grep ant.home to find the path, which for me was ant.home: /usr/share/ant. I then copied the ant-jsch.jar file to the /usr/share/ant/lib directory.

I now needed the actual JSch JAR file that has the tasks. I was able to download the file jsch–0.1.48.jar from http://www.jcraft.com/jsch/index.html. I created a directory to store this in my root by using the mkdir -p ~/.ant/lib command and copying the jsch-0.1.48.jar file to that ~/.ant/lib location.

Now I’m able to use the scp task in my ANT build files, yea!

Without this I would continue to receive the message "Not Available (the implementation class is not present)"

Thursday, July 19, 2012

Unable to start MySQL after upgrade to Ubuntu 12.04 LTS

I recently upgraded one of my Ubuntu servers from 10.04 LTS to 12.04 LTS. During the process it warned me about the servers MySQL configuration file being different then the one provided in the package by the maintainer. I selected to keep mine, with it’s customizations, however after the upgrade I was no longer able to start the MySQL service.

To get the list of MySQL packages that were installed and that I needed to remove, I used the following command:

dpkg –get-selections | grep mysql

I removed the MySQL server using the following command:

sudo apt-get remove libmysqlclient16 libmysqlclient18 mysql-client-core–5.5 mysql-common mysql-server–5.1 mysql-server–5.5 mysql-server-core–5.5

I then restarted the server using the following command:

sudo shutdown -r now

I then installed MySQL once again using the following command:

sudo apt-get install mysql-server mysql-client

However that process terminated with the error dpkg: error processing mysql-server (--configure)

This time I removed the MySQL using the following command:

sudo aptitude purge libmysqlclient16 libmysqlclient18 mysql-client-core–5.5 mysql-common mysql-server–5.1 mysql-server–5.5 mysql-server-core–5.5

Then I renamed the /etc/mysql/ directory and restarted the server using the following command:

sudo mv /etc/mysql/ /etc/mysql.old
sudo shutdown -r now

Once the server restarted I re-installed MySQL, which completed correctly, by using the following command:

sudo apt-get install mysql-server mysql-client

In comparing my old MySQL configuration file and the new configuration file I noted the difference seems to be the addition of the following line under the [mysqld] section:

pid-file = /var/run/mysqld/mysqld.pid

Also, I had to remove the following two lines that I had added to the new MySQL configuration, as the server wouldn’t start with these two settings under the [mysqld]that I used with MySQL 5.1:

default-collation=utf8_unicode_ci
default-character-set=utf8

With those lines above removed or commented out, I was able to successfully start the server and all of my databases were intact and working.

After reviewing the MySQL 5.5 documentation it looks like the server option default-collation was deprecated in MySQL 5.5.3 in favor of collation-server. The same is true of the server option default-character-set being deprecated in MySQL 5.5.3 in favor of character-set-server

Monday, July 02, 2012

Sync Sublime Between Multiple Macs

I’ve been using Sublime Text 2 since way, way back when it was just starting to be developed. I’ve used it since and still love it. It’s light, fast and extensible. However, something that I wanted was the ability to have it in sync between my two Macs. I know, first world problem, but something I wanted a solution to nonetheless. I have an iMac at home and a MacBook Air that I use at the office, when I’m not working remotely from my home office. Using Dropbox I was able to easily accomplish this. Please note that this is for Mac OS X, and should also work on Linux, but probably not on Windows (possible solution here)

Install Sublime Text 2

This should be obvious, but if you haven’t installed Sublime Text 2 already, you’ll want to do this first. You can grab your copy here and I’d encourage you to purchase a license to support the developer.

Install Dropbox

I’m using Dropbox to keep my settings, packages and other supporting files in sync between my two Macs. Now I’m sure you have Dropbox already, but if you’re the 1 person left on the planet that doesn’t, then please use this link so that both you and I receive an extra 500MB free for our accounts.

You’ll want to make sure you have Dropbox installed on all of the Mac’s you’ll want to have your settings in sync.

Setup Sync on First System

Here are the steps I took to setup the sync. I did this on my iMac desktop first, then my MacBook Air second (shouldn’t matter which one you do first, just one at a time). Note that this requires you to use the Mac OS X Terminal, or the excellent iTerm2.

  1. Quit Sublime Text 2 if it’s running
  2. Open the Terminal or iTerm2
  3. Change to your Dropbox folder
    cd ~/Dropbox
    
  4. I recommend creating a new folder for Sublime Text 2 to organize everything. I created one for the Application Support folder and one for the Preferences file. This is what I did, but you can use a different path if you want:
    mkdir -p ~/Dropbox/Applications/Sublime\ Text\ 2/Application\ Support
    mkdir -p ~/Dropbox/Applications/Sublime\ Text\ 2/Preferences
    
  5. Now we move your current Preferences file to the new Dropbox folder
    mv ~/Library/Preferences/com.sublimetext.2.plist ~/Dropbox/Applications/Sublime\ Text\ 2/Preferences/
    mv ~/Library/Preferences/com.sublimetext.2.plist.lockfile ~/Dropbox/Applications/Sublime\ Text\ 2/Preferences/
    
  6. Now we need to create a symlink for each of those files. The symlink will be in the ~/Library/Preferences folder where Sublime Text 2 looks for the Preferences file, and will point to the actual copy that’s stored in your Dropbox folder
    ln -s ~/Dropbox/Applications/Sublime\ Text\ 2/Preferences/com.sublimetext.2.plist ~/Library/Preferences/com.sublimetext.2.plist
    ln -s ~/Dropbox/Applications/Sublime\ Text\ 2/Preferences/com.sublimetext.2.plist.lockfile ~/Library/Preferences/com.sublimetext.2.plist.lockfile
    
  7. As you probably guessed, we need to do the same thing with the Application Support folder, move it then symlink it.
    mv ~/Library/Application\ Support/Sublime\ Text\ 2 ~/Dropbox/Applications/Sublime\ Text\ 2/Application\ Support/
    ln -s ~/Dropbox/Applications/Sublime\ Text\ 2/Application\ Support/Sublime\ Text\ 2 ~/Library/Application\ Support/Sublime\ Text\ 2
    

At this point your first computer should be setup to use the Preferences file and Application Support folder (contains your packages, key-bindings, etc) stored in your Dropbox. Go ahead and launch Sublime Text 2, it should open just like before, nothing should be different.

Setup Sync on Second System

Now go to your second system. Install Dropbox if you haven’t already, At this point it’s important to wait for Dropbox to finish it’s sync. If you haven’t already installed Sublime Text 2, go ahead and do that as well, but don’t launch it.

Now let’s setup this second computer to point to the Dropbox versions of the Preference file and Application Support folder.

  1. Quit Sublime Text 2 if it’s running
  2. Open the Terminal or iTerm2
  3. Change to your Dropbox folder
    cd ~/Dropbox
    
  4. If you’ve run Sublime Text 2 on this second computer before, we’ll rename the current Preference file and Application Support folder so that these are saved, but not used. If you’ve never run Sublime Text 2 on this second computer, skip to the numbered step
    mv ~/Library/Preferences/com.sublimetext.2.plist ~/Library/Preferences/old-com.sublimetext.2.plist
    mv ~/Library/Preferences/com.sublimetext.2.plist.lockfile ~/Library/Preferences/old-com.sublimetext.2.plist.lockfile
    mv ~/Library/Application\ Support/Sublime\ Text\ 2 ~/Library/Application\ Support/Old\ Sublime\ Text\ 2
    
  5. Now let’s setup the symlink for the Preference file
    ln -s ~/Dropbox/Applications/Sublime\ Text\ 2/Preferences/com.sublimetext.2.plist ~/Library/Preferences/com.sublimetext.2.plist
    ln -s ~/Dropbox/Applications/Sublime\ Text\ 2/Preferences/com.sublimetext.2.plist.lockfile ~/Library/Preferences/com.sublimetext.2.plist.lockfile
    
  6. Then the Application Support folder
    ln -s ~/Dropbox/Applications/Sublime\ Text\ 2/Application\ Support/Sublime\ Text\ 2 ~/Library/Application\ Support/Sublime\ Text\ 2
    

At this point you should be able to launch Sublime Text 2 on the second computer and have all of your same Preferences, packages and key-bindings setup and installed. Note that I haven’t run Sublime Text 2 on both computers at the same time, so I can’t comment on what this may or may not do.

Displaying PDF Form Fields Using iText and ColdFusion

One of my most recently developed web application is a new health care system for a number of laborites that perform various testing. The initial workflow has the central office receiving the lab test order and sample, entering it into the system, and then sending the sample and five or six (depending on the test ordered) worksheets along to the lab techs. Currently the worksheets that have to be completed are a variety of MS Excel, MS Word and an Adobe PDF file. This can take anywhere between 3 to 8 minutes to complete, depending on which forms are needed and what information is available on the test order. They asked for an easier way to do this.

I decided to explore generating a single PDF file that would be generated after the test order is entered in the system. The fields on the various documents that normally the administrative staff have to fill in would be populated by the web application. Normally this would be easy to do using cfpdfform, however for this project we’re using Railo instead of Adobe ColdFusion and the cfpdfform tag isn’t available. I was hoping that Railo 4 would include this tag as a feature, but there was no mention of it being included at cf.Objective() 2012 by the Railo team when I asked. I’ve asked on the Railo list twice, initially they said yes but most recently they haven’t responded. Therefore I needed to find an alternative solution, which I did, and here’s what I ended up doing.

Create a single Adobe Acrobat PDF Form

The first step was to use Adobe Acrobat Professional to combine the MS Excel, MS Word and Adobe PDF files into a single PDF file. The next step was to create the form fields within the PDF for the web application to populate from the database. Since every page had a “name” field, we just made that field name the same on each page.

Get iText

iText is a Java component that is designed to work with PDF files. It can create, read and update PDF files. The technical documentation on the website is pretty thin, they really encourage you to buy a copy of their “iText in Action” book. I’d have no problem with this, but they don’t currently offer a Kindle version yet so I’m holding off on that. I did find the API documentation is available online that you can use, and they do have the samples from the book available for download that may help.

Download the iText PDF community version from here. I decompressed these files and placed them in the same directory as I had my Railo JAR files, then I restarted Apache Tomcat. I’m pretty sure I could put these in my ColdFusion on Wheels application directory /lib directory and load them using the javaLoader for CFWheels, but I haven’t tried it yet.

CFDump the form fields

The next thing I wanted to do was to dump the form fields from the PDF file to make sure I was able to read the file correctly. I placed the single PDF file that we had created with all of the form fields with my ColdFusion on Wheels application directory. I then created a CFML page and used the following code to dump the form fields that are found within the entire file.


readPDF = expandpath("the_file_name_here.pdf");
writePDF = expandpath("#createUUID()#.pdf");
fileIO = createObject("java","java.io.FileOutputStream").init(writePDF);
reader = createObject("java","com.itextpdf.text.pdf.PdfReader").init(readPDF);
stamper = createObject("java","com.itextpdf.text.pdf.PdfStamper").init(reader, fileIO);
pdfForm = stamper.getAcroFields();


This dumped out a list of all of the form fields within the PDF so I can make sure that iText was able to read them, and that I spelled them correctly.

Populate the Form Fields

The next step was to populate these fields with data from my database. I also wanted to display this PDF in the users browser. I was able to to this pretty much as I did above, but just with a minor changes.


readPDF = expandpath("the_file_name_here.pdf");
writePDF = expandpath("#createUUID()#.pdf");
fileIO = createObject("java","java.io.FileOutputStream").init(writePDF);
reader = createObject("java","com.itextpdf.text.pdf.PdfReader").init(readPDF);
stamper = createObject("java","com.itextpdf.text.pdf.PdfStamper").init(reader, fileIO);
pdfForm.setField("date_sample_collected", "#date_sample_collected#");
pdfForm.setField("patient_name", "#patient_name#");
pdfForm.setField("date_of_birth", "#date_of_birth#");
pdfForm.setField("order_number", "#order_number#");
stamper.setFormFlattening(true);
stamper.close();
reader.close();
fileIO.close();


Summary

Using this code I was able to satisfy the initial request that the administrative staff, to save them from creating these additional forms manually with the data they had just entered into the web application.

I know I can make this better though, since not every page of that PDF is needed, it depends on the test selected. I plan to re-factor this application code in the future to to determine which test was selected, then only grab those worksheets. This means I’ll need to separate each of the worksheets out into a separate PDF file, then stitch them together, depending on what the user has entered for the order, into a single file.

Thanks To

Thanks to this cfSearching blog post that helped, as well as rip747’s Stackoverflow posting that helped me complete this task.

Sunday, May 13, 2012

Using Legacy MS SQL Server 2008 tables with Ruby on Rails Application

On my first Rails application I’m developing against a legacy MS SQL Server database running on MSSQL R2. When I developed this database back in 2001 I didn’t follow any of the Rails “opinions” in terms of column naming. This makes working with the database somewhat difficult.
I found a presentation from the 2009 Rails Conference entitled “Rails + Legacy Databases” which provided some great tips. One of the suggestions for working with a MSSQL database and tables that don’t match the Rails convention is to use a database view to simulate the table with the Rails naming.
I thought this was pretty slick, but I wasn’t able to get it to work at the outset. I contacted the presentation author Brian Hogan a few times via Twitter and he advised meto make sure of two things to make this work: 1.) Make sure the view is updatable, which is a permission you have to make sure the SQL login account that your Rails app is using to connect has. Here’s the SQL code that I used to create the view with the permissions my Rails login needed:
use [hla]
GO
GRANT DELETE ON [dbo].[States] TO [hlaapprailsuser]
GO
use [hla]
GO
GRANT INSERT ON [dbo].[States] TO [hlaapprailsuser]
GO
use [hla]
GO
GRANT SELECT ON [dbo].[States] TO [hlaapprailsuser]
GO
use [hla]
GO
GRANT UPDATE ON [dbo].[States] TO [hlaapprailsuser]
GO
2.) Make use of the
:foreign_key => "state_id"
parameter on your associations.
This ended up working out really nice and saved me time and headache so I thought I would share in case anyone else finds themselves in a similar circumstance.

Wednesday, April 11, 2012

Installing activerecord-sqlserver-adapter on Mac OS X Lion

I’m on Mac OS X 10.7.3 “Lion” and want to develop a Ruby on Rails 3.2.2 application using a MS SQL Server 2008 database. To do this I needed to install the activerecord-sqlserver-adapter which requires TinyTDS. While the gem install activerecord-sqlserver-adapter worked fine, the gem install tiny_tds failed to compile. It required a freetds component.

This took me a while and I ended up having to install Homebrew to get it to work. Here are the steps I took to get this working, hopefully it’ll save others the hour or so I spent trying to get it working.

  1. Install Homebrew Package Manager by using these instructions
  2. Install the FreeTDS component
    brew install freetds
  3. Install the TinyTDS gem
    gem install tiny_tds -- --with-freetds-include=/usr/local/include --with-freetds-lib=/usr/local/lib --with-iconv-include=/usr/local/Cellar/libiconv/1.14/include --with-iconv-lib=/usr/local/Cellar/libiconv/1.14/lib
  4. Now install the SQL Server ActiveRecord gem
    gem install activerecord-sqlserver-adapter

You’ll need to then setup your database.yml file accordingly:

development:
  adapter: sqlserver
  host: 10.1.1.100
  database: mydb
  usernane: user
  password: s3cr3t