Archive for the 'How-To' Category

Install Red5 + Xuggler on CentOS 5.x

A new project requires using Red5 and Xuggler on a CentOS virtual host.  Unfortunately, setting up both Xuggler and Red5 can be a bear on CentOS, because the default installation doesn’t come with Java.  So, I’ve put together a tutorial that should help you out if you’re trying to setup a Red5 system with Xuggler.

Step 1: Setup Java

CentOS will use the openJDK packages if you try to install java via YUM, but unfortunately, these packages have caused problems for a lot of users trying to install Red5.  I recommend using the Sun binaries, which now seem to work fine for CentOS.  First, you’ll want to download the most current JDK (note: it must be the JDK rather than JRE package) rpm binary package from this site:

$ cd /usr/src
$ wget $long_link_from_java_download_page$

Once its downloaded, make sure the filename looks something like ‘jre-xxxx-linux-i586-rpm.bin‘.  Next, make sure the binary is executable, and run it:

$ chmod a+x jre-6u17-linux-i586-rpm.bin
$ ./jre-6u17-linux-i586-rpm.bin

You’ll get a license agreement page, so hit the space bar until you get to the bottom, and type ‘yes’ to agree. Next, you’ll need to run the resulting rpm package:

$ rpm -i jre-6u17-linux-i586.rpm

Now, confirm that java has been installed correctly to /usr/local by running the ‘java -version’ command:

$ java -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Server VM (build 14.3-b01, mixed mode)
$

If the command runs successfully, you’re all done with Step 1.

Step 2: Get ANT

Apache ANT is a build system commonly used for java projects.  ANT is required by both Red5 and Xuggler, so we’ll go ahead and get it installed.  The setup is pretty easy; first, download and extract the latest ANT binary:

$ cd /usr/src
$ wget http://archive.apache.org/dist/ant/binaries/apache-ant-1.7.1-bin.tar.gz
$ tar -xzf apache-ant-1.7.1-bin.tar.gz
$ mv apache-ant-1.7.1-bin /usr/local/ant

Now, you need to setup the ANT_HOME environment variable:

$ export ANT_HOME=/usr/local/ant
$ export PATH=$PATH:/usr/local/ant/bin

Step 3: Setup Xuggler

The best way to get Xuggler is to download it via the current SVN trunk:

$ cd /usr/src
$ svn checkout http://xuggle.googlecode.com/svn/trunk/java/xuggle-xuggler xuggle-xuggler

Once everything has been checked out (which can take quite a while), move into the xuggle-xuggler directory and set the appropriate environment variables:

$ cd /usr/src/xuggle-xuggler
$ export XUGGLE_HOME=/usr/local
$ export PATH=$XUGGLE_HOME/bin:$PATH
$ export LD_LIBRARY_PATH=$XUGGLE_HOME/lib:$LD_LIBRARY_PATH

Next, begin the build by running:

$ ant run-tests

This will make all the native and java binaries and then run the appropriate unit tests on each. This can take a while (10 minutes on my server), so be patient. Ideally, all the tests should pass, but sometimes I’ve had certain MP3 tests fail. If you don’t plan on using the MP3 transcoding features of Xuggler, you can ignore these errors.  Next, install Xuggler:

$ sudo ant install

If everything went well, you should see a bunch of print outs indicating a successful install.

Step 4: Install Red5

Like Xuggler, the best place to get Red5 is the current SVN trunk:

$ cd /usr/local
$ svn checkout http://red5.googlecode.com/svn/java/server/trunk/ red5

Next, use ANT to build and install Red5:

$ ant prepare
$ ant dist
$ cp -r dist/conf .

If everything went well, Red5 should be installed and configured. You can test your install by starting the server:

$ ./red5.sh

and visiting ‘http://yourserveraddres:5080/‘.  If you get the screenshot below, you are good to go with Red5.

red5Step 5: Copy Xuggler to Red5

For Red5 to use the Xuggler library, you have to copy a compiled Jar to the red5/lib directory:

$ cp /usr/src/xuggle-xuggler/dist/lib/xuggle-xuggler.jar /usr/local/red5/lib

And with that, you should be all set to go! Just copy your Red5 app into the webapps directory and you’re ready to do some cool stuff with video.

Getting Notes to Sync in Mail from iPhone OS 3.0

One feature I am really excited about in the new iPhone 3.0 OS released on Wednesday is the ability to sync your notes with the Mail application in Leopard.  However, it took me a few tries to figure out how to get this to work exactly.  I realized that I ran into this problem because I had never created a note on my Mac in Mail, so this walkthrough assumes you are in the same position.  I’ve outlined the steps below:

  1. Enable Notes syncing in iTunes.  You can do this by going to the ‘Info’ tab when you have your iPhone/iPod attached to your computer.  Check the ‘Sync Notes’ checkbox about halfway down the page.notes-itunes
  2. If you go ahead sync your iPhone now, and you’ll notice that none of the Notes show up in mail.  If you have multiple mailboxes, they’ll be listed under the ‘Reminders’ heading in the Mail sidebar, with little note icons, but you won’t see any from your iPhone.  What you have to do is create a note in Mail now, by going to File > New Note.  Type something in and save it, and you’ll see a new note icon under ‘Reminders/Notes’ labeled ‘On My Mac’.  mailboxes
  3. Sync your iPhone one more time.  After its completed, you should see all your notes under the ‘On My Mac’.

Creating a Ruby Gem

Ruby Gems are a the most common mechanism for extending the functionality of the Ruby language through plug-ins.  Similar to CPAN or PEAR, the Gem infrastructure allows users to download additional libraries from a central online repository and install it locally.  All you need to do is start a project at rubyforge.org, upload your finished Gem, and it will automatically appear in the central gem listing. As I was researching the steps for creating a gem, it was pretty clear that there wasn’t much of a comprehensive guide out there for beginners.  I’m hoping this article will help out those who are interested in creating gems, and save you some time as well.

Background
Building a Gem is actually pretty straightforward.  A gem is basically just a package of ruby code that has been assembled using the ‘gem build’ command.  If you’ve developed debian packages or RPMs, you are already familiar with this concept.  Essentially, the gem builder assembles the package, compresses it, and adds some metadata to help with the organization and installation of  your code onto any computer.

Getting Started
To create a gem, you’ll need some code (which I’m assuming you’ve already developed as a module), a pretty basic folder structure and a gemspec file.  First, lets take a look at a folder structure:

booksearch/
  README
  demo.rb
  lib/
    booksearch.rb
    booksearch/
      base.rb
      search.rb
  test/
    unit.rb

The folder structure above is for a gem called BookSearch.  Under the root directory, there is a README file, a demo.rb file and two directories, lib/ and test/.  The test/ directory contains a unit test file to verify the gem, and the lib/ directory is where all the code for the library is stored.  Directly in the lib/ directory is a file called booksearch.rb which is the file that is run when calling ‘require’ to load the gem.  All this file needs to do is load/require the correct files under the lib/booksearch/ directory.  Obviously then, the booksearch/ directory contains the actual code for the gem.  In the example above, there is the base.rb and search.rb files.  You can, of course, add other files and change the directory structure to suit your needs, but every gem will have a structure basically similar to this.

The Gemspec File
The core of the gem build process is the gemspec file.  This files contains all the metadata about the packaged gem, in additional to basic build instructions, similar to a configuration file.  Below is the gemspec file for my BookSearch gem:

Gem::Specification.new do |s|
   s.name = %q{booksearch}
   s.version = "0.1.0"
   s.date = %q{2009-06-02}
   s.authors = ["Mike Reich"]
   s.email = %q{mike@seabourneconsulting.com}
   s.summary = %q{A full featured Book Search API}
   s.homepage = %q{http://xxx.rubyforge.org/}
   s.description = %q{A full featured Book Search API}
   s.files = ["lib/booksearch.rb", "lib/booksearch/base.rb", "lib/booksearch/search.rb", "test/unit.rg", "demo.rb" "README"]
   s.rubyforge_project = 'booksearch'
   s.has_rdoc = true
   s.test_files = ['test/unit.rb']
end

There are a few key elements worth mentioning.  The ‘has_rdoc’ setting will alert Gem to the fact that your source code is commented to support RDoc documentation.  When a user installs your gem, RDoc will then be run on the source automatically to generate the documentation.  The ‘test_files’ setting is an array that should point to your unit test files, so that a user can choose to run the unit tests associated with your project through the gem command line tool.  You can see all the possible values of a gemspec file in the documentation.

Building Your Gem
Building a gem is a one step process.  You’ll want to place the gemspec file in the root directory of your gem, and then enter the command

gem build booksearch.gemspec

where ‘booksearch’ is the name of your gem.  The output of that command will be the fully constructed gem that you can install with the command

sudo gem install booksearch-0.1.0.gem

At this point, you can choose to distribute your gem any number of ways.

Conclusions
Overall, creating a Ruby Gem is much less complicated that creating a Debian package or RPM package.  The tools are well documented and clean, and the resulting package can be a powerful way to distribute your code to the world.

VMWare Server 1.0x on Kubuntu 9.04

VMware Inc.
Image via Wikipedia

I just updated my Hardy Kubuntu system to Jaunty 9.04 – everything went pretty smooth, except for getting my VMWare server installation to work again.   For various reasons, I use VMWare server 1.0 (mostly because I need to boot a windows partition which is not supported under VMWare server 2, plus the web interface sucks).  So, I was able to do the system update fine, and the first time I tried to start VMWare, it figured out there was a new kernel version and asked to recompile all the modules.  The configuration process went fine, but when I wen to start vmware, I would get the following error:

/usr/lib/vmware/bin/vmware: symbol lookup error: /usr/lib/libgio-2.0.so.0: undefined symbol: g_thread_gettime

Really annoying!  So, after some googling, came across a few Ubuntu forum threads where peopel were running into the same error, except they were running 8.10 64 bit systems.  Figured their fix was worth a shot, and lo-and-behold, it worked.  Here’s the process I followed:

Step 1: Download the latest 1.09 version
You can find it here.  Download and run the install script.  However, when it asks you to run the configuration, select ‘no’.  The installer will then quit.

Step 2: Download and install kernel patch
You can find the patch here.  Now, un-tar and run the installer script ‘runme.pl’ as sudo.  Now, when the patch asks you to run the configuration for VMWare server, select ‘yes’ and continue.  The configuration script should compile and install all the modules (though I ran into quite a few warnings).  Now, if you tried to run VMWare, you’d still get the ‘g_thread_gettime’ error, so, you need to start VMWare in a special way.

Step 3: Start VMWare
Now, to finally get everything running, you’ll need to run this command:

VMWARE_USE_SHIPPED_GTK="force" vmware

This will tell VMWare to use the correct version of the GIO lib and thus will get you running with no problems.

Update: Step 4
The final step, which I discovered after a few days, is to reset the defaul keyboard mapping for VMWare.  You’ll need to do this if you notice your arrow or function keys are not responding correctly.  To fix this, simply enter the following command into the terminal:

echo xkeymap.nokeycodeMap = true > ~/.vmware/config

Creating Public Calendars with Google Calendar API

Update: I’ve got a new Ruby Gem that improves upon the functionality described below.  Check it out here.

In my previous post I covered how to create and manage google calendars using the Google Calendar API and Ruby on Rails.  One feature I really wanted in order to make my project really user friendly was the ability to make a newly created calendar public without having to log in to the Google Calendar website and make the permissions change manually.  Unfortunately, the documentation for how to do this is sparse at best.

Background
The key to making a public calendar lies in the Google Calendar Access Control Lists (ACL).  Like all other parts of the API, this is simply an Atom RSS feed that you can POST or GET from.  Essentially, ACLs allow you to specify the major permissions for each user that is added to a calendar.  The first problem I ran into was trying to figure out the correct url to POST to.  The google documentation only lists how to change the ACL for a specific user (and by default their primary calendar) rather than for a secondary calendar.  With a little sluething, I was able find a forum post that gives the calendar url:

"http://www.google.com/calendar/feeds/#{cal_id}/acl/full"

Where ‘cal_id’ is the unique calendar id.

To change a permission, you post a new rule to the feed above.  For example, to add a user with basic read permissions, you would POST the following code the to ACL feed url:

<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'/>
  <gAcl:scope type='user' value='darcy@gmail.com'></gAcl:scope>
  <gAcl:role
    value='http://schemas.google.com/gCal/2005#read'>
  </gAcl:role>
</entry>

The code above is pretty straightforward, and the google documentation gives a nice overview of what each part of the XML represents. However, I don’t want to add specific users to my calendars – rather I want to make them public to everyone by default.

After looking more at the documentation and at some forum posts, I figured out that instead of specifying a user, you can set the ’scope’ type to ‘default’ and omit the value attribute.  The role value can then be ‘read’ to allow for read only access to the public.  Therefore, the XML to create a public calendar looks like this:

<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'/>
  <gAcl:scope type='default'></gAcl:scope>
  <gAcl:role
    value='http://schemas.google.com/gCal/2005#read'>
  </gAcl:role>
</entry>

Extend GCalAPI
The code for adding this to the GCapAPI code, as I did in my previous post, is as follows:

class GoogleCalendar::ServiceBase
  def make_calendar_public(cal_id)
    #change permissions on the calendar to public
    path = "http://www.google.com/calendar/feeds/#{cal_id}/acl/full"
    request = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>
                    <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/acl/2007#accessRule'/>
                     <gAcl:scope type='default'></gAcl:scope>
                     <gAcl:role value='http://schemas.google.com/gCal/2005#read'></gAcl:role>
                  </entry>"
    uri = URI.parse(path)
    res = do_post(uri, {"Content-Type" => "application/atom+xml", "Content-Length" => request.length.to_s}, request)
    if res.code.to_i != 201
      raise "Could not change permissions on calendar: "+res.body
    end
  end
end

You can now add the ‘make_calendar_public’ function call wherever you need, passing the relevant calendar id.

Super Basic CAPTCHA with Joomla and PHP

A website I’m developing that has a fairly complex form has suddenly started getting a ton of spam (about 200 spam posts per hour).  The client needed a CAPTCHA system super quick, so I had to get something temporary up ASAP.  There are very good image CAPTCHA generator services out there, but I didn’t have time to integrate in the third party image and test everything.  So, I came up with the approach outlined below – for a low traffic site, and as a temporary solution, this works great

Note: this is by no means a secure CAPTCHA system, and should not be used with the expectation that it is bulletproof (quite the opposite, but it would take at least some human intervention to figure out how to beat it, which is perfect for a low traffic site).

Premise

A CAPTCHA works by presenting a user with a hard to decipher (for a machine) image containing a random string.  The user then has to enter the text string in a form box.  If the string matches the image, then the user is assumed to be authentic (at least not a bot) and the form is successfully submitted.  If the string doens’t match the image, then the form is rejected.

Programmatically, there are a few features to note.  First, you need to have an electronic version of the string in the image to compare the user’s text to.  This can be done two ways, depending on where you want your validation to occur.

  1. Server Side Validation: this is probably the most common, as it integrates well with 3rd part CAPTCHA systems and is the most secure.  In this case, you generate a random string and a secret key.  You then generate an image based on the secret key and the random string.  You then take the user’s text string, combine it with the key, and if the value matches the original, then the CAPTCHA is passed.
  2. If you want to do client side validation, you can take an AJAX approach to the previous method, or you can add the CAPTCHA to a javascript form validator.  In this case, you don’t want a secret key or the text string on your page, so you can use a MD5 or SHA hash of the string.  This way, you can include it in the validation javascript without fear of any secrets being given away.  The validation function simply compares the hash of the user’s input with the hash in the function and if they match, the CAPTCHA passes.

Since I’m already using a javascript form validator in my website, and I was really crunched on time, I decided to go with approach 2.  So, here’s a step by step guide for building a super quick, functional, though not particularly secure CAPTCHA system.  A little background: I’m using Joomla 1.5 to build the website and the form, so the examples include some Joomla specific code.

Implementation

  1. Get your CAPTCHA images.  You’ll need 5 to 10 premade CAPTCHA images.  You can either create them yourself or find them on the web,  but be mindful of copyright issues in using someone else’s.  Number the images ‘Captcha-0′, ‘Captcha-1′, etc.
  2. Generate an MD5 hash of each CAPTCHA’s text.  Write it down and note the number of in the image name of the CAPTCHA photo for each one.
  3. In your PHP file, add an array containing all the hashes, in the order that the images are in:
    $captcha = array("ca608814f1afdbc3ce97b00baf6e3545",
                     "c900ea6ac5e2beca0c23a45c2b779fbf",
                     "39437118c696911d4c58c686a9cfd3d0",
                     "4f5767844def01697cb2bb0e175d5500",
                     "8a2e4dd82d392386031ac56f8026f4da");
    
  4. Next, user the rand() function to generate a random number based on your array size:
    $num = rand(0, (count($captcha)-1));
    
  5. Add the corresponding MD5 hash (by referencing the correct position in the hash array) to your validation function.  In this case, I’m using the built in validator for Mootools 1.1 and Joomla:
    <script type="text/javascript">
    
    Window.onDomReady(function() {
            document.formvalidator.setHandler('captcha', function(value) {
                    if (MD5(value) == '<?php echo $captcha[$num]; ?>') {
                            return true;
                    } else {
                            return false;
                    }
            });
    });
    </script>
    
  6. Add the image to your form by matching the image number with the random number:
    <img src="/media/system/images/Captcha-<?php echo $num; ?>.jpeg"/>
    

And that’s it – now you have a very basic CAPTCHA system implemented.  As long as a user types the correct text in the text box you create, the form will submit.  Otherwise an error is returned to the user.  Of course, the effectiveness of this goes up the more images and hashes you have, but unless you have someone putting at least some effort into beating this, it should keep the random bot from posting on your website’s form.