<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>charlie on software</title>
	
	<link>http://charliemeyer.net/blog</link>
	<description>yes, i ripped it off of joel</description>
	<lastBuildDate>Wed, 19 Dec 2012 16:10:18 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5</generator>
	<copyright>Copyright © charlie on software 2012 </copyright>
	<managingEditor>charlie@charliemeyer.net (charlie on software)</managingEditor>
	<webMaster>charlie@charliemeyer.net (charlie on software)</webMaster>
	<image>
		<url>http://charliemeyer.net/blog/wp-content/plugins/podpress/images/powered_by_podpress.jpg</url>
		<title>charlie on software</title>
		<link>http://charliemeyer.net/blog</link>
		<width>144</width>
		<height>144</height>
	</image>
	<itunes:subtitle />
	<itunes:summary>yes, i ripped it off of joel</itunes:summary>
	<itunes:keywords />
	<itunes:category text="Society &amp; Culture" />
	<itunes:author>charlie on software</itunes:author>
	<itunes:owner>
		<itunes:name>charlie on software</itunes:name>
		<itunes:email>charlie@charliemeyer.net</itunes:email>
	</itunes:owner>
	<itunes:block>no</itunes:block>
	<itunes:explicit>no</itunes:explicit>
	<itunes:image href="http://charliemeyer.net/blog/wp-content/plugins/podpress/images/powered_by_podpress_large.jpg" />
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/CharlieOnSoftware" /><feedburner:info uri="charlieonsoftware" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Pidgin-closeoffline: a plugin for Pidgin to close offline conversation tabs</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/3V0Jg0QJdT4/</link>
		<comments>http://charliemeyer.net/blog/2012/12/pidgin-closeoffline-a-plugin-for-pidgin-to-close-offline-conversation-tabs/#comments</comments>
		<pubDate>Wed, 19 Dec 2012 16:09:00 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[libpurple]]></category>
		<category><![CDATA[Pidgin]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=278</guid>
		<description><![CDATA[I recently took some time to learn some of the inner workings of Pidgin and libpurple, and along the way I decided to write a plugin that would provide a feature that I was really missing from native Pidgin. There are often times where I would have my Pidgin open for days at a time, [...]]]></description>
				<content:encoded><![CDATA[<p>I recently took some time to learn some of the inner workings of Pidgin and libpurple, and along the way I decided to write a plugin that would provide a feature that I was really missing from native Pidgin. There are often times where I would have my Pidgin open for days at a time, and would accumulate huge numbers of conversation tabs open, with many of those chat partners signed offline. I didn&#8217;t want to close all the tabs, only the offline buddies, and I didn&#8217;t see a way to do this in Pidgin. So I took a dive into the APIs for Pidgin and libpurple and came up with this little plugin that adds an item to the right click context menu of the tab bar in a conversation window that will close all offline buddies. Right now, I have only tested it working on Ubuntu 12.04.1 32 bit and 64 bit, but I assume it would work other places too. To install the plugin, first download it from:</p>
<p><a href="https://github.com/cemeyer2/pidgin-closeoffline/archive/master.zip" target="_blank">https://github.com/cemeyer2/pidgin-closeoffline/archive/master.zip</a></p>
<p>Extract that folder, then open a terminal in that directory and run:</p>
<pre class="brush: shell; gutter: false; first-line: 1"># ./install_ubuntu.sh</pre>
<p>This should take care of setting up all the dependencies, compiling the plugin, and then installing it to the local user&#8217;s plugin directory.</p>
<p>If you care to browse the source code, its available in the downloaded zip file as well as in the github repository at: <a href="https://github.com/cemeyer2/pidgin-closeoffline" target="_blank">https://github.com/cemeyer2/pidgin-closeoffline</a></p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/12/pidgin-closeoffline-a-plugin-for-pidgin-to-close-offline-conversation-tabs/" data-text="Pidgin-closeoffline: a plugin for Pidgin to close offline conversation tabs" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/12/pidgin-closeoffline-a-plugin-for-pidgin-to-close-offline-conversation-tabs/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F12%2Fpidgin-closeoffline-a-plugin-for-pidgin-to-close-offline-conversation-tabs%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/12/pidgin-closeoffline-a-plugin-for-pidgin-to-close-offline-conversation-tabs/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/3V0Jg0QJdT4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/12/pidgin-closeoffline-a-plugin-for-pidgin-to-close-offline-conversation-tabs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/12/pidgin-closeoffline-a-plugin-for-pidgin-to-close-offline-conversation-tabs/</feedburner:origLink></item>
		<item>
		<title>Email to SMS gateway solution for Google Voice users</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/Bka2-oq9rC8/</link>
		<comments>http://charliemeyer.net/blog/2012/12/email-to-sms-gateway-solution-for-google-voice-users/#comments</comments>
		<pubDate>Wed, 05 Dec 2012 14:00:28 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[gateway]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[google voice]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[sms]]></category>
		<category><![CDATA[SMS to email]]></category>
		<category><![CDATA[voice]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=264</guid>
		<description><![CDATA[I&#8217;m a loyal Sprint PCS cell phone subscriber. Not only is their price/feature ratio right, but they offer outstanding integration with Google Voice that is unmatched by any other national cell phone carrier. With almost all cell phone carriers, they offer an email to SMS gateway solution, wherein anyone can send an email with a [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m a loyal Sprint PCS cell phone subscriber. Not only is their price/feature ratio right, but they offer outstanding integration with Google Voice that is unmatched by any other national cell phone carrier.</p>
<p>With almost all cell phone carriers, they offer an email to SMS gateway solution, wherein anyone can send an email with a short message in it to a specific address and it will be converted by the carrier into a text message and sent to your phone. For Sprint, the form is:</p>
<p>10digitnumber@messaging.sprintpcs.com</p>
<p>This is all fine and dandy, except that if you opt in for the enhanced Google Voice integration, that email to SMS gateway no longer will function for your number. There is a common solution posted on the Internet for this problem:</p>
<p>Have Google Voice forward text messages to your GMail account. From Google Voice, send a text message to yourself and wait for it to show up in your inbox. Look at that email and use the from address there as the address to send email to to send SMS to your phone. The problem with this is that Google generates a unique from address for each email it sends out as a text, which ties that from address to a specific recipient, so that threaded conversation can be maintained in Google Voice. Aka, you can save that specific from address and use it from your local GMail account to email texts to yourself, but if you give that email address to someone else, the emails from them will not go through to your phone.</p>
<p>I required a more robust solution, where I could provide a single email address to multiple outside people/services that would act as a gateway into a text message sent to my phone.  Here is my solution:</p>
<p>Requirements:</p>
<ul>
<li>a machine that continually is up and runs python</li>
<li>a dummy GMail account</li>
<li>a dummy Google Voice account (optional, may be hard to get if you don&#8217;t have an extra phone number to tie it to)</li>
<li>pygooglevoice installed on the server machine (either in a virtualenv or system wide), patched as shown on https://code.google.com/p/pygooglevoice/issues/detail?id=58#c24</li>
<li>python-daemon installed on the server machine (either in a virtualenv or system wide)</li>
</ul>
<p>Here is the setup:</p>
<p>Run a python daemon on a machine that monitors the dummy GMail inbox periodically for new mail. When it finds on, it downloads the message, parses out the body text, logs into a Google Voice account, and texts the body of the message to your cell phone. Seem simple enough?</p>
<p>Here is the code for the daemon that I wrote:</p>
<pre class="brush: python; gutter: false; first-line: 1">'''
Created on Dec 4, 2012

Simple Python daemon that acts as a proxy to forward
emails to a cell phone (for me, my google voice number)

@author: Charlie Meyer &lt;charlie@charliemeyer.net&gt;
'''

import imaplib
import email
from googlevoice import Voice
import logging
import time
from daemon import runner

logger = logging.getLogger("SMSDaemon")
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.FileHandler("/var/log/SMSDaemon.log")
handler.setFormatter(formatter)
logger.addHandler(handler)

class EmailReceiver:

    def __init__(self):
        logger.debug("Email Init")
        self.username = "yoursmsdummyaccount@gmail.com" #edit this
        self.password = "smsdummyaccountpassword" #edit this
        self.server = "imap.gmail.com"
        self.port = 993
        self.M = None
        self.response = None

    def login(self):
        logger.debug("IMAP Login")
        self.M = imaplib.IMAP4_SSL(self.server, self.port)
        rc, self.response = self.M.login(self.username, self.password)
        logger.info(self.response)
        logger.debug("IMAP Login complete")
        return rc

    def logout(self):
        logger.debug("IMAP logout")
        self.M.logout()
        logger.debug("Logged out")

    def get_messages(self):
        logger.debug("Getting unread mail")
        self.M.select("INBOX")
        logger.debug("Getting unread count")
        status, response = self.M.status('INBOX', "(UNSEEN)")
        logger.debug("rc="+str(status))
        unreadcount = int(response[0].split()[2].strip(').,]'))
        if unreadcount &gt; 0:
            logger.info("There are "+str(unreadcount)+" unread messages")
        logger.debug("Getting unread mail")
        status, email_ids = self.M.search(None, '(UNSEEN)')
        logger.debug("rc="+str(status))
        messages = []
        for e_id in email_ids[0].split():
            logger.info("Fetching message id="+str(e_id))
            rc, data = self.M.FETCH(e_id, '(RFC822)')
            logger.debug("Fetch complete, rc="+str(rc))
            mail = email.message_from_string(data[0][1])
            for part in mail.walk():
                if part.get_content_maintype() == 'multipart':
                    continue
                if part.get_content_subtype() != 'plain':
                    continue
                payload = part.get_payload()
                logger.info("message: "+str(payload))
                messages.append(payload)
        logger.debug("Mail fetch complete")
        return messages

class SMSSender:

    def __init__(self):
        logger.debug("SMS init")
        self.username = "dummygvoice@gmail.com" #edit this to be either your gvoice account or your dummy one if you have one
        self.password = "password" #edit this
        self.to = "your10digitphonenumber" #edit this
        self.voice = None

    def login(self):
        logger.info("SMS Login")
        self.voice = Voice()
        self.voice.login(self.username, self.password)
        logger.info("SMS Login complete")

    def logout(self):
        logger.info("SMS Logout")
        self.voice.logout()
        logger.info("SMS Logout complete")

    def send_sms(self, message):
        logger.info("Sending message: "+str(message))
        self.voice.send_sms(self.to, message)
        logger.info("Message sent")

class SMSDaemon():

    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path =  '/var/run/smsdaemon.pid'
        self.pidfile_timeout = 5

    def run(self):
        while True:
            logger.info("Daemon looping")
            g = EmailReceiver()
            g.login()
            messages = g.get_messages()
            if len(messages) &gt; 0:
                sms = SMSSender()
                sms.login()
                for message in messages:
                    sms.send_sms(message)
                sms.logout()
            g.logout()
            logger.debug("Daemon Sleeping")
            time.sleep(60)

daemon = SMSDaemon()
daemon_runner = runner.DaemonRunner(daemon)
daemon_runner.daemon_context.files_preserve=[handler.stream]
daemon_runner.do_action()</pre>
<p>I saved that file in /root/smsdaemon/SMSDaemon.py</p>
<p>I then tested it using:</p>
<p>python SMSDaemon.py start</p>
<p>and sent an email to my dummy gmail account and ensured it arrived as a text message on my phone. The program will log to /var/log/SMSDaemon.log, so you can look there to ensure it is working. Once that works, time to write the init script so it loads on boot.</p>
<p>First, ensure the daemon is stopped:</p>
<p>python SMSDaemon.py stop</p>
<p>Then, add the following to /etc/init.d/smsdaemon</p>
<pre class="brush: shell; gutter: false; first-line: 1">#!/bin/bash
#
# /etc/init.d/smsdaemon
#
### BEGIN INIT INFO
# Provides: smsdaemon
# Required-Start:
# Should-Start:
# Required-Stop:
# Should-Stop:
# Default-Start:  3 5
# Default-Stop:   0 1 2 6
# Short-Description: SMSDaemon process
# Description:    Runs up the SMSDaemon process
### END INIT INFO

# modified from http://www.gavinj.net/2012/06/building-python-daemon-process.html

# uncomment and edit the following line if needed to activate the python virtual environment
# . /path_to_virtualenv/activate

case "$1" in
  start)
    echo "Starting"
    python /root/smsdaemon/SMSDaemon.py start
    ;;
  stop)
    echo "Stopping"
    python /root/smsdaemon/SMSDaemon.py stop
    ;;
  restart)
    echo "Restarting"
    python /root/smsdaemon/SMSDaemon.py restart
    ;;
  *)
    echo "Usage: /etc/init.d/smsdaemon {start|stop|restart}"
    exit 1
    ;;
esac

exit 0</pre>
<p>Now:</p>
<pre class="brush: shell; gutter: false; first-line: 1">sudo chmod +x /etc/init.d/smsdaemon
sudo update-rc.d smsdaemon defaults
sudo service smsdaemon start</pre>
<p>There you go, all done!</p>
<p>Let me know if this works for you or if you have any comments, I might be looking to port this solution to a compute cloud like the Google App Engine or similar in the future.</p>
<p>ymmv</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/12/email-to-sms-gateway-solution-for-google-voice-users/" data-text="Email to SMS gateway solution for Google Voice users" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/12/email-to-sms-gateway-solution-for-google-voice-users/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F12%2Femail-to-sms-gateway-solution-for-google-voice-users%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/12/email-to-sms-gateway-solution-for-google-voice-users/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/Bka2-oq9rC8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/12/email-to-sms-gateway-solution-for-google-voice-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/12/email-to-sms-gateway-solution-for-google-voice-users/</feedburner:origLink></item>
		<item>
		<title>Automapping channel numbers to TiVo commands from the Ubuntu command line</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/kYDDroVtTUs/</link>
		<comments>http://charliemeyer.net/blog/2012/12/automapping-channel-numbers-to-tivo-commands-from-the-ubuntu-command-line/#comments</comments>
		<pubDate>Wed, 05 Dec 2012 05:43:23 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[IR]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[remote]]></category>
		<category><![CDATA[remote control]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[TiVo]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=271</guid>
		<description><![CDATA[In a previous post, I described how to control your TiVo from the Linux command line. I wanted to take it a bit further and make it easier to enter numeric IR codes to my TiVo. With some pointers from Alex Lambert, I came up with a solution that works on my Ubuntu 12.04 laptop. [...]]]></description>
				<content:encoded><![CDATA[<p>In a <a title="Remote control of a TiVo from the Linux command line" href="http://charliemeyer.net/blog/2012/12/remote-control-of-a-tivo-from-the-linux-command-line/" target="_blank">previous post</a>, I described how to control your TiVo from the Linux command line. I wanted to take it a bit further and make it easier to enter numeric IR codes to my TiVo. With some pointers from Alex Lambert, I came up with a solution that works on my Ubuntu 12.04 laptop.</p>
<p>I am assuming you followed the instructions in the previous post and have created the following symlinks:</p>
<pre class="brush: shell; gutter: false; first-line: 1">lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:24 NUM0 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:24 NUM1 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:24 NUM2 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:24 NUM3 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:24 NUM4 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:24 NUM5 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:24 NUM6 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:24 NUM7 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:25 NUM8 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:25 NUM9 -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 23:32 ENTER -&gt; tivoircode</pre>
<p>Now, the goal here is that simply entering the command such as &#8220;1695&#8243; will send the sequence NUM1;NUM6;NUM9;NUM5 to the TiVo. This can be accomplished using the same facility that Ubuntu uses to suggest packages to install when you issue a command from a package that is not currently installed. To do this, add the following to your ~/.bashrc:</p>
<pre class="brush: shell; gutter: false; first-line: 1">function is_integer() {
    s=$(echo $1 | tr -d 0-9)
    if [ -z "$s" ]; then
        return 0
    else
        return 1
    fi
}

command_not_found_handle() {
        if is_integer $1; then
                for NUM in `echo $1 | fold -w1`
                do
                        NUM$NUM
                done
#               ENTER
        else
                if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
                if [ -x /usr/lib/command-not-found ]; then
                   /usr/bin/python /usr/lib/command-not-found -- "$1"
                   return $?
                elif [ -x /usr/share/command-not-found/command-not-found ]; then
                   /usr/bin/python /usr/share/command-not-found/command-not-found -- "$1"
                   return $?
                else
                   printf "%s: command not found\n" "$1" &gt;&amp;2
                   return 127
                fi
                fi

        fi
}</pre>
<p>Now, when you enter an numeric integer value on your bash session, it will send it to your TiVo as a series of IR codes for each digit in the number. You can uncomment the final ENTER command if you wish for the enter button to be pressed when a number is finished being entered on the TiVo, but that is up to you. This function copies the body of the command_not_found_handle default function from /etc/bash.bashrc that ships with Ubuntu, so that non-integer commands are sent through the old mechanism and no functionality is lost.</p>
<p>Happy TiVo&#8217;ing</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/12/automapping-channel-numbers-to-tivo-commands-from-the-ubuntu-command-line/" data-text="Automapping channel numbers to TiVo commands from the Ubuntu command line" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/12/automapping-channel-numbers-to-tivo-commands-from-the-ubuntu-command-line/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F12%2Fautomapping-channel-numbers-to-tivo-commands-from-the-ubuntu-command-line%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/12/automapping-channel-numbers-to-tivo-commands-from-the-ubuntu-command-line/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/kYDDroVtTUs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/12/automapping-channel-numbers-to-tivo-commands-from-the-ubuntu-command-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/12/automapping-channel-numbers-to-tivo-commands-from-the-ubuntu-command-line/</feedburner:origLink></item>
		<item>
		<title>Remote control of a TiVo from the Linux command line</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/3Wxz9Ss3hEQ/</link>
		<comments>http://charliemeyer.net/blog/2012/12/remote-control-of-a-tivo-from-the-linux-command-line/#comments</comments>
		<pubDate>Wed, 05 Dec 2012 00:46:14 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[remote]]></category>
		<category><![CDATA[remote control]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[TiVo]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=260</guid>
		<description><![CDATA[I&#8217;m a huge fan of TiVo brand DVRs, so much so that I own two of them for myself. That being said,  most of the time that I am watching TV, I also have my laptop open with me. Since I run Linux on my laptops, I knew there had to be a way to [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m a huge fan of TiVo brand DVRs, so much so that I own two of them for myself. That being said,  most of the time that I am watching TV, I also have my laptop open with me. Since I run Linux on my laptops, I knew there had to be a way to write a set of shell scripts to allow me to use my always open terminal to easily manipulate my TiVo.</p>
<p>This is the solution that I came up with:</p>
<p>Assume that ~/bin is on your PATH</p>
<p>Create ~/bin/tivoircode with the following contents:</p>
<pre class="brush: python; gutter: true; first-line: 1">#!/usr/bin/env python

#simple python script to send remote IR commands to a TiVo DVR
#this script should never be called directly, but rather via
#symbolic links to it
#
#Written by Charlie Meyer &lt;charlie@charliemeyer.net&gt;
#December 2012

import socket
import sys
import time
import os.path

#set this to the ip address of the tivo to control
tivo_address = "192.168.1.101"

sock = None

def connect():
    global sock
    global tivo_address
    try:
        sock = socket.socket()
        sock.settimeout(5)
        sock.connect((tivo_address, 31339))
        sock.settimeout(None)
    except Exception, msg:
        print msg

def disconnect():
    global sock
    sock.close()

def send_code(code):
    if not sock:
        connect()
    try:
        sock.sendall("IRCODE "+code+"\r")
        time.sleep(0.1)
    except Exception, msg:
        print msg

times = 1;
if(len(sys.argv) &gt; 1):
    times = int(sys.argv[1])

for i in range(0,times):
    send_code(os.path.basename(sys.argv[0]))

disconnect()</pre>
<p>This is the base script from which all others will inherit. Obviously you will need to change the variable at the top of the file to point to the IP address of the TiVo which you want to control.</p>
<p>Now, here comes the fun part. There are a series of symbolic links that need to be made. The name of the link is the raw IR code that is sent to the TiVo, and they all link back to the master script we just created. I have not added all of the remote functions to my environment, but rather only the ones that I regularly use:</p>
<pre class="brush: bash; gutter: true; first-line: 1">lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:48 CLEAR -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:50 PAUSE -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:51 REPLAY -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:51 RIGHT -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:52 LEFT -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:52 UP -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:52 DOWN -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:54 PLAY -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:54 INFO -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:55 SELECT -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 21:56 ADVANCE -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 22:02 TIVO -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 22:03 WINDOW -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 22:04 CHANNELUP -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 22:04 CHANNELDOWN -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 22:04 THUMBSDOWN -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  3 22:04 THUMBSUP -&gt; tivoircode
lrwxrwxrwx 1 chuck chuck   10 Dec  4 18:04 GUIDE -&gt; tivoircode</pre>
<p>To create each one of these, use the ln command, such as:</p>
<p>ln -s tivoircode PLAY</p>
<p>to link PLAY to tivoircode</p>
<p>You should now be able to use the command PLAY in your terminal to cause the TiVo to emulate a regular infrared remote control pressing the play button.</p>
<p>Based on research done online, the following IRCODE commands can be symlinked to my tivoricode script and work properly (should be self-explanatory):</p>
<pre>UP
DOWN
LEFT
RIGHT
SELECT
TIVO
LIVETV
THUMBSUP
THUMBSDOWN
CHANNELUP
CHANNELDOWN
RECORD
DISPLAY
DIRECTV
NUM0
NUM1
NUM2
NUM3
NUM4
NUM5
NUM6
NUM7
NUM8
NUM9
ENTER
CLEAR
PLAY
PAUSE
SLOW
FORWARD
REVERSE
STANDBY
NOWSHOWING
REPLAY
ADVANCE
DELIMITER
GUIDE</pre>
<p>I wanted to make it a little easier for me, since typing PLAY is probably harder than actually just pressing the play button on the physical remote. To solve this, I created a set of bash aliases that map shorthand commands to the symbolic links we just created. Here is what I added to my ~/.bashrc at the bottom:</p>
<pre class="brush: bash; gutter: false; first-line: 1">#TiVO commands
alias info="INFO"
alias cl="CLEAR"
alias pa="PAUSE"
alias pu="PAUSE"
alias replay="REPLAY"
alias rw="REPLAY"
alias re="REPLAY"
alias down="DOWN"
alias d="DOWN"
alias up="UP"
alias u="UP"
alias left="LEFT"
alias l="LEFT"
alias right="RIGHT"
alias r="RIGHT"
alias play="PLAY"
alias pl="PLAY"
alias select="SELECT"
alias sel="SELECT"
alias ff="ADVANCE"
alias skip="ADVANCE"
alias tivo="TIVO"
alias zoom="WINDOW"
alias zm="WINDOW"
alias chup="CHANNELUP"
alias chu="CHANNELUP"
alias pgu="CHANNELUP"
alias pgup="CHANNELUP"
alias chdn="CHANNELDOWN"
alias chd="CHANNELDOWN"
alias pgdn="CHANNELDOWN"
alias pgd="CHANNELDOWN"
alias thumbsup="THUMBSUP"
alias thup="THUMBSUP"
alias thu="THUMBSUP"
alias thumbsdown="THUMBSDOWN"
alias thdn="THUMBSDOWN"
alias thd="THUMBSDOWN"
alias guide="GUIDE"
alias gu="GUIDE"</pre>
<p>Now, i can use my TiVo from the konsole (via yakuake) that I always have running using commands such as `ff 6` to fast forward 6&#215;30 seconds, `rw 3` to rewind 3&#215;8 seconds, `pu` to pause, `pl` to play, etc etc etc</p>
<p>shoutout to Alex Lambert for his help pointing out some of the obvious to me</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/12/remote-control-of-a-tivo-from-the-linux-command-line/" data-text="Remote control of a TiVo from the Linux command line" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/12/remote-control-of-a-tivo-from-the-linux-command-line/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F12%2Fremote-control-of-a-tivo-from-the-linux-command-line%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/12/remote-control-of-a-tivo-from-the-linux-command-line/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/3Wxz9Ss3hEQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/12/remote-control-of-a-tivo-from-the-linux-command-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/12/remote-control-of-a-tivo-from-the-linux-command-line/</feedburner:origLink></item>
		<item>
		<title>Adventures in Cooking 2: Bucatini ala Charlie</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/DJiUrilZkO8/</link>
		<comments>http://charliemeyer.net/blog/2012/11/adventures-in-cooking-2-pasta-ala-charlie/#comments</comments>
		<pubDate>Sun, 25 Nov 2012 07:31:54 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[cooking]]></category>
		<category><![CDATA[italian]]></category>
		<category><![CDATA[pasta]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=250</guid>
		<description><![CDATA[Ingredients: 1 large sweet onion, finely chopped 2 carrots, peeled and shredded 1/2-1 lb porcini mushrooms, cleaned and sliced 3/4 lb pancetta, chopped (i get 4 slices at the largest thickness at the deli) 1 wedge fresh parm cheese (the canned stuff is no good here) 1 lb italian sausage 1 large can of crushed [...]]]></description>
				<content:encoded><![CDATA[<p>Ingredients:</p>
<p>1 large sweet onion, finely chopped<br />
2 carrots, peeled and shredded<br />
1/2-1 lb porcini mushrooms, cleaned and sliced<br />
3/4 lb pancetta, chopped (i get 4 slices at the largest thickness at the deli)<br />
1 wedge fresh parm cheese (the canned stuff is no good here)<br />
1 lb italian sausage<br />
1 large can of crushed tomatoes<br />
1 large can of tomato sauce<br />
2 tiny cans of tomato paste<br />
3-4 roasted red bell peppers in water, drained and pureed in food processor<br />
fresh basil<br />
italian seasoning<br />
salt<br />
sugar<br />
crushed red pepper<br />
olive oil<br />
1 lb bucatini pasta</p>
<p>Carmelize onion in sautee pan olver med-low heat with a bit of olive oil. Set aside. Sautee mushrooms and carrots until soft in olive oil. Set aside. Cook pancetta and italian sausage until pancetta is crispy and sausage is cooked through. Be sure sausage is well broken up into very small pieces. Drain excess fat from pan. In large stock pot, combine combine onions, mushrooms, carrots, meat, tomato sauce, crushed tomatoes, red peppers, tomato paste. Stir to combine. Cut off rind from parm wedge and add to pot. Season with seasonings to taste. I go easy with the sugar until it tastes just right. Simmer over low heat for 3-4 hours to reduce. With 30 mins to go in cooking, add basil. When done, cool and store in fridge.</p>
<p>To serve, cook bucatini for 1 minute less than box suggests. Reserve 1 cup of pasta water. Drain pasta and return to pot it was cooked in. Add 1-2 large scoops of sauce per person that is eating (depending on how saucey you like it). Reheat sauce together with pasta over med heat until sauce is hot and bubbly. The extra time with the sauce will finish cooking the pasta. Serve in bowls. Finely grate top with fresh parm cheese, a drizzle of olive oil, and some chopped basil.</p>
<p>&#8220;Pasta is not a castle, therefore it should not be floating in a moat of sauce&#8221; -Guy Fieri</p>
<p><a href="http://charliemeyer.net/blog/wp-content/uploads/2012/11/IMG_20121111_170043.jpg"><img class="aligncenter size-medium wp-image-252" title="IMG_20121111_170043" src="http://charliemeyer.net/blog/wp-content/uploads/2012/11/IMG_20121111_170043-300x225.jpg" alt="" width="300" height="225" /></a></p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/11/adventures-in-cooking-2-pasta-ala-charlie/" data-text="Adventures in Cooking 2: Bucatini ala Charlie" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/11/adventures-in-cooking-2-pasta-ala-charlie/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F11%2Fadventures-in-cooking-2-pasta-ala-charlie%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/11/adventures-in-cooking-2-pasta-ala-charlie/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/DJiUrilZkO8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/11/adventures-in-cooking-2-pasta-ala-charlie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/11/adventures-in-cooking-2-pasta-ala-charlie/</feedburner:origLink></item>
		<item>
		<title>Adventures in cooking: Coca-Cola pot roast</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/WArl46GT-qw/</link>
		<comments>http://charliemeyer.net/blog/2012/09/adventures-in-cooking-coca-cola-pot-roast/#comments</comments>
		<pubDate>Mon, 24 Sep 2012 04:38:31 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[cooking]]></category>
		<category><![CDATA[pot roast]]></category>
		<category><![CDATA[slow cooker]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=244</guid>
		<description><![CDATA[Today I went out on a limb and tried a new recipe to make a sweet and savory pot roast. It turned out extremely well, so I felt like I would share it here: Coca-Cola Slow Cooker Pot Roast Ingredients:  1 3-4 lb beef roast 1 can cola (350 ml if pouring into measuring cup) [...]]]></description>
				<content:encoded><![CDATA[<p>Today I went out on a limb and tried a new recipe to make a sweet and savory pot roast. It turned out extremely well, so I felt like I would share it here:</p>
<p><strong>Coca-Cola Slow Cooker Pot Roast</strong></p>
<p><strong>Ingredients:</strong></p>
<ul>
<li> 1 3-4 lb beef roast</li>
<li>1 can cola (350 ml if pouring into measuring cup)</li>
<li>1 can cream of mushroom soup</li>
<li>1 packet of dry onion soup mix</li>
<li>(Optional) 4-6 red potatoes</li>
<li>2 large carrots, chopped</li>
<li>1 package either white button or baby portabello mushrooms, sliced</li>
<li>2 stalks celery, chopped</li>
<li>1 packet brown gravy mix</li>
<li>2 tbsp corn starch</li>
</ul>
<p><strong>Steps:</strong></p>
<ol>
<li>Trim roast of all excess fat</li>
<li>Place roast in slow cooker</li>
<li>If desired, quarter potatoes and place around roast</li>
<li>Place carrots and celery around roast</li>
<li>Place mushrooms around and on top of roast</li>
<li>In a large bowl, mix cola, mushroom soup, and onion soup mix until homogeneous</li>
<li>Pour liquid mixture on veggies</li>
<li>Cook on low setting for 8-9 hours</li>
<li>When cooking is complete, place a colander in large sauté pan and pour contents of slow cooker into it</li>
<li>Strain all drippings into sauté pan</li>
<li>In small bowl or coffee cup, mix cornstarch with 3 tbsp water</li>
<li>Heat juices to boiling, add brown gravy mix and cornstarch slurry</li>
<li>Wisk continually until gravy thickens</li>
</ol>
<p>Serve beef with veggies and gravy. I added homemade mashed potatoes along with it, recipe for those follows.</p>
<p>Serves 5-6</p>
<p><a href="http://charliemeyer.net/blog/wp-content/uploads/2012/09/IMG_20120923_171326.jpg"><img class="aligncenter size-medium wp-image-243" title="Coca-Cola Pot Roast" src="http://charliemeyer.net/blog/wp-content/uploads/2012/09/IMG_20120923_171326-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p><strong>Charlie&#8217;s/Emily&#8217;s Party Potatoes</strong></p>
<p><strong>Ingredients:</strong></p>
<ul>
<li>3-5 large russet potatoes, usually about 1 potato per serving</li>
<li>Kosher salt to taste</li>
<li>Black pepper to taste</li>
<li>Cayenne pepper to taste</li>
<li>1 small container low fat/fat free cream cheese</li>
<li>1 small container light sour cream</li>
<li>1/2 stick margarine/butter (Optional) (i used orville reddenbocker fat free butter flavored popcorn topping seasoning instead)</li>
<li>1 packet ranch dressing mix</li>
<li>(Optional) Paprika</li>
</ul>
<p><strong>Steps:</strong></p>
<ol>
<li>(Optional) Peel skins from potatoes</li>
<li>Cut potatoes into approximately 1 inch cubes and place into large stock pot</li>
<li>Cover potatoes with cold water</li>
<li>Salt water until the salt is noticeable when tasting</li>
<li>Heat pot to boiling</li>
<li>Reduce heat and boil until potatoes are fork tender, roughly 45 minutes depending on potato size</li>
<li>Drain water and return potatoes to pot</li>
<li>Add cream cheese, sour cream, margarine, salt, pepper, cayenne pepper, and ranch dressing packet</li>
<li>Beat with hand mixer until smooth and creamy</li>
<li>(Optional) Put mashed potatoes in baking dish, top with pads of butter/margarine, sprinkle with paprika or cayenne, and bake for 20-30 minutes</li>
</ol>
<p><a href="http://charliemeyer.net/blog/wp-content/uploads/2012/09/IMG_20120923_183839.jpg"><img class="aligncenter size-medium wp-image-242" title="Coca-Cola Pot Roast Plate" src="http://charliemeyer.net/blog/wp-content/uploads/2012/09/IMG_20120923_183839-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>This was an amazing dinner(s) for me, so maybe someone else will find it worthwhile too!</p>
<p>-cem</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/09/adventures-in-cooking-coca-cola-pot-roast/" data-text="Adventures in cooking: Coca-Cola pot roast" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/09/adventures-in-cooking-coca-cola-pot-roast/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F09%2Fadventures-in-cooking-coca-cola-pot-roast%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/09/adventures-in-cooking-coca-cola-pot-roast/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/WArl46GT-qw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/09/adventures-in-cooking-coca-cola-pot-roast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/09/adventures-in-cooking-coca-cola-pot-roast/</feedburner:origLink></item>
		<item>
		<title>Masters Thesis</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/XChXUMs2Iw4/</link>
		<comments>http://charliemeyer.net/blog/2012/07/masters-thesis/#comments</comments>
		<pubDate>Wed, 25 Jul 2012 06:59:16 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[education]]></category>
		<category><![CDATA[research]]></category>
		<category><![CDATA[comoto]]></category>
		<category><![CDATA[masters]]></category>
		<category><![CDATA[MS]]></category>
		<category><![CDATA[thesis]]></category>
		<category><![CDATA[uiuc]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=230</guid>
		<description><![CDATA[I have finally finished my Masters of Science degree at the University of Illinois at Urbana-Champaign. I wrote my thesis on the plagiarism detection software that I wrote that has become the standard means of plagiarism detection at the CS department here. I hope that this work will only allow my work to be continued [...]]]></description>
				<content:encoded><![CDATA[<p>I have finally finished my Masters of Science degree at the University of Illinois at Urbana-Champaign. I wrote my thesis on the plagiarism detection software that I wrote that has become the standard means of plagiarism detection at the CS department here.</p>
<p>I hope that this work will only allow my work to be continued in the future and allow for further adoption of my method.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/07/masters-thesis/" data-text="Masters Thesis" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/07/masters-thesis/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F07%2Fmasters-thesis%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/07/masters-thesis/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/XChXUMs2Iw4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/07/masters-thesis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/07/masters-thesis/</feedburner:origLink></item>
		<item>
		<title>ITiCSE 2012 Slides</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/WP4P655xzI0/</link>
		<comments>http://charliemeyer.net/blog/2012/06/iticse-2012-slides/#comments</comments>
		<pubDate>Wed, 13 Jun 2012 06:40:37 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[education]]></category>
		<category><![CDATA[research]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[CS Education]]></category>
		<category><![CDATA[cs242]]></category>
		<category><![CDATA[haifa]]></category>
		<category><![CDATA[israel]]></category>
		<category><![CDATA[Istanbul]]></category>
		<category><![CDATA[ITiCSE]]></category>
		<category><![CDATA[iticse 2012]]></category>
		<category><![CDATA[paper]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[programming studio]]></category>
		<category><![CDATA[slides]]></category>
		<category><![CDATA[Studio]]></category>
		<category><![CDATA[Travel]]></category>
		<category><![CDATA[Turkey]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=224</guid>
		<description><![CDATA[In a few weeks, I will be traveling with Michael Woodley to Haifa, Israel to attend the ITiCSE 2012 conference (conference on innovation and technology in computer science education). This will be my second trip to this conference as I traveled to Germany last summer to present work on another topic. This year, I will [...]]]></description>
				<content:encoded><![CDATA[<p>In a few weeks, I will be traveling with Michael Woodley to Haifa, Israel to attend the ITiCSE 2012 conference (conference on innovation and technology in computer science education). This will be my second trip to this conference as I traveled to Germany last summer to present work on another topic. This year, I will be presenting on the course that I have helped to develop at the University of Illinois at Urbana-Champaign over the past six years. The paper can be seen in a previous post here, but the slide deck I will be using to present can be seen here:</p>
<p>In addition to the week I will be spending in Israel, I will be making a side trip after to Istanbul, Turkey to meet with Professor Barış Aktemur at Özyeğin University there as he is replicating our course. This is the second ever installment worldwide of our programming studio concept, and we are excited to meet with him to discuss how his first semester of the course was as well as share our tips for success and learn from him what we can do to improve our course as well.</p>
<p>I&#8217;m looking forward to the trip to Asia very much, but not so much to the 20 hours of travel that it will take to get to Israel as well as the 8 hours of time difference that I will need to adjust to once I arrive. Wish me luck!</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/06/iticse-2012-slides/" data-text="ITiCSE 2012 Slides" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/06/iticse-2012-slides/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F06%2Fiticse-2012-slides%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/06/iticse-2012-slides/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/WP4P655xzI0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/06/iticse-2012-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/06/iticse-2012-slides/</feedburner:origLink></item>
		<item>
		<title>Cabo Alpha 2012 Photos</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/5JFkLZ1zUPs/</link>
		<comments>http://charliemeyer.net/blog/2012/03/cabo-alpha-2012-photos/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 00:32:42 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[Academy]]></category>
		<category><![CDATA[ALA]]></category>
		<category><![CDATA[American]]></category>
		<category><![CDATA[American Leadership Academy]]></category>
		<category><![CDATA[BCS]]></category>
		<category><![CDATA[Cabo]]></category>
		<category><![CDATA[Cabo San Lucas]]></category>
		<category><![CDATA[Hacienda Los Amigos]]></category>
		<category><![CDATA[Jerry Nelson]]></category>
		<category><![CDATA[Leadership]]></category>
		<category><![CDATA[Marbella Suites]]></category>
		<category><![CDATA[Mexico]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=182</guid>
		<description><![CDATA[Photos from my trip to the Cabo Alpha American Leadership Academy in Cabo San Lucas, BCS, Mexico are now posted in the gallery here. Tweet]]></description>
				<content:encoded><![CDATA[<p>Photos from my trip to the Cabo Alpha American Leadership Academy in Cabo San Lucas, BCS, Mexico are now posted in the gallery <a href="http://charliemeyer.net/blog/photos/?wppa-album=1&amp;wppa-cover=0&amp;wppa-occur=1">here</a>.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/03/cabo-alpha-2012-photos/" data-text="Cabo Alpha 2012 Photos" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/03/cabo-alpha-2012-photos/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F03%2Fcabo-alpha-2012-photos%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/03/cabo-alpha-2012-photos/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/5JFkLZ1zUPs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/03/cabo-alpha-2012-photos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/03/cabo-alpha-2012-photos/</feedburner:origLink></item>
		<item>
		<title>Thinkpad Slice Battery Woes</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/k5Mhubv-VdQ/</link>
		<comments>http://charliemeyer.net/blog/2012/03/thinkpad-slice-battery-woes/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 08:23:32 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[battery]]></category>
		<category><![CDATA[bios]]></category>
		<category><![CDATA[boot]]></category>
		<category><![CDATA[dead]]></category>
		<category><![CDATA[dead battery]]></category>
		<category><![CDATA[laptop]]></category>
		<category><![CDATA[lenovo]]></category>
		<category><![CDATA[slice]]></category>
		<category><![CDATA[slice battery]]></category>
		<category><![CDATA[suspend]]></category>
		<category><![CDATA[t510]]></category>
		<category><![CDATA[t520]]></category>
		<category><![CDATA[thinkpad]]></category>
		<category><![CDATA[w510]]></category>
		<category><![CDATA[w520]]></category>
		<category><![CDATA[workstation]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=173</guid>
		<description><![CDATA[I recently purchased the Thinkpad slice battery for my Thinkpad W520 laptop. This battery also fits the W510, T510, and T520. I noticed that when using the laptop on battery power, the slice battery would drain first followed by the regular 9 cell battery. I came into a problem where i would either nearly drain [...]]]></description>
				<content:encoded><![CDATA[<p>I recently purchased the Thinkpad slice battery for my Thinkpad W520 laptop. This battery also fits the W510, T510, and T520. I noticed that when using the laptop on battery power, the slice battery would drain first followed by the regular 9 cell battery. I came into a problem where i would either nearly drain or all the way drain the slice battery (then continue on to the 9 cell) and would then suspend the laptop. The laptop would power off as it would try to draw from the dead slice battery for power even if the 9 cell had plenty of power left. If you are encountering this issue, update your BIOS to the latest version as it fixes this issue. The latest BIOS is available on <a href="http://support.lenovo.com/en_US/" target="_blank">lenovo&#8217;s website</a>.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/03/thinkpad-slice-battery-woes/" data-text="Thinkpad Slice Battery Woes" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/03/thinkpad-slice-battery-woes/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F03%2Fthinkpad-slice-battery-woes%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/03/thinkpad-slice-battery-woes/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/k5Mhubv-VdQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/03/thinkpad-slice-battery-woes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/03/thinkpad-slice-battery-woes/</feedburner:origLink></item>
		<item>
		<title>Programming Studio: Advances and Lessons Learned</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/mcF035L_YEs/</link>
		<comments>http://charliemeyer.net/blog/2012/03/programming-studio-advances-and-lessons-learned/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 03:15:51 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[cs242]]></category>
		<category><![CDATA[haifa]]></category>
		<category><![CDATA[israel]]></category>
		<category><![CDATA[ITiCSE]]></category>
		<category><![CDATA[iticse 2012]]></category>
		<category><![CDATA[paper]]></category>
		<category><![CDATA[programming studio]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=167</guid>
		<description><![CDATA[I recently was first author on a tips paper which has been accepted to be published in the proceedings of ITiCSE 2012 in Haifa, Israel. The paper can be downloaded here. Tweet]]></description>
				<content:encoded><![CDATA[<p>I recently was first author on a tips paper which has been accepted to be published in the proceedings of ITiCSE 2012 in Haifa, Israel. The paper can be downloaded <a href="http://charliemeyer.net/blog/wp-content/uploads/2012/03/paper.pdf">here</a>.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/03/programming-studio-advances-and-lessons-learned/" data-text="Programming Studio: Advances and Lessons Learned" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/03/programming-studio-advances-and-lessons-learned/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F03%2Fprogramming-studio-advances-and-lessons-learned%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/03/programming-studio-advances-and-lessons-learned/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/mcF035L_YEs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/03/programming-studio-advances-and-lessons-learned/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/03/programming-studio-advances-and-lessons-learned/</feedburner:origLink></item>
		<item>
		<title>Gradient Backgrounds With Processing</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/-Si-KkQzZ9Y/</link>
		<comments>http://charliemeyer.net/blog/2012/02/gradient-backgrounds-with-processing/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 19:23:12 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[gradient]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=161</guid>
		<description><![CDATA[I came across the need to make a gradient background for a visualization prototype I was working on for a course. We were using processing, and here is the code that I came up with to accomplish it. Usage should be fairly straightforward, and it should be easy to modify for any needs anyone has. [...]]]></description>
				<content:encoded><![CDATA[<p>I came across the need to make a gradient background for a visualization prototype I was working on for a course. We were using processing, and here is the code that I came up with to accomplish it. Usage should be fairly straightforward, and it should be easy to modify for any needs anyone has.<br />
<br/></p>
<pre>
<span style="color: #CC6600;">class</span> GradientBackground{
&nbsp;&nbsp;<span style="color: #CC6600;">color</span>[] colors;
&nbsp;&nbsp;<span style="color: #CC6600;">int</span> c_alpha;
&nbsp;&nbsp;
&nbsp;&nbsp;GradientBackground(<span style="color: #CC6600;">color</span>[] t_colors, <span style="color: #CC6600;">int</span> t_alpha){
&nbsp;&nbsp;&nbsp;&nbsp;colors&nbsp;=&nbsp;t_colors;
&nbsp;&nbsp;&nbsp;&nbsp;c_alpha&nbsp;=&nbsp;t_alpha;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">float</span> w = <span style="color: #006699;">width</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">int</span> colorWidth = (<span style="color: #CC6600;">int</span>)((w / (colors.<span style="color: #CC6600;">length</span>-1)));
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">int</span> colorHeight = <span style="color: #006699;">height</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">for</span>(<span style="color: #CC6600;">int</span> colorIndex = 0; colorIndex < (colors.<span style="color: #CC6600;">length</span>-1); colorIndex++){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setGradient(colorIndex*colorWidth,&nbsp;0,&nbsp;colorWidth,&nbsp;colorHeight,&nbsp;colors[colorIndex],&nbsp;colors[colorIndex+1]);&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;<span style="color: #CC6600;">void</span> setGradient(<span style="color: #CC6600;">int</span> x, <span style="color: #CC6600;">int</span> y, <span style="color: #CC6600;">float</span> w, <span style="color: #CC6600;">float</span> h, <span style="color: #CC6600;">color</span> c1, <span style="color: #CC6600;">color</span> c2 ){
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">float</span> deltaR = <span style="color: #CC6600;">red</span>(c2)-<span style="color: #CC6600;">red</span>(c1);
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">float</span> deltaG = <span style="color: #CC6600;">green</span>(c2)-<span style="color: #CC6600;">green</span>(c1);
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">float</span> deltaB = <span style="color: #CC6600;">blue</span>(c2)-<span style="color: #CC6600;">blue</span>(c1);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">for</span> (<span style="color: #CC6600;">int</span> i=y; i<=(y+h); i++){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">for</span> (<span style="color: #CC6600;">int</span> j = 1; j<=w; j++){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">color</span> c = <span style="color: #CC6600;">color</span>(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color: #CC6600;">red</span>(c1)+(j)*(deltaR/w)),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color: #CC6600;">green</span>(c1)+(j)*(deltaG/w)),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color: #CC6600;">blue</span>(c1)+(j)*(deltaB/w)),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c_alpha
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">stroke</span>(c);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">fill</span>(c);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7E7E7E;">//point(j+x, i); //this line is buggy, doesnt work properly with most recent version of processing</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #CC6600;">rect</span>(j+x, i,1,1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
}

</pre>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2012/02/gradient-backgrounds-with-processing/" data-text="Gradient Backgrounds With Processing" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2012/02/gradient-backgrounds-with-processing/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2012%2F02%2Fgradient-backgrounds-with-processing%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2012/02/gradient-backgrounds-with-processing/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/-Si-KkQzZ9Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2012/02/gradient-backgrounds-with-processing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2012/02/gradient-backgrounds-with-processing/</feedburner:origLink></item>
		<item>
		<title>Fix for sound stop working randomly on Ubuntu 11.04</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/k-kVnM1O7NM/</link>
		<comments>http://charliemeyer.net/blog/2011/10/fix-for-sound-stop-working-randomly-on-ubuntu-11-04/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 01:59:33 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[natty]]></category>
		<category><![CDATA[pulseaudio]]></category>
		<category><![CDATA[sound]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=158</guid>
		<description><![CDATA[Recently, after a few days of uptime, my sound would completely go out on my laptop with the only thing fixing it being a complete restart of the machine. I originally tried: sudo /etc/init.d/pulseaudio restart This did not work at all, so I resigned myself to just restart the machine when it happened. With a [...]]]></description>
				<content:encoded><![CDATA[<p>Recently, after a few days of uptime, my sound would completely go out on my laptop with the only thing fixing it being a complete restart of the machine. I originally tried:</p>
<pre class="brush:shell">sudo /etc/init.d/pulseaudio restart</pre>
<p>This did not work at all, so I resigned myself to just restart the machine when it happened. With a solid state disk, rebooting takes 30 seconds, so it was not a major pain. But the sound went out again today after only about 2 days, so I decided to see if I could fix things. I decided to run VLC on an audio file from the terminal to induce some error messages. After playing the song for a few seconds, the terminal began to be flooded with messages like:</p>
<pre class="brush:shell">[0xdf11a0] pulse audio output error: overflow</pre>
<p>Aha, it was in fact a pulseaudio problem. So, the following steps fixed my problem.</p>
<p>In a terminal:</p>
<pre class="brush:applescript">sudo killall pulseaudio</pre>
<p>Then, Alt+F2, enter pulseaudio in the box, click Run, and boom sound was back in action.</p>
<p>Hope this helps someone.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/10/fix-for-sound-stop-working-randomly-on-ubuntu-11-04/" data-text="Fix for sound stop working randomly on Ubuntu 11.04" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/10/fix-for-sound-stop-working-randomly-on-ubuntu-11-04/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F10%2Ffix-for-sound-stop-working-randomly-on-ubuntu-11-04%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/10/fix-for-sound-stop-working-randomly-on-ubuntu-11-04/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/k-kVnM1O7NM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/10/fix-for-sound-stop-working-randomly-on-ubuntu-11-04/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/10/fix-for-sound-stop-working-randomly-on-ubuntu-11-04/</feedburner:origLink></item>
		<item>
		<title>ITiCSE 2011 debrief</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/FY9VOATRweM/</link>
		<comments>http://charliemeyer.net/blog/2011/07/iticse-2011-debrief/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 07:36:31 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[ACM]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Darmstadt]]></category>
		<category><![CDATA[Germany]]></category>
		<category><![CDATA[ITiCSE]]></category>
		<category><![CDATA[ITiCSE 2011]]></category>
		<category><![CDATA[SIGCSE]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=147</guid>
		<description><![CDATA[I just got home from a nearly week long trip to Darmstadt, Germany (about 20 km outside of Frankfurt) to attend the ITiCSE 2011 conference. I plan to write a post on each of my favorite paper sessions in the near future, but long story short there were a bunch of fantastic things that I [...]]]></description>
				<content:encoded><![CDATA[<p>I just got home from a nearly week long trip to Darmstadt, Germany (about 20 km outside of Frankfurt) to attend the<a title="ITiCSE 2011" href="http://www.iticse2011.tu-darmstadt.de/"> ITiCSE 2011</a> conference. I plan to write a post on each of my favorite paper sessions in the near future, but long story short there were a bunch of fantastic things that I picked up that I plan to bring back to UIUC and incorporate into the courses that I am involved with teaching. I made some great friends from all over the world and am already looking forward to finding a way to attend next year&#8217;s incarnation of this conference in Israel.</p>
<p>Here are the slides from the talk I gave this past Monday:</p>
<p>Keep an eye out, more ITiCSE-related posts soon to come.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/07/iticse-2011-debrief/" data-text="ITiCSE 2011 debrief" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/07/iticse-2011-debrief/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F07%2Fiticse-2011-debrief%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/07/iticse-2011-debrief/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/FY9VOATRweM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/07/iticse-2011-debrief/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/07/iticse-2011-debrief/</feedburner:origLink></item>
		<item>
		<title>New Thinkpad</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/HZWV48Af3mY/</link>
		<comments>http://charliemeyer.net/blog/2011/05/new-thinkpad/#comments</comments>
		<pubDate>Tue, 24 May 2011 04:55:29 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[other]]></category>
		<category><![CDATA[laptop]]></category>
		<category><![CDATA[lenovo]]></category>
		<category><![CDATA[thinkpad]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=143</guid>
		<description><![CDATA[I just received my new Thinkpad W520 laptop and the least I can say is, wow, its amazing&#8230; Intel Core i7-2820QM Processor (2.30GHz, 8MB L3) Dual boot Ubuntu 11.04 64/Windows 7 Professional 64 15.6&#8243; FHD (1920 x 1080) LED Backlit Anti-Glare Display NVIDIA Quadro 2000M Graphics with 2GB DDR3 Memory 16 GB PC3-10600 DDR3 SDRAM [...]]]></description>
				<content:encoded><![CDATA[<p>I just received my new Thinkpad W520 laptop and the least I can say is, wow, its amazing&#8230;</p>
<ul>
<li>Intel Core i7-2820QM Processor (2.30GHz, 8MB L3)</li>
<li>Dual boot Ubuntu 11.04 64/Windows 7 Professional 64</li>
<li>15.6&#8243; FHD (1920 x 1080) LED Backlit Anti-Glare Display</li>
<li>NVIDIA Quadro 2000M Graphics with 2GB DDR3 Memory</li>
<li>16 GB PC3-10600 DDR3 SDRAM 1333MHz SODIMM Memory</li>
<li>UltraNav with TrackPoint &amp; touchpad plus Fingerprint reader</li>
<li>720p Camera</li>
<li>750 GB Primary Hard Disk Drive, 7200rpm</li>
<li>1 TB Secondary Hard Disk Drive, 5400rpm</li>
<li>DVD recordable multiburner</li>
<li>Express Card Slot &amp; 4 in 1 Card Reader</li>
<li>9 cell Li-Ion Battery &#8211;  55++</li>
<li>Bluetooth 3.0</li>
<li>Intel Centrino Ultimate-N 6300 (3&#215;3 AGN)</li>
<li>2 USB 3.0 ports</li>
<li>1 USB/eSATA</li>
<li>1 Powered USB</li>
<li>Dual digital microphone</li>
<li>ThinkPad Mini Dock Plus Series 3</li>
</ul>
<p>I&#8217;ve had a blast with this thing so far, and can&#8217;t wait to dig into it more. It boots up quicker than you can believe and runs several virtual machines simultaneously with no issues at all. I plan on putting in an Intel 310 Soda Creek PCI-E SSD as soon as they get in stock on Newegg to even juice the performance a bit further. There are only two things I dislike about it thus far: 1. the size of the power adapter, its literally 3x the size of the 90W adapter that came with my T500, but that&#8217;s understandable I guess for a 170W adapter 2. The speakers are unusually quiet at full volume, even headphones are quieter than I would have thought them to be.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/05/new-thinkpad/" data-text="New Thinkpad" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/05/new-thinkpad/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F05%2Fnew-thinkpad%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/05/new-thinkpad/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/HZWV48Af3mY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/05/new-thinkpad/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/05/new-thinkpad/</feedburner:origLink></item>
		<item>
		<title>Patching Seaside for deployment</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/MNJJ5IKgfPA/</link>
		<comments>http://charliemeyer.net/blog/2011/05/patching-seaside-for-deployment/#comments</comments>
		<pubDate>Mon, 09 May 2011 20:33:35 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[pharo]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[Seaside]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=140</guid>
		<description><![CDATA[I&#8217;m currently in the process of deploying a Seaside application on my server at the University, and I noticed something that I needed to fix before I went any further. By default, the server adapters that ship with Seaside will listen on all interfaces for connections. Since I plan on proxying my Pharo image behind [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m currently in the process of deploying a Seaside application on my server at the University, and I noticed something that I needed to fix before I went any further. By default, the server adapters that ship with Seaside will listen on all interfaces for connections. Since I plan on proxying my Pharo image behind an Apache server, with Apache doing all of the authentication, I did not want my Seaside server to be accessible to outside clients on the port its listening on. This would allow them to bypass my authentication mechanisms I have in place.</p>
<p>I dug through the Seaside code a bit and found what I needed to patch. Note here, I only am patching the WAListenerAdaptor since that is the adaptor which supports Comet (which my application makes heavy use of).</p>
<p>Here is the original code:</p>
<pre class="brush:shell">WAListenerAdaptor&gt;&gt;listenLoop
	| socket |
	socket := Socket newTCP.
	socket 
		listenOn: port
		backlogSize: 50.
	socket isValid ifFalse: [ self error: 'Cannot listen on port ' , port greaseString ].
	
	[ 
	[ socket isValid ifFalse: [ ^ self listenLoop ].
	self waitForConnection: socket ] repeat ] ifCurtailed: 
		[ (Delay forMilliseconds: 10) wait.
		socket destroy ]</pre>
<p>And the patched code:</p>
<pre class="brush:shell">WAListenerAdaptor&gt;&gt;listenLoop
	| socket |
	socket := Socket newTCP.
	socket 
		listenOn: port
		backlogSize: 50
		interface: NetNameResolver loopBackAddress.
	socket isValid ifFalse: [ self error: 'Cannot listen on port ' , port greaseString ].
	
	[ 
	[ socket isValid ifFalse: [ ^ self listenLoop ].
	self waitForConnection: socket ] repeat ] ifCurtailed: 
		[ (Delay forMilliseconds: 10) wait.
		socket destroy ]</pre>
<p>Notice how I changed the socket initialization message to include the interface keyword, and supplied it with the loop back address. Now my application is only accessible via 127.0.0.1 or localhost, and not via its external IP.</p>
<p>The alternative would have been to leave the code unpatched and instead write some iptables firewall rules to block on the port the Seaside adaptor is listening on, but this seemed like a simpler solution and allows me to leave the rest of my system untouched. Also, this solution is the only possible way to do it if you do not have root access to the machine to add iptables rules.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/05/patching-seaside-for-deployment/" data-text="Patching Seaside for deployment" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/05/patching-seaside-for-deployment/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F05%2Fpatching-seaside-for-deployment%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/05/patching-seaside-for-deployment/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/MNJJ5IKgfPA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/05/patching-seaside-for-deployment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/05/patching-seaside-for-deployment/</feedburner:origLink></item>
		<item>
		<title>Apache-based authentication for Seaside</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/3SimUR4Uv-g/</link>
		<comments>http://charliemeyer.net/blog/2011/04/apache-based-authentication-for-seaside/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 03:24:22 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[Bluestem]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[pharo]]></category>
		<category><![CDATA[Seaside]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=135</guid>
		<description><![CDATA[I recently posted about a completely Smalltalk-based solution for LDAP authentication for Seaside applications. After I got that working for my application, I realized that once I submitted my application to our security group here on campus for review, it would never pass inspection due to the fact that user passwords are accessible to my [...]]]></description>
				<content:encoded><![CDATA[<p>I recently posted about a completely Smalltalk-based solution for LDAP authentication for Seaside applications. After I got that working for my application, I realized that once I submitted my application to our security group here on campus for review, it would never pass inspection due to the fact that user passwords are accessible to my code. I can imagine many scenarios where programmer access to user credentials is unacceptable.</p>
<p>Fortunately, our university provides its own kerberos-based authentication solution for applications called <a title="Bluestem" href="http://www.cites.illinois.edu/bluestemdocs/" target="_blank">Bluestem</a>. It provides the user first with a screen to enter their username, then a second screen to enter their university kerberos password. Upon successful authentication, the user is given access to the proper resources on the server. Bluestem is written in Perl and there exists an Apache module to integrate it with web applications. I previously set up the server I plan to deploy my Seaside application on for Bluestem authentication for other web applications that I host on it, but I did not know of a way that I could use this type of authentication with Seaside since I was planning on using mod_proxy to proxy requests from my external-facing Apache server to my headless Pharo VM.</p>
<p>While I was researching how to do this, I came across an Apache module that someone has posted on Github at <a href="https://github.com/aimxhaisse/mod-proxy-add-user" target="_blank">https://github.com/aimxhaisse/mod-proxy-add-user</a> which takes the authenticated user name set by Apache and forwards it on to servers being proxied. I was able to compile it (manually, the Makefile appeared to be broken) and get it up and running on my CentOS server within a few minutes. I configured my Apache configuration file with:</p>
<pre class="brush:shell">&lt;Proxy *&gt;
    Order deny,allow
    Allow from all
    ProxyAddUser On
    ProxyAddUserKey "HTTP_X_FORWARDED_USER"
&lt;/Proxy&gt;
</pre>
<p>And low and behold, I was able to access the authenticated user name in my proxied Seaside application with:</p>
<pre class="brush:shell">username := self class decodeUserIdFrom: (self requestContext request headerAt: 'http_x_forwarded_user' ifAbsent: [username := 'cemeyer2']).</pre>
<p>Let me explain a little bit. In most cases, just self requestContext request headerAt: &#8216;http_x_forwarded_user&#8217; will give you the authenticated user name, but our university&#8217;s kerberos solution sets this variable to &#8216;username@uiuc.edu/kerberos&#8217;, so the decodeUserIdFrom message strips off everything but the user name. The above line also is useful for when accessing the application when not being proxied behind university authentication (such as during development), as it will default to return my user name if the header is not found.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/04/apache-based-authentication-for-seaside/" data-text="Apache-based authentication for Seaside" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/04/apache-based-authentication-for-seaside/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F04%2Fapache-based-authentication-for-seaside%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/04/apache-based-authentication-for-seaside/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/3SimUR4Uv-g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/04/apache-based-authentication-for-seaside/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/04/apache-based-authentication-for-seaside/</feedburner:origLink></item>
		<item>
		<title>Integrating LDAP Authentication with Seaside</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/9x6VQF300Jo/</link>
		<comments>http://charliemeyer.net/blog/2011/04/integrating-ldap-authentication-with-seaside/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 16:03:03 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[pharo]]></category>
		<category><![CDATA[Seaside]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=133</guid>
		<description><![CDATA[For one of my projects at school, I am building an application using the Seaside web development framework. The project will eventually become a piece of courseware for a class I teach, and as such has requirements for authentication. I wanted to use our university&#8217;s authentication system to accomplish this. It took a fair amount [...]]]></description>
				<content:encoded><![CDATA[<p>For one of my projects at school, I am building an application using the Seaside web development framework. The project will eventually become a piece of courseware for a class I teach, and as such has requirements for authentication. I wanted to use our university&#8217;s authentication system to accomplish this. It took a fair amount of digging through the Seaside source code, and following the dead ends that the documentation provided (for example, WAAuthMain doesn&#8217;t even exist).</p>
<p>I decided to use the smalltalk LDAPLayer package to allow me to do what I needed to do. First order of business was to set up a way to do encrypted connections to the LDAP server. The LDAPLayer package does not support SSL connections out of the box (as far as i could tell), so rather than try to modify the source to allow it, I decided to run a local stunnel instance on my machine to provide a SSL proxy to the directory:</p>
<pre class="brush:shell">

sudo stunnel -c -d 389 -r ad.uiuc.edu:636

</pre>
<p>I then can connect to localhost on the regular LDAP port, 389, and it will be securely tunneled to our campus&#8217; Active Directory cluster.</p>
<p>The next step was to write an authenticator that would do the actual authentication. Mine turned out to look something like:</p>
<pre class="brush:shell">LDAPAuthenticator&gt;&gt;#verifyPassword: aPassword forUser: aUsername
	| dn req tempConn |
	aPassword ifNil: [^false].
	aPassword ifNil: [^false].
	dn := self getDNForUsername: aUsername .
	tempConn := LDAPConnection
		to: self class hostname
		port: self class port.
	req := tempConn
		bindAs: dn
		credentials: aPassword.
	[req wait] on: LDAPException do: [ :exception | tempConn disconnect. ^false ].
	tempConn disconnect.
	^true</pre>
<p>I also implemented LDAPAuthenticator&gt;&gt;#getDNForUsername which converts a username into a fully qualified distinguished name for binding to the directory with. In addition, LDAPAuthenticator class&gt;&gt;#hostname and LDAPAuthenticator class&gt;&gt;#port return localhost and 139 respectively. It is important to note that the message implemented has to exactly match #verifyPassword:forUsername: and the message also needs to respond with false if either are nil (it was a bug that threw me off for a bit). Then its simply a matter of tying it all together in the initialize method of the application&#8217;s root component:</p>
<pre class="brush:shell">initialize
	"self initialize"
	| app authFilter |
	app := (WAAdmin register: self asApplicationAt: 'mypath')
		addLibrary: PTDeploymentLibrary;
		addLibrary: SUDeploymentLibrary;
		addLibrary: CTLibrary;
		yourself.
	app preferenceAt: #sessionClass put: MyCustomSession.
	authFilter := WAAuthenticationFilter new.
	authFilter realm: 'Active Directory. Use your username and Active Directory Password'.
	authFilter authenticator: LDAPAuthenticator new.
	app addFilter: authFilter .</pre>
<p>Once that is complete, authentication works like a charm. Of course I could modify the authenticator to only allow members of certain groups, etc, but for my needs, letting anyone with valid credentials is quite alright. I also wanted to tie a user object representing the logged in user to my custom session, so I did the following to get the username of the authenticated user in my overridden #initialrequest in my root component:</p>
<pre class="brush:shell">username := self requestContext request user.</pre>
<p>That took care of the whole mess for me&#8230;</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/04/integrating-ldap-authentication-with-seaside/" data-text="Integrating LDAP Authentication with Seaside" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/04/integrating-ldap-authentication-with-seaside/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F04%2Fintegrating-ldap-authentication-with-seaside%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/04/integrating-ldap-authentication-with-seaside/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/9x6VQF300Jo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/04/integrating-ldap-authentication-with-seaside/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/04/integrating-ldap-authentication-with-seaside/</feedburner:origLink></item>
		<item>
		<title>Notes on using comet with Seaside</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/DLF0k7LUxzI/</link>
		<comments>http://charliemeyer.net/blog/2011/04/notes-on-using-comet-with-seaside/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 23:09:06 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[pharo]]></category>
		<category><![CDATA[Seaside]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=122</guid>
		<description><![CDATA[I&#8217;ve been using the Seaside web development framework for a project at school for the past few weeks and overall have found it to be quite enjoyable. Its amazing how quickly I was able to get a fairly complex web application up and running, especially considering all of the advanced JavaScript that I wanted to [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been using the Seaside web development framework for a project at school for the past few weeks and overall have found it to be quite enjoyable. Its amazing how quickly I was able to get a fairly complex web application up and running, especially considering all of the advanced JavaScript that I wanted to include in the project. I read the <a title="Seaside book" href="http://book.seaside.st" target="_blank">Seaside book</a> to learn how to integrate the &#8220;pushiness&#8221; of <a title="comet" href="https://secure.wikimedia.org/wikipedia/en/wiki/Comet_%28programming%29" target="_blank">comet</a> into my project and hit a bit of a rocky road when I tried to take the simple examples in the book as well as in the Comet-Examples package that comes with Seaside and try to adopt them for use in my application.</p>
<h3>Issue #1: Page never appears to finish loading</h3>
<p>I was able to get basic comet up and running rather quickly, but I noticed when I loaded the page, the browser would continue to appear as if the page was constantly loading. This was because of the way that the Seaside book instructs you to add the comet script to your page. The book example code looks like:</p>
<pre class="brush:shell">html script: (html comet
     pusher: self class pusher;
     connect)</pre>
<p>Assuming:</p>
<pre class="brush:shell">MyComponent class&gt;&gt;#pusher
     ^pusher ifNil: [ pusher := CTPusher new ]</pre>
<p>What this actually does is place a block of JavaScript code in the generated HTML that the browser immediately executes in the foreground when it encounters it. Due to the nature of the comet implementation that Seaside provides (streaming), the browser immediately opens up an asynchronous connection to the Seaside server and streams from it, stopping the browser from doing anything else. This is why it appears to constantly be loading. The proper way to add comet to a Seaside application is as follows:</p>
<pre class="brush:shell">html document
    addLoadScript: (html comet
    pusher: self class pusher;
    connect)</pre>
<p>This causes the browser to start up the comet streaming connection when the page has finished loading, and in the background. Thus the page will appear to the end user as if it is completely loaded, even though the streaming comet connection is open.</p>
<h3>Issue #2: Using comet with a custom session</h3>
<p>I still haven&#8217;t solved this error yet, but hopefully I will soon, so while I wait to hear back from the Seaside mailing list, I&#8217;ll describe the kludge I put in to make it work right.</p>
<p>For my application, I needed a custom subclass of WASession to hold on to information about the logged in user. Unfortunately, when I used this session class with comet, things broke. On the first request of a new session, I would constantly get stacktraces like:</p>
<p><a href="http://charliemeyer.net/blog/wp-content/uploads/2011/04/PharoScreenshot.1.png"><img class="aligncenter size-full wp-image-126" title="Comet Error Stacktrace With Custom Session" src="http://charliemeyer.net/blog/wp-content/uploads/2011/04/PharoScreenshot.1.png" alt="Comet Error Stacktrace With Custom Session" width="599" height="701" /></a></p>
<p>It appears as if the parent of my custom session was never being set to the WAApplication instance that it should have been. It only happened on the first request of the session, and all subsequent comet interactions worked as expected. I thought I could fix this problem by overriding initialize in my custom session, but that did not work:</p>
<pre class="brush:shell">initialize
    ^super initialize</pre>
<p>So, I posted my question to the Seaside mailing list and am still awaiting a response. In the meantime, I have added a &#8220;patch&#8221; to CTHandler&gt;&gt;notifySession to change it from:</p>
<pre class="brush:shell">notifySession
    self session application cache
        notifyRetrieved: self session
        key: self session key</pre>
<p>to:</p>
<pre class="brush:shell">notifySession
    [self session application cache
        notifyRetrieved: self session
        key: self session key]
    on: MessageNotUnderstood do: [:error | ]</pre>
<p>This basically attempts to run the old notifySession code, but when the MessageNotUnderstood error is raised, it simply ignores it and continues on with execution. I know this is not the best practice, but it does make the application work as expected.</p>
<h3>Issue #3: Duplicated JavaScript code sent to clients</h3>
<p>I didn&#8217;t notice this bug until I used FireBug and took a look at the JS that Seaside was generating from my Smalltalk code and streaming to the clients. What I found out, much to my surprise, was that every single JavaScript action that I had coded once in SmallTalk was being sent over the wire twice, both identical. This took a bit to trace down, but again it had to do with inadequate examples from the Seaside book. The Seaside book makes use of jQuery for all of its work with comet (as do the comet examples that come with Seaside itself), and I had chosen to use Prototype/Scriptaculous for my application, so this is where the issue might have arisen.</p>
<p>Say you wanted to push some JavaScript that would set the contents of the div element with id=&#8217;peanut&#8217; to be &#8216;butter&#8217;. The Seaside book and examples led me to believe that using Scriptaculous/Prototype, the code should look like:</p>
<pre class="brush:shell">pushToClient
    self class pusher
        javascript: [ :script |
            script &lt;&lt;  (script scriptaculous element
                id:'peanut';
                update: 'butter').
        ].</pre>
<p>But this actually causes the div to be updated twice in rapid succession, both to the same thing. It was completely unnoticeable on the client side, but it was extra overhead being executed on the client browser as well as extra unnecessary data being sent over the wire.</p>
<p>Thanks to the fantastic debugger built into Pharo, I was able to trace down the problem and rewrite the above code as follows:</p>
<pre class="brush:shell">pushToClient
    self class pusher
        javascript: [ :script |
            script scriptaculous element
                id:'peanut';
                update: 'butter'.
        ].</pre>
<p>The script variable is an instance of a JSScript object, and the #&lt;&lt; message means to append the argument onto its list of JavaScript statements. What I found was that when using the JSScript&gt;&gt;scriptaculous message, it was already appending the generated JavaScript statements onto the JSScript, so the #&lt;&lt; message was simply redundant. Eliminating all usages of #&lt;&lt; in my comet code fixed the error and everything works as expected now.</p>
<h3>Issue #4: Conditionally pushing to clients</h3>
<p>In my application, I have regular users and administrators. They are defined as such based on what type of object is attached to the custom session I wrote for the project. There are certain elements on my pages that only appear for regular users and certain elements that only appear for administrators, as well as a large number of elements that appear in both. I wanted to use a single comet pusher to be able to push to both regular users as well as administrators, to reduce connection overhead in the final deployed version of the application. Having a separate CTPusher for regular users and a separate one for administrators would have worked, but would have been painful. I wanted something a little cleaner. So I did some hacking on the comet source that comes with seaside and this is what I came up with (added):</p>
<pre class="brush:shell">javascript: aBlock forHandlers: handlerBlock
	"Evaluate aBlock with an JSScript instance and pushes the resulting script-string aString to
	handlers which when evaluated as the argument to handlerBlock causes it to return true."

	| script |
	script := (JSScript context: self renderContext)
		rendererClass: self rendererClass;
		yourself.
	aBlock value: script.
	self push: (String streamContents: [ :stream |
		stream
			nextPutAll: '&lt;script type="text/javascript"&gt;parent.Comet.eval(';
			javascript: script asJavascript;
			nextPutAll: ')&lt;/script&gt;' ])
		forHandlers: handlerBlock</pre>
<p>And:</p>
<pre class="brush:shell">push: aString forHandlers: aBlock
	"Push aString to handlers which when passed as the argument to aBlock causes
	it to return true."
	| pushHandlers |
	pushHandlers := handlers select: aBlock.
	self mutex critical: [ pushHandlers do: [ :each | each push: aString ] ]</pre>
<p>I do realize that this does not do exactly what the plain CTHandler&gt;&gt;#push message does. Namely, it does not prune down the handlers list to ensure that only the connected ones continue to receive updates from the server, but in my application I do mostly regular pushes with only a few requiring the handlers block, so I feel like I am pretty much safe for now. So now, using the code I added, if I want to update the div on the page with id &#8216;peanut&#8217; to contain the text &#8216;butter&#8217; for regular users, but to &#8216;jelly&#8217; for administrators, its quite simple:</p>
<pre class="brush:shell">pushToClient
    self class pusher
        javascript: [ :script |
            script scriptaculous element
                id:'peanut';
                update: 'butter'.
        ] forHandlers: [ :handler | handler session user isRegularUser ].
    self class pusher
        javascript: [ :script |
            script scriptaculous element
                id:'peanut';
                update: 'jelly'.
        ] forHandlers: [ :handler | handler session user isAdministrator ].</pre>
<p>So those are my notes on using comet with Seaside thus far. Overall its been a lot of fun watching something really complex come together in such a short period of time. Next, when I get time, I&#8217;ll post about how I was able to get custom basic authentication working using LDAP in Seaside.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/04/notes-on-using-comet-with-seaside/" data-text="Notes on using comet with Seaside" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/04/notes-on-using-comet-with-seaside/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F04%2Fnotes-on-using-comet-with-seaside%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/04/notes-on-using-comet-with-seaside/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/DLF0k7LUxzI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/04/notes-on-using-comet-with-seaside/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/04/notes-on-using-comet-with-seaside/</feedburner:origLink></item>
		<item>
		<title>new favorite tux</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/REqV6Odu524/</link>
		<comments>http://charliemeyer.net/blog/2011/04/new-favorite-tux/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 05:31:20 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=119</guid>
		<description><![CDATA[being a Linux guru, I love to find new logos of my beloved Tux. I feel that this one particularly fits me well: &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; credits to the tux factory Tweet]]></description>
				<content:encoded><![CDATA[<p>being a Linux guru, I love to find new logos of my beloved Tux. I feel that this one particularly fits me well:</p>
<p><a href="http://charliemeyer.net/blog/wp-content/uploads/2011/04/overlord59-dj-tux-mix-platine.png"><img class="alignleft size-full wp-image-118" title="dj tux" src="http://charliemeyer.net/blog/wp-content/uploads/2011/04/overlord59-dj-tux-mix-platine.png" alt="" width="490" height="490" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>credits to <a href="http://tux.crystalxp.net/">the tux factory</a></p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/04/new-favorite-tux/" data-text="new favorite tux" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/04/new-favorite-tux/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F04%2Fnew-favorite-tux%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/04/new-favorite-tux/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/REqV6Odu524" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/04/new-favorite-tux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/04/new-favorite-tux/</feedburner:origLink></item>
		<item>
		<title>fancy new SSL, all thanks to Mercurial</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/ucb4-DE7lew/</link>
		<comments>http://charliemeyer.net/blog/2011/02/fancy-new-ssl-all-thanks-to-mercurial/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 23:44:43 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[certificate]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[VPS]]></category>

		<guid isPermaLink="false">http://charliemeyer.net/blog/?p=113</guid>
		<description><![CDATA[As of today, I finally bit the bullet and installed a real (as in, not self-signed) SSL certificate for my server. It should validate with most browsers out there, but it was relatively inexpensive so I&#8217;m not sure how great the compatibility will be. The main motivating factor was the new version of Mercurial became [...]]]></description>
				<content:encoded><![CDATA[<p>As of today, I finally bit the bullet and installed a real (as in, not self-signed) SSL certificate for my server. It should validate with most browsers out there, but it was relatively inexpensive so I&#8217;m not sure how great the compatibility will be.</p>
<p>The main motivating factor was the new version of Mercurial became very irritating when pushing/pulling/cloning/etc from a remote https repository where the certificate was not able to be validated:</p>
<pre class="brush:shell">chuck@silverstone:~/Documents/cs433$ hg push --insecure https://charliemeyer.net/hg/cs433
warning: charliemeyer.net certificate with fingerprint b0:f2:09:06:87:32:b1:8d:cc:7f:51:09:07:28:44:45:8d:86:f8:fd not verified (check hostfingerprints or web.cacerts config setting)
http authorization required
realm: charliemeyer.net authentication
user: cemeyer2
password: 
warning: charliemeyer.net certificate with fingerprint b0:f2:09:06:87:32:b1:8d:cc:7f:51:09:07:28:44:45:8d:86:f8:fd not verified (check hostfingerprints or web.cacerts config setting)
pushing to https://charliemeyer.net/hg/cs433
warning: charliemeyer.net certificate with fingerprint b0:f2:09:06:87:32:b1:8d:cc:7f:51:09:07:28:44:45:8d:86:f8:fd not verified (check hostfingerprints or web.cacerts config setting)
warning: charliemeyer.net certificate with fingerprint b0:f2:09:06:87:32:b1:8d:cc:7f:51:09:07:28:44:45:8d:86:f8:fd not verified (check hostfingerprints or web.cacerts config setting)
searching for changes
warning: charliemeyer.net certificate with fingerprint b0:f2:09:06:87:32:b1:8d:cc:7f:51:09:07:28:44:45:8d:86:f8:fd not verified (check hostfingerprints or web.cacerts config setting)
bundling changes [ &lt;=&gt;                                                                                                                                                                                           ] 0
warning: charliemeyer.net certificate with fingerprint b0:f2:09:06:87:32:b1:8d:cc:7f:51:09:07:28:44:45:8d:86:f8:fd not verified (check hostfingerprints or web.cacerts config setting)
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 2 changesets with 3 changes to 3 files
</pre>
<p>As you can see from above, not only is the extra noise irritating, but I also have to append &#8220;&#8211;insecure&#8221; to all of my commands. I know I could have modified my hgrc and imported my self-signed certificate, but I already had my global hgrc set up to recognize properly signed repositories:</p>
<pre class="brush:plain">[web]
cacerts = /etc/ssl/certs/ca-certificates.crt</pre>
<p>I do a lot of work with remote hg repositories that do have valid certificates, but also a lot of work with hg repositories on this server, enough work that I didn&#8217;t want to import the self-signed certificate for each hgrc file in each clone of a repository I have on every one of machines. Plus, when I go to other machines, it would take a lot of unnecessary configuration just to get it to work properly.</p>
<p>So, to ease the irritation that Mercurial was causing, this server can now be accessed using a &#8220;more secure&#8221; https than before:</p>
<pre class="brush:shell">chuck@silverstone:~/Documents/cs433$ hg incoming
comparing with https://cemeyer2:***@charliemeyer.net/hg/cs433
searching for changes
no changes found</pre>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/02/fancy-new-ssl-all-thanks-to-mercurial/" data-text="fancy new SSL, all thanks to Mercurial" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/02/fancy-new-ssl-all-thanks-to-mercurial/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F02%2Ffancy-new-ssl-all-thanks-to-mercurial%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/02/fancy-new-ssl-all-thanks-to-mercurial/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/ucb4-DE7lew" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/02/fancy-new-ssl-all-thanks-to-mercurial/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/02/fancy-new-ssl-all-thanks-to-mercurial/</feedburner:origLink></item>
		<item>
		<title>Setting a global default font for Swing applications</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/-BL-ll6R2sg/</link>
		<comments>http://charliemeyer.net/blog/2011/02/setting-a-global-default-font-for-swing-applications/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 16:18:42 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[comoto]]></category>
		<category><![CDATA[HCI]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[plagiarism]]></category>
		<category><![CDATA[Swing]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=103</guid>
		<description><![CDATA[For my research, I am working on writing a Swing application for visualizing data. Part of this work is an exercise in human-computer interaction (HCI). To make this application more visually appeasing, we chose a font to apply to all Swing components. Originally, each component was initialized and then had component.setFont(DEFAULT_FONT); called on it. I [...]]]></description>
				<content:encoded><![CDATA[<p>For my research, I am working on writing a Swing application for visualizing data. Part of this work is an exercise in human-computer interaction (HCI). To make this application more visually appeasing, we chose a font to apply to all Swing components. Originally, each component was initialized and then had</p>
<pre>component.setFont(DEFAULT_FONT);</pre>
<p>called on it. I did some searching on the Internet and realized this could all be avoided with a simple routine run before initializing the entire GUI:</p>
<pre class="brush:java">private static void setDefaultFont() {
        Enumeration keys = UIManager.getDefaults().keys();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof javax.swing.plaf.FontUIResource) {
                UIManager.put(key, DEFAULT_FONT);
            }
        }
    }</pre>
<p>This has worked extremely well and reduced our complexity cost for maintaining and enhancing the application.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2011/02/setting-a-global-default-font-for-swing-applications/" data-text="Setting a global default font for Swing applications" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2011/02/setting-a-global-default-font-for-swing-applications/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2011%2F02%2Fsetting-a-global-default-font-for-swing-applications%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2011/02/setting-a-global-default-font-for-swing-applications/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/-BL-ll6R2sg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2011/02/setting-a-global-default-font-for-swing-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2011/02/setting-a-global-default-font-for-swing-applications/</feedburner:origLink></item>
		<item>
		<title>Extracting strings from MySQL text columns</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/VTcHy9jw3qQ/</link>
		<comments>http://charliemeyer.net/blog/2010/12/97/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 08:23:16 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[parsing]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=97</guid>
		<description><![CDATA[Today, I was working with a MySQL database that contained a column of text that I wanted to parse out into multiple other columns so I could query on them. The first thing that came to mind was why not use regular expressions to extract out the needed bits from the column, but unfortunately, MySQL [...]]]></description>
				<content:encoded><![CDATA[<p>Today, I was working with a MySQL database that contained a column of text that I wanted to parse out into multiple other columns so I could query on them. The first thing that came to mind was why not use regular expressions to extract out the needed bits from the column, but unfortunately, MySQL does not support this use of regular expressions nor regular expression matching at all on InnoDB tables (which is what this was). I was able to accomplish this task using the following SQL:</p>
<p>To extract the first instance of a given piece of text between string start and string end in string content:</p>
<p>For example, start=&#8221;www.&#8221;, end=&#8221;.com&#8221;, content=&#8221;www.facebook.com links to www.google.com&#8221; and I want to select out &#8220;facebook&#8221;:</p>
<pre>
SUBSTRING( 
MAX( content ) , 
LOCATE(start,content)+LENGTH(start), 
LOCATE(end, content, LOCATE(start, content)+LENGTH(start)) - LOCATE(start, content) - LENGTH(start)
)
</pre>
<p>For example:</p>
<pre>
mysql> SELECT
    -> @content:="www.facebook.com links to www.google.com",
    -> @start:="www.",
    -> @finish:=".com",
    -> SUBSTRING( 
    -> @content , 
    -> LOCATE(@start, @content)+LENGTH(@start), 
    -> LOCATE(@finish, @content, LOCATE(@start, @content)+LENGTH(@start)) - LOCATE(@start, @content)- LENGTH(@start)
    -> ) AS extracted;
+------------------------------------------------------+----------------+-----------------+-----------+
| @content:="www.facebook.com links to www.google.com" | @start:="www." | @finish:=".com" | extracted |
+------------------------------------------------------+----------------+-----------------+-----------+
| www.facebook.com links to www.google.com             | www.           | .com            | facebook  | 
+------------------------------------------------------+----------------+-----------------+-----------+
1 row in set (0.00 sec)
</pre>
<p>And of course when creating a view, its always best to cast the columns to the proper types so they can be effectively queried, which is as easy as:</p>
<pre>
CAST( col AS type)
</pre>
<p>For example:</p>
<pre>
mysql> SELECT @text:="  0438t", CAST( @text AS DECIMAL);
+------------------+-------------------------+
| @text:="  0438t" | CAST( @text AS DECIMAL) |
+------------------+-------------------------+
|   0438t          |                     438 | 
+------------------+-------------------------+
1 row in set (0.00 sec)
</pre>
<p>I will be the first to admit this is not the most efficient use of the database, but it works (and I can cast the values) and it can easily be queried when used as a view.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/12/97/" data-text="Extracting strings from MySQL text columns" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/12/97/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F12%2F97%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/12/97/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/VTcHy9jw3qQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/12/97/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/12/97/</feedburner:origLink></item>
		<item>
		<title>Authenticating against UIUC Active Directory (AD) using Python</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/Ep7aRdtn1Nc/</link>
		<comments>http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-python/#comments</comments>
		<pubDate>Tue, 30 Nov 2010 06:10:48 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[University of Illinois]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=92</guid>
		<description><![CDATA[So in a follow up to my earlier post, here is the equivalent code to authenticate against UIUC Active Directory using Python: ldap_auth.py: import ldap def authenticate(netid, password): server = "ldaps://ad.uiuc.edu:636" who = "CN="+netid+",OU=Campus Accounts,DC=ad,DC=uiuc,DC=edu" try: conn = ldap.initialize(server) ldap.set_option( ldap.OPT_X_TLS_DEMAND, True ) ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_NEVER) result = conn.simple_bind_s(who,password) except ldap.LDAPError, e: return False conn.unbind() return True [...]]]></description>
				<content:encoded><![CDATA[<p>So in a follow up to my earlier post, here is the equivalent code to authenticate against UIUC Active Directory using Python:</p>
<p>ldap_auth.py:</p>
<pre>import ldap

def authenticate(netid, password):
    server = "ldaps://ad.uiuc.edu:636"
    who = "CN="+netid+",OU=Campus Accounts,DC=ad,DC=uiuc,DC=edu"
    try:
        conn = ldap.initialize(server)
        ldap.set_option( ldap.OPT_X_TLS_DEMAND, True )
        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_NEVER)
        result = conn.simple_bind_s(who,password)
    except ldap.LDAPError, e:
        return False
    conn.unbind()
    return True

print authenticate("cemeyer2", "password")</pre>
<p>That&#8217;s it. As mentioned in my earlier post, I’m pretty sure that any application that authenticates this way would be looked down upon by CITES since the application in question would potentially be able to sniff user login information, <strong>so please only use this code in a personal testing environment, not for a deployed application unless approved by people much higher up than me.</strong></p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-python/" data-text="Authenticating against UIUC Active Directory (AD) using Python" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-python/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F11%2Fauthenticating-against-uiuc-active-directory-ad-using-python%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-python/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/Ep7aRdtn1Nc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-python/</feedburner:origLink></item>
		<item>
		<title>Authenticating against UIUC Active Directory (AD) using Java</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/b1sIU0KZ6IA/</link>
		<comments>http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-java/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 05:44:27 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[University of Illinois]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=90</guid>
		<description><![CDATA[So in recent weeks I have become interested in means of authenticating users against sources such as Active Directory at UIUC. Although the UIUC domain controllers support Kerberos authentication, I have decided to implement a simpler LDAPS based method due to LDAP being included in the JRE. The code I wrote up looks something like: [...]]]></description>
				<content:encoded><![CDATA[<p>So in recent weeks I have become interested in means of authenticating users against sources such as Active Directory at UIUC. Although the UIUC domain controllers support Kerberos authentication, I have decided to implement a simpler LDAPS based method due to LDAP being included in the JRE. The code I wrote up looks something like:</p>
<p>LDAPAuth.java:</p>
<pre>import java.util.Hashtable;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class LDAPAuth {

	public static void main(String[] args)
	{
		System.out.println(authenticate("cemeyer2","password"));
	}

	public static boolean authenticate(String netid, String password)
	{
		String userDN = findUserDN(netid);
		try
		{
			LdapContext ctx = createLDAPContext(userDN, password);
			ctx.close();
			return true;
		}
		catch(Exception e)
		{
			return false;
		}
	}

	private static String findUserDN(String netid)
	{
		return "CN="+netid+",OU=Campus Accounts,DC=ad,DC=uiuc,DC=edu";
	}

	private static LdapContext createLDAPContext(String bindDN, String bindPassword) throws NamingException
	{
		Hashtable env = new Hashtable();
		env.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
		env.put("java.naming.provider.url", "ldaps://ad.uiuc.edu/");
		env.put("java.naming.ldap.factory.socket", "TrustAllSSLSocketFactory");
		env.put("java.naming.security.protocol", "ssl");
		env.put("java.naming.security.principal", bindDN);
		env.put("java.naming.security.credentials", bindPassword);
		env.put("java.naming.security.authentication", "simple");
		env.put("com.sun.jndi.ldap.connect.pool", "true");
		LdapContext context = new InitialLdapContext(env, null);
		return context;
	}
}</pre>
<p>And in the same package (default package in this example), TrustAllSSLSocketFactory.java:</p>
<pre>import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class TrustAllSSLSocketFactory extends SSLSocketFactory
{
    private static class TrustAllTrustManager
        implements X509TrustManager
    {

        public void checkClientTrusted(X509Certificate ax509certificate[], String s1)
            throws CertificateException
        {
        }

        public void checkServerTrusted(X509Certificate ax509certificate[], String s1)
            throws CertificateException
        {
        }

        public X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[0];
        }

        private TrustAllTrustManager()
        {
        }

    }

    public TrustAllSSLSocketFactory()
    {
        try
        {
            SSLContext sslcontent = SSLContext.getInstance("TLS");
            sslcontent.init(null, new TrustManager[] {
                new TrustAllTrustManager()
            }, new SecureRandom());
            _factory = sslcontent.getSocketFactory();
        }
        catch(Throwable t)
        {
        	//do nothing
        }
    }

    public static SocketFactory getDefault()
    {
        return new TrustAllSSLSocketFactory();
    }

    public Socket createSocket(Socket socket, String s, int i, boolean flag)
        throws IOException
    {
        return _factory.createSocket(socket, s, i, flag);
    }

    public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr2, int j)
        throws IOException
    {
        return _factory.createSocket(inaddr, i, inaddr2, j);
    }

    public Socket createSocket(InetAddress inaddr, int i)
        throws IOException
    {
        return _factory.createSocket(inaddr, i);
    }

    public Socket createSocket(String s, int i, InetAddress inaddr, int j)
        throws IOException
    {
        return _factory.createSocket(s, i, inaddr, j);
    }

    public Socket createSocket(String s, int i)
        throws IOException
    {
        return _factory.createSocket(s, i);
    }

    public String[] getDefaultCipherSuites()
    {
        return _factory.getSupportedCipherSuites();
    }

    public String[] getSupportedCipherSuites()
    {
        return _factory.getSupportedCipherSuites();
    }

    private SSLSocketFactory _factory;

}</pre>
<p>Once that&#8217;s done, using the static LDAPAuth.authenticate() method will allow you to authenticate users against UIUC Active Directory over LDAPS without the need for an AD service account. But I&#8217;m pretty sure that any application that authenticates this way would be looked down upon by CITES since the application in question would potentially be able to sniff user login information, <strong>so please only use this code in a personal testing environment, not for a deployed application unless approved by people much higher up than me.</strong></p>
<p>Good Luck!</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-java/" data-text="Authenticating against UIUC Active Directory (AD) using Java" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-java/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F11%2Fauthenticating-against-uiuc-active-directory-ad-using-java%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-java/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/b1sIU0KZ6IA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/11/authenticating-against-uiuc-active-directory-ad-using-java/</feedburner:origLink></item>
		<item>
		<title>a successful summer at IBM</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/jWRtUveFUOY/</link>
		<comments>http://charliemeyer.net/blog/2010/08/a-successful-summer-at-ibm/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 19:04:08 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[other]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[IBM]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=82</guid>
		<description><![CDATA[This summer, I worked for IBM in Austin, TX and had an absolute blast. Not only was the work enjoyable, but Austin is an incredible city. Definitely more friendly to someone in their early twenties than say, Rochester, MN (where I co-op&#8217;d for IBM previously). Without going into too much detail, I worked on a [...]]]></description>
				<content:encoded><![CDATA[<p>This summer, I worked for IBM in Austin, TX and had an absolute blast. Not only was the work enjoyable, but Austin is an incredible city. Definitely more friendly to someone in their early twenties than say, Rochester, MN (where I co-op&#8217;d for IBM previously).</p>
<p>Without going into too much detail, I worked on a test automation team. Through the course of the summer, I designed and built a test suite composed of approximately 90 different functional test cases using Rational tools. While there was some learning curve, my previous experience with IBM POWER hardware from my previous co-op with IBM and my experience with the Eclipse Framework was invaluable. All in all, it was a great experience.</p>
<p>I&#8217;m sure though that if you talk to most graduate students in Computer Science, almost none of them will say they want a career path that is pure coding like I did this summer and I would tend to agree with that statement. For me at least, that is part of the reason that I am pursuing graduate school, because I want something more than just writing code for the next however many years. But in the future, I would love to come back to Austin in some capacity, hopefully for IBM again.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/08/a-successful-summer-at-ibm/" data-text="a successful summer at IBM" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/08/a-successful-summer-at-ibm/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F08%2Fa-successful-summer-at-ibm%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/08/a-successful-summer-at-ibm/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/jWRtUveFUOY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/08/a-successful-summer-at-ibm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/08/a-successful-summer-at-ibm/</feedburner:origLink></item>
		<item>
		<title>bug or feature?</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/Re68UTnJOI8/</link>
		<comments>http://charliemeyer.net/blog/2010/08/bug-or-feature/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 01:48:11 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Rational]]></category>
		<category><![CDATA[RFT]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=77</guid>
		<description><![CDATA[It seems to be a common joke among people in the software field whether when something odd happens in a program, is it a bug or a feature? I was working with Rational Functional Tester last week, which is a product based on the Eclipse framework, and came across a situation where I was asking [...]]]></description>
				<content:encoded><![CDATA[<p>It seems to be a common joke among people in the software field whether when something odd happens in a program, is it a bug or a feature? I was working with Rational Functional Tester last week, which is a product based on the Eclipse framework, and came across a situation where I was asking myself that same question. This particular incident involved working with the application using the Java Development Tools (JDT), so its quite possible that this problem infests itself in the common IDE versions of Eclipse.</p>
<p>Long story short, Java projects in Eclipse have a source location and a binary location. The binary location is where source files are compiled to so that they can be executed. One of the common actions in Eclipse is to &#8220;clean&#8221; a project, which erases all of the compiled files and recompiles everything from scratch. This is particularly useful to improve the performance of binaries due to penalties incurred by incremental compilation. The problem I ran into was that my destination folder for compilation was the same as my source folder, which seems innocent enough to me. Why not store compiled files alongside their source counterparts? But when I went to clean the project, Eclipse decided to erase <em>everything</em> in the binary folders, including all of my source files. It would seem to me that the proper behavior would be to only delete files deemed to be generated by the build engine. Luckily, I had most of my work backed up in source control and on network shares, so not much was lost, but it was still very irritating.</p>
<p>RFT is based on Eclipse 3.3 or 3.4, I don&#8217;t remember which, but not a recent version, so I&#8217;m not sure if this is present in the current release (Helios). But I plan to investigate later when I have some time to burn&#8230;</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/08/bug-or-feature/" data-text="bug or feature?" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/08/bug-or-feature/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F08%2Fbug-or-feature%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/08/bug-or-feature/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/Re68UTnJOI8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/08/bug-or-feature/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/08/bug-or-feature/</feedburner:origLink></item>
		<item>
		<title>now with a dose of IPv6</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/TL_sTwg3bIg/</link>
		<comments>http://charliemeyer.net/blog/2010/07/now-with-a-dose-of-ipv6/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 18:30:08 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[IPv6]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=74</guid>
		<description><![CDATA[As of 27 July 2010, this server is now alive in the IPv6 world at 2607:f878:1:35a:0:12:5023:1. DNS might take a little bit to propagate through the system, but the AAAA records are in place. Tweet]]></description>
				<content:encoded><![CDATA[<p>As of 27 July 2010, this server is now alive in the IPv6 world at 2607:f878:1:35a:0:12:5023:1.</p>
<p>DNS might take a little bit to propagate through the system, but the AAAA records are in place.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/07/now-with-a-dose-of-ipv6/" data-text="now with a dose of IPv6" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/07/now-with-a-dose-of-ipv6/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F07%2Fnow-with-a-dose-of-ipv6%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/07/now-with-a-dose-of-ipv6/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/TL_sTwg3bIg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/07/now-with-a-dose-of-ipv6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/07/now-with-a-dose-of-ipv6/</feedburner:origLink></item>
		<item>
		<title>now running Ubuntu</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/EYF-j6nFsuY/</link>
		<comments>http://charliemeyer.net/blog/2010/07/now-running-ubuntu/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 03:42:48 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[BurstNet]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[VPS]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=72</guid>
		<description><![CDATA[After running this server for several months with CentOS 5.5, I have taken the plunge and reinstalled it with Ubuntu Server 10.04 LTS. Since this is a VPS, running fantastically courteously of BurstNet, there are several limitations that would not be encountered by a traditional server. The platform that this server runs on is OpenVZ, [...]]]></description>
				<content:encoded><![CDATA[<p>After running this server for several months with CentOS 5.5, I have taken the plunge and reinstalled it with Ubuntu Server 10.04 LTS. Since this is a VPS, running fantastically courteously of BurstNet, there are several limitations that would not be encountered by a traditional server. The platform that this server runs on is OpenVZ, which has its own way of virtualizing containers. In particular, when running CentOS, it was almost impossible to run any Java application on this system due to the way that OpenVZ allocates memory for processes. Based on how I understand it, when launching a Java application, the JVM requests a large block of contiguous memory to run in. OpenVZ often fails to deliver the memory requested, which causes the JVM to fail. For some reason that I don&#8217;t completely understand yet, running Ubuntu in OpenVZ alleviates this problem. I&#8217;m thinking it has something to do with the way the Ubuntu template for OpenVZ was constructed. I run Ubuntu on all of my desktop machines, so I am looking forward to using the server variant here in the future.</p>
<p>So far, I have only restored basic services on this machine such as the basic LAMP stack for WordPress and such, but I&#8217;ll get SVN, Mercurial, Git, Tomcat, NX, SFTP, my Pylons applications, and such back up later this week. Stay tuned.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/07/now-running-ubuntu/" data-text="now running Ubuntu" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/07/now-running-ubuntu/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F07%2Fnow-running-ubuntu%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/07/now-running-ubuntu/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/EYF-j6nFsuY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/07/now-running-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/07/now-running-ubuntu/</feedburner:origLink></item>
		<item>
		<title>installing lotus sametime on ubuntu 10.04 x64</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/t_-1kvAPOwQ/</link>
		<comments>http://charliemeyer.net/blog/2010/07/installing-lotus-sametime-on-ubuntu-10-04-x64/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 04:30:17 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[lotus]]></category>
		<category><![CDATA[sametime]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=69</guid>
		<description><![CDATA[Note: this is only applicable for IBM employees, since the download link is only accessible from the IBM network I previously wrote about how to install the AT&#38;T network client on Ubuntu 10.04 x64. If you are an IBM employee, the next logical step is to install lotus sametime for instant messaging. Luckily, at one [...]]]></description>
				<content:encoded><![CDATA[<p>Note: this is only applicable for IBM employees, since the download link is only accessible from the IBM network</p>
<p>I previously wrote about how to install the AT&amp;T network client on Ubuntu 10.04 x64. If you are an IBM employee, the next logical step is to install lotus sametime for instant messaging. Luckily, at one point in time IBM produced deb files for debian-like distributions that can still be used on 10.04. For this, i will assume that you have already followed the instructions to install the global network client, including installing getlibs.</p>
<p>First, download sametime 7.51 blue from <a href="http://pokgsa.ibm.com/projects/l/lud/pool/stable/s/sametime-blue/sametime-blue_7.5.1.20070416-4_i386.deb" target="_blank">http://pokgsa.ibm.com/projects/l/lud/pool/stable/s/sametime-blue/sametime-blue_7.5.1.20070416-4_i386.deb</a></p>
<p>Then run `sudo apt-get install libmotif3` and then `sudo getlibs -p libmotif3`</p>
<p>The next dependency is lib32stdc++5, so to install it you first have to add a ppa to your apt repositories using the command `sudo apt-add-repository ppa:jason-scheunemann/ppa`</p>
<p>You can then `sudo apt-get update` and then `sudo apt-get install lib32stdc++5`</p>
<p>Next you have to install the 64 bit version, so `wget  http://mirrors.kernel.org/ubuntu/pool/universe/g/gcc-3.3/libstdc++5_3.3.6-17ubuntu1_amd64.deb`  then `sudo dpkg -i libstdc++5_3.3.6-17ubuntu1_amd64.deb`</p>
<p>Lastly, `sudo dpkg -i &#8211;force-architecture sametime-blue_7.5.1.20070416-4_i386.deb`</p>
<p>Sametime should now show up in the applications menu under the other category. You can sign in using your IBM intranet id and password, although due to some library problems that I have not yet solved, certain preferences (such as password saving and location setting) do not work. Ill update this post if I end up solving these issues.</p>
<p>As always, YMMV. Good luck!</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/07/installing-lotus-sametime-on-ubuntu-10-04-x64/" data-text="installing lotus sametime on ubuntu 10.04 x64" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/07/installing-lotus-sametime-on-ubuntu-10-04-x64/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F07%2Finstalling-lotus-sametime-on-ubuntu-10-04-x64%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/07/installing-lotus-sametime-on-ubuntu-10-04-x64/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/t_-1kvAPOwQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/07/installing-lotus-sametime-on-ubuntu-10-04-x64/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/07/installing-lotus-sametime-on-ubuntu-10-04-x64/</feedburner:origLink></item>
		<item>
		<title>being academically honest</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/xBJiv5XGxDY/</link>
		<comments>http://charliemeyer.net/blog/2010/07/being-academically-honest/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 19:48:24 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[research]]></category>
		<category><![CDATA[comoto]]></category>
		<category><![CDATA[plagiarism]]></category>
		<category><![CDATA[slashdot]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=62</guid>
		<description><![CDATA[One of my research projects at UIUC is to develop new methods of automated plagiarism/collaboration detection and analysis in student programming assignment submissions. I work with a variety of people on the project, using a variety of technologies, and we have produced some interesting software that has led to interesting results. Eventually, we plan to [...]]]></description>
				<content:encoded><![CDATA[<p>One of my research projects at UIUC is to develop new methods of automated plagiarism/collaboration detection and analysis in student programming assignment submissions. I work with a variety of people on the project, using a variety of technologies, and we have produced some <a href="http://comoto.cs.illinois.edu" target="_blank">interesting software</a> that has led to interesting results. Eventually, we plan to roll this software out as a service to the CS department and greater campus, but those plans are still far in the future.</p>
<p>I&#8217;ve been working on this project now for a couple of years and have seen some of the lengths that students will go to to cheat. Being involved in this arena has led me to become very interested in how students cheat, why students cheat, and ways to detecting it. I came across <a href="http://www.citypages.com/2010-06-30/news/plagiarism-inc/" target="_blank">this article</a> today on <a href="http://slashdot.org" target="_blank">slashdot</a> that piqued my attention. Although this article has nothing to do with plagiarizing programming assignments, it nonetheless reminded me of what some will do to slide by in school. If you take a few minutes to peruse <a href="http://www.vworker.com" target="_blank">http://www.vworker.com</a>, I am positive that you will be able to find some cleverly disguised homework assignments that programmers from around the world are bidding on to complete, even when their <a href="http://www.vworker.com/RentACoder/SoftwareBuyers/BidReqestPostingPolicy.asp" target="_blank">terms of service</a> disallow these types of projects.</p>
<p>These hired-out homework assignments, at least in the computer science world, are in my opinion the toughest kind of plagiarism to detect automatically. Sure a manual inspection will bring it to light pretty quick, but in some of the classes we do analysis on there are 200-300 students, so a manual inspection of each assignment is just not feasible. At least for now, it appears that given the right circumstances, if students are willing to pay the cash anything is possible.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/07/being-academically-honest/" data-text="being academically honest" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/07/being-academically-honest/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F07%2Fbeing-academically-honest%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/07/being-academically-honest/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/xBJiv5XGxDY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/07/being-academically-honest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/07/being-academically-honest/</feedburner:origLink></item>
		<item>
		<title>Installing the AT&amp;T Global Network Client on Ubuntu 10.04 Lucid Lynx 64 bit</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/gyeRhEitzu4/</link>
		<comments>http://charliemeyer.net/blog/2010/06/installing-the-att-global-network-client-on-ubuntu-10-04-lucid-lynx-64-bit/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 16:22:55 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[AT&T Network Client]]></category>
		<category><![CDATA[lucid]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=56</guid>
		<description><![CDATA[The AT&#38;T global network client is a 32 bit application, that with a bit of messing with it will run perfectly fine on Ubuntu 10.04 64 bit. Here are the steps that I came up with that worked for me: make sure you have the 32 bit compatibility package installed, `sudo apt-get install ia32-libs` will [...]]]></description>
				<content:encoded><![CDATA[<p>The AT&amp;T global network client is a 32 bit application, that with a bit of messing with it will run perfectly fine on Ubuntu 10.04 64 bit.</p>
<p>Here are the steps that I came up with that worked for me:</p>
<ul>
<li>make sure you have the 32 bit compatibility package installed, `sudo apt-get install ia32-libs` will do the trick</li>
<li>Install getlibs from <a href="http://frozenfox.freehostia.com/cappy/getlibs-all.deb">http://frozenfox.freehostia.com/cappy/getlibs-all.deb</a></li>
<li>Download the client from <a href="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/agnclient-2.0.1-ubuntu.zip">agnclient-2.0.1-ubuntu</a></li>
<li>Unzip the file</li>
<li>from the command line, install all three packages using `sudo dpkg &#8211;force-all -i &lt;package.deb&gt;` &#8211; I installed agnclient_1.0.1-1_i386.deb first, then the gtk package, then the dev package</li>
<li>Use getlibs to install the necessary libraries. I only needed libssl, so I did `sudo getlibs -p libssl0.9.8`</li>
<li>I then had to create some symbolic links so that the client would work properly, so in /lib32, i ran `sudo ln -s libssl.so.0.9.8 libssl.so.4` and `sudo ln -s libcrypto.so.0.9.8 libcrypto.so.4`</li>
<li>To verify that everything works properly, I checked the linking of the various programs to ensure that they were linking against the proper libraries, here is what I got</li>
<li>chuck@silverstone:/opt/agns/bin$ ldd NetVPN<br />
linux-gate.so.1 =&gt;  (0xf7727000)<br />
libpthread.so.0 =&gt; /lib32/libpthread.so.0 (0xf76e5000)<br />
libssl.so.4 =&gt; /lib32/libssl.so.4 (0xf769f000)<br />
libcrypto.so.4 =&gt; /lib32/libcrypto.so.4 (0xf754b000)<br />
libdl.so.2 =&gt; /lib32/libdl.so.2 (0xf7547000)<br />
libc.so.6 =&gt; /lib32/libc.so.6 (0xf73ed000)<br />
/lib/ld-linux.so.2 (0xf7728000)<br />
libz.so.1 =&gt; /usr/lib32/libz.so.1 (0xf73d8000)</li>
<li>chuck@silverstone:/opt/agns/bin$ ldd agnclient<br />
linux-gate.so.1 =&gt;  (0xf773b000)<br />
libagnLogc.so.1 =&gt; /opt/agns/lib/libagnLogc.so.1 (0xf7736000)<br />
libagnc.so.1 =&gt; /opt/agns/lib/libagnc.so.1 (0xf772c000)<br />
libpthread.so.0 =&gt; /lib32/libpthread.so.0 (0xf76ec000)<br />
libm.so.6 =&gt; /lib32/libm.so.6 (0xf76c6000)<br />
libdl.so.2 =&gt; /lib32/libdl.so.2 (0xf76c2000)<br />
libgtk-x11-2.0.so.0 =&gt; /usr/lib32/libgtk-x11-2.0.so.0 (0xf72ed000)<br />
libgdk-x11-2.0.so.0 =&gt; /usr/lib32/libgdk-x11-2.0.so.0 (0xf7257000)<br />
libatk-1.0.so.0 =&gt; /usr/lib32/libatk-1.0.so.0 (0xf723a000)<br />
libgdk_pixbuf-2.0.so.0 =&gt; /usr/lib32/libgdk_pixbuf-2.0.so.0 (0xf7220000)<br />
libpangoxft-1.0.so.0 =&gt; /usr/lib32/libpangoxft-1.0.so.0 (0xf7218000)<br />
libpangox-1.0.so.0 =&gt; /usr/lib32/libpangox-1.0.so.0 (0xf720b000)<br />
libpango-1.0.so.0 =&gt; /usr/lib32/libpango-1.0.so.0 (0xf71c8000)<br />
libgobject-2.0.so.0 =&gt; /usr/lib32/libgobject-2.0.so.0 (0xf7188000)<br />
libgmodule-2.0.so.0 =&gt; /usr/lib32/libgmodule-2.0.so.0 (0xf7183000)<br />
libgthread-2.0.so.0 =&gt; /usr/lib32/libgthread-2.0.so.0 (0xf717d000)<br />
libglib-2.0.so.0 =&gt; /lib32/libglib-2.0.so.0 (0xf70b3000)<br />
libxml2.so.2 =&gt; /usr/lib32/libxml2.so.2 (0xf6f89000)<br />
libc.so.6 =&gt; /lib32/libc.so.6 (0xf6e2e000)<br />
/lib/ld-linux.so.2 (0xf773c000)<br />
libpangocairo-1.0.so.0 =&gt; /usr/lib32/libpangocairo-1.0.so.0 (0xf6e22000)<br />
libX11.so.6 =&gt; /usr/lib32/libX11.so.6 (0xf6d05000)<br />
libXcomposite.so.1 =&gt; /usr/lib32/libXcomposite.so.1 (0xf6d01000)<br />
libXdamage.so.1 =&gt; /usr/lib32/libXdamage.so.1 (0xf6cfd000)<br />
libXfixes.so.3 =&gt; /usr/lib32/libXfixes.so.3 (0xf6cf6000)<br />
libcairo.so.2 =&gt; /usr/lib32/libcairo.so.2 (0xf6c7c000)<br />
libgio-2.0.so.0 =&gt; /usr/lib32/libgio-2.0.so.0 (0xf6bde000)<br />
libpangoft2-1.0.so.0 =&gt; /usr/lib32/libpangoft2-1.0.so.0 (0xf6bb7000)<br />
libfreetype.so.6 =&gt; /usr/lib32/libfreetype.so.6 (0xf6b41000)<br />
libfontconfig.so.1 =&gt; /usr/lib32/libfontconfig.so.1 (0xf6b10000)<br />
librt.so.1 =&gt; /lib32/librt.so.1 (0xf6b07000)<br />
libXext.so.6 =&gt; /usr/lib32/libXext.so.6 (0xf6af7000)<br />
libXrender.so.1 =&gt; /usr/lib32/libXrender.so.1 (0xf6aed000)<br />
libXinerama.so.1 =&gt; /usr/lib32/libXinerama.so.1 (0xf6ae9000)<br />
libXi.so.6 =&gt; /usr/lib32/libXi.so.6 (0xf6ada000)<br />
libXrandr.so.2 =&gt; /usr/lib32/libXrandr.so.2 (0xf6ad2000)<br />
libXcursor.so.1 =&gt; /usr/lib32/libXcursor.so.1 (0xf6ac8000)<br />
libXft.so.2 =&gt; /usr/lib32/libXft.so.2 (0xf6ab4000)<br />
libz.so.1 =&gt; /usr/lib32/libz.so.1 (0xf6a9f000)<br />
libpcre.so.3 =&gt; /lib32/libpcre.so.3 (0xf6a6d000)<br />
libxcb.so.1 =&gt; /usr/lib32/libxcb.so.1 (0xf6a53000)<br />
libpixman-1.so.0 =&gt; /usr/lib32/libpixman-1.so.0 (0xf69f9000)<br />
libdirectfb-1.2.so.0 =&gt; /usr/lib32/libdirectfb-1.2.so.0 (0xf6982000)<br />
libfusion-1.2.so.0 =&gt; /usr/lib32/libfusion-1.2.so.0 (0xf6978000)<br />
libdirect-1.2.so.0 =&gt; /usr/lib32/libdirect-1.2.so.0 (0xf6961000)<br />
libpng12.so.0 =&gt; /lib32/libpng12.so.0 (0xf693c000)<br />
libxcb-render-util.so.0 =&gt; /usr/lib32/libxcb-render-util.so.0 (0xf6937000)<br />
libxcb-render.so.0 =&gt; /usr/lib32/libxcb-render.so.0 (0xf692f000)<br />
libresolv.so.2 =&gt; /lib32/libresolv.so.2 (0xf691b000)<br />
libselinux.so.1 =&gt; /lib32/libselinux.so.1 (0xf68ff000)<br />
libexpat.so.1 =&gt; /lib32/libexpat.so.1 (0xf68d8000)<br />
libXau.so.6 =&gt; /usr/lib32/libXau.so.6 (0xf68d4000)<br />
libXdmcp.so.6 =&gt; /usr/lib32/libXdmcp.so.6 (0xf68ce000)</li>
<li>you might need to install additional libraries, use getlibs to do it as shown above (my system had some libraries on it before I started the install that yours might not have)</li>
<li>restart the daemon with `sudo /etc/init.d/agnclientd restart`</li>
<li>try opening the client from the applications menu under the internet category and connecting</li>
<li>If something goes wrong, check the logs in /var/log/agns</li>
</ul>
<p>Good Luck!</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/06/installing-the-att-global-network-client-on-ubuntu-10-04-lucid-lynx-64-bit/" data-text="Installing the AT&#038;T Global Network Client on Ubuntu 10.04 Lucid Lynx 64 bit" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/06/installing-the-att-global-network-client-on-ubuntu-10-04-lucid-lynx-64-bit/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F06%2Finstalling-the-att-global-network-client-on-ubuntu-10-04-lucid-lynx-64-bit%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/06/installing-the-att-global-network-client-on-ubuntu-10-04-lucid-lynx-64-bit/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/gyeRhEitzu4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/06/installing-the-att-global-network-client-on-ubuntu-10-04-lucid-lynx-64-bit/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/06/installing-the-att-global-network-client-on-ubuntu-10-04-lucid-lynx-64-bit/</feedburner:origLink></item>
		<item>
		<title>even programmers have some humor</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/DMkzplm1_Hk/</link>
		<comments>http://charliemeyer.net/blog/2010/06/even-programmers-have-some-humor/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 23:02:28 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/blog/?p=49</guid>
		<description><![CDATA[I run Linux on all my personal computers (including the server that hosts this blog), except my media center pc (Linux is a bit behind for watching high definition movies, especially for digital audio like Dolby TrueHD and DTS Master Audio). I absolutely love Ubuntu, so when I rediscovered this today it made me laugh. [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/safe_image.php_.png"><img class="alignleft size-full wp-image-50" title="safe_image.php" src="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/safe_image.php_.png" alt="" width="64" height="64" /></a>I run Linux on all my personal computers (including the server that hosts this blog), except my media center pc (Linux is a bit behind for watching high definition movies, especially for digital audio like Dolby TrueHD and DTS Master Audio). I absolutely love Ubuntu, so when I rediscovered this today it made me laugh.</p>
<p><strong><a rel="nofollow" href="https://launchpad.net/bugs/1" target="_blank">Bug #1 in Ubuntu: “Microsoft has a majority market share”</a></strong></p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/06/even-programmers-have-some-humor/" data-text="even programmers have some humor" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/06/even-programmers-have-some-humor/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F06%2Feven-programmers-have-some-humor%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/06/even-programmers-have-some-humor/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/DMkzplm1_Hk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/06/even-programmers-have-some-humor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/06/even-programmers-have-some-humor/</feedburner:origLink></item>
		<item>
		<title>why not use standard widgets?</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/d7QAeJmi2NU/</link>
		<comments>http://charliemeyer.net/blog/2010/06/why-not-use-standard-widgets/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 21:01:49 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[HMC]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.charliemeyer.net/?p=39</guid>
		<description><![CDATA[This summer I am working on a project to design and build automated functional tests of some of IBM&#8217;s web interfaces that act as control panels for their servers. This appears to be a fairly straightforward task: figure out what the test should do, use the tools to write the test, and debug the test [...]]]></description>
				<content:encoded><![CDATA[<p>This summer I am working on a project to design and build automated functional tests of some of IBM&#8217;s web interfaces that act as control panels for their servers. This appears to be a fairly straightforward task: figure out what the test should do, use the tools to write the test, and debug the test until it works properly. Oh if only life were so easy&#8230;. Due to some design choices in IBM&#8217;s hardware management console software, the process has been extended with an additional step: figure out what the test should do, modify the tools so they can do what they need to, use the modified tools to write the test, and then debug the test until it works properly. Rather than ranting on forever and ever, I figure a picture is worth a thousand words, so here it is, IBM&#8217;s HMC interface in all its glory:</p>
<p><a href="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/welcome.png"><img class="aligncenter size-medium wp-image-38" title="welcome" src="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/welcome-300x199.png" alt="" width="300" height="199" /></a></p>
<p style="text-align: left;"><a href="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/welcome.png"><img class="aligncenter size-medium wp-image-38" title="welcome" src="http://www.charliemeyer.net/wp-content/uploads/2010/06/welcome-300x199.png" alt="" /></a>Above is the welcome screen, which is innocent enough. Nothing major here to report that personally makes my life difficult. I just felt that it would be too one-sided if all I did was complain. Now, lets get on to the stuff that makes you wonder why was this done?</p>
<p>What we have here is my first example of non-standard widgets that cause me problems. If you look at the screenshot carefully, <a href="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/servers.png"><img class="alignright size-medium wp-image-37" title="servers" src="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/servers-300x74.png" alt="" width="300" height="74" /></a>you might notice two places that seem perfectly normal at first but at closer inspection are just not quite right. Were you thinking about the check box in the table and the drop down combo box in the upper right corner? These widgets are actually images that are manipulated with fancy Javascript to appear as normal as possible. The tools we are using support standard widgets, things built with input tags, fancy JS is just a pain to test. Plus, imho, it makes the interface feel much more sluggish. Every time one of these widgets is manipulated there is a definite delay before any feedback is presented to the user.</p>
<p><a href="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/asm1.png"><img class="alignleft size-medium wp-image-35" title="asm1" src="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/asm1-300x163.png" alt="" width="300" height="163" /></a>Now, let&#8217;s get on to another example. In the images below, there is another example of a drop down combo box that is implemented purely with image tags and Javascript. What is worse about this particular example, is that upon changing the value of the combo box, the entire page reloads to fill in the new value. This is because the combo box options are implemented by hyperlinks that when clicked, redirect the browser to a new page that has the previously clicked link as the selected option.</p>
<p>Now its not that I am angry with the way this was designed or that I am overly critical of it, but it raises <a href="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/asm2.png"><img class="alignright size-medium wp-image-36" title="asm2" src="http://www.charliemeyer.net/blog/wp-content/uploads/2010/06/asm2-300x161.png" alt="" width="300" height="161" /></a>the question, are the standard widgets that we are provided by our programming APIs sufficient for most uses? On the internet, I would say that overwhelmingly the widgets that are built into the browser are fantastic for 95% of whats out there. I mean, realistically, how often do you see someone reinventing a textbox with some Javascript ninja magic. The answer: never. Why? Because the ones built into the browser are already good enough at what they do. Alright alright, some things just cannot be done with standard widgets in a web browser, things like date pickers and sliders, but why reinvent the wheel when it is not necessary? The only thing that I could think of for this particular case was that using homegrown widgets improved cross-browser compatibility in some way that I couldn&#8217;t imagine. If I find out the answer to this question, I&#8217;ll try to remember to put it up here.</p>
<p>But back to my basic question, are when are standard widgets not enough? I guess there are lots of times the more I think about it, but lots of times in a sea the size of an ocean is still a limited amount. Then that also raises the question, what does it take to consider a widget to be &#8220;standard&#8221;? All the major web browsers implement the widgets slightly differently, especially between different platforms. And take Java for instance, built into the language are two widget libraries, AWT and Swing, which I would argue are Java&#8217;s &#8220;standard&#8221; widgets. But there exists a popular add on library confusingly named the Standard Widget Toolkit (SWT), so what is a newcomer to think? I think Ill come back to this question later.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/06/why-not-use-standard-widgets/" data-text="why not use standard widgets?" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/06/why-not-use-standard-widgets/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F06%2Fwhy-not-use-standard-widgets%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/06/why-not-use-standard-widgets/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/d7QAeJmi2NU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/06/why-not-use-standard-widgets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/06/why-not-use-standard-widgets/</feedburner:origLink></item>
		<item>
		<title>Rational Rational Rational</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/FDgqnR11nto/</link>
		<comments>http://charliemeyer.net/blog/2010/06/rational-rational-rational/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 21:13:17 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[Rational]]></category>
		<category><![CDATA[RFT]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.charliemeyer.net/?p=12</guid>
		<description><![CDATA[So this summer I&#8217;ve been working with (and will continue to work with) an entire suite of IBM Rational tools, so I thought I would write down a few first impressions of this, seemingly, popular software. Ill start with just one today, and hopefully add more reviews as the summer progresses. My one overwhelming gripe [...]]]></description>
				<content:encoded><![CDATA[<p>So this summer I&#8217;ve been working with (and will continue to work with) an entire suite of IBM Rational tools, so I thought I would write down a few first impressions of this, seemingly, popular software. Ill start with just one today, and hopefully add more reviews as the summer progresses.</p>
<p>My one overwhelming gripe about all the Rational software is that it is all based on Eclipse. Yes I know, IBM originally wrote Eclipse and donated it as open source, but Eclipse is a resource hog that tends to quickly run out of control. Rational Functional Tester, Rational Performance Tester, Rational Team Concert Client, Rational Software Modeler, and more are all Eclipsed based. Oh, and as if that wasn&#8217;t enough, so is the installer for each of them (add that to the Eclipsed-based Lotus Symphony that IBM has us use for office documents and Eclipse-based Lotus Notes for email and collaboration, and my laptop is out of memory before I can even start coding). Whats worse in my opinion, is that as you incrementally install each Rational Tool, they build on each other into some mega Eclipse monstrosity rather than stay separate as their own installs. This beast then takes forever to load, oh yeah, and a lot more memory to run.</p>
<p>Rational Functional Tester: All I can say is, it does the job, but makes it painful. Ever since I started writing software, user interfaces were always the most challenging aspects to test. Simulating clicking on something, checking the appearance of a window, etc is no small task, which is why I have seen several project groups that I have mentored at school resort to manual testing for this kind of thing. RFT allows a developer to write functional &#8220;test scripts&#8221; in Java or VB.net which guide RFT to interact with another application. One great aspect of RFT is that, well only on Windows, it has a recorder feature which allows the developer to interact with the software and have RFT record what was done. The developer can also insert checkpoints into the recording where he can instruct RFT to compare various attributes of objects in the application to baseline readings to judge if a test passed or not. Another handy feature I wish I had back when I was working on AS400s is the ability to test command line applications and terminal applications both on System Z mainframes and IBM i 5250 green screens. But enough of the good stuff, heres what I&#8217;m not so fond of&#8230;..First off, let me say that I use RFT purely for testing web applications, so this experience is only based on RFT&#8217;s ability to work with the webapps that I am trying to test. So, my biggest gripe with RFT is a lack of consistency. Often times when I&#8217;m writing up a test script, I have code that I am positive will work, but it just plain wont. So ill restart the browser under test, sometimes that will fix it, or Ill restart RFT, sometimes that works, but most often I end up rebooting my entire machine to fix some stupid error. Oh yeah, Im working on windows testing using IE6, so that may have a lot to do with it, but RFT should be better. Second problem, RFT doesnt support many browsers. Hence why we are using IE6 at work (because the webapp under test doesnt behave well with firefox, sigh). Next, although the recorder is great for simple tests, it just isnt powerful enough to do many of the tests that we want to do, so we code every test script by hand, which leads me to my final gripe&#8230;.Horrible API. I won&#8217;t even sugarcoat it, its not fun at all to deal with. In my opinion, it is far to generalized and leave the burden on the developer to do most of the work. There is even an internal IBM project which has developed a layer that sits on top of the RFT API and exposes a simpler API for webapp testers, but this layer doesnt cover everything. It can take 30-40 lines of code just to find a hyperlink on a webpage and click on it. Not cool. So overall, RFT is alright, it does the job, but can be a pain to work with. Ill try to update here more over the next few weeks with my impressions of the other Rational tools I&#8217;m using.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/06/rational-rational-rational/" data-text="Rational Rational Rational" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/06/rational-rational-rational/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F06%2Frational-rational-rational%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/06/rational-rational-rational/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/FDgqnR11nto" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/06/rational-rational-rational/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/06/rational-rational-rational/</feedburner:origLink></item>
		<item>
		<title>up close and personal with blue waters</title>
		<link>http://feedproxy.google.com/~r/CharlieOnSoftware/~3/H-f4FZs6w3Q/</link>
		<comments>http://charliemeyer.net/blog/2010/06/up-close-and-personal-with-blue-waters/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 21:05:24 +0000</pubDate>
		<dc:creator>charlie</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[Blue Waters]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[supercomputing]]></category>

		<guid isPermaLink="false">http://blog.charliemeyer.net/?p=4</guid>
		<description><![CDATA[this afternoon I got an up close and personal look into the hardware for the new Blue Waters supercomputer that will soon be coming to the University of Illinois. Not only was I impressed by the sheer amount of processing power each of the boards has, but also their sheer size. Picture a typical 1U [...]]]></description>
				<content:encoded><![CDATA[<p>this afternoon I got an up close and personal look into the hardware for the new Blue Waters supercomputer that will soon be coming to the University of Illinois. Not only was I impressed by the sheer amount of processing power each of the boards has, but also their sheer size. Picture a typical 1U rackmount server, keep the height, double the width, and triple the depth, then you have one of the boards going into blue waters. I was able to spend some time with some of the people in the IBM labs that are working on bringing up these boxes so that they will be ready to ship down to school soon, and was able to learn a lot about the power distribution characteristics, system topology, and how the massive things are cooled. I&#8217;m looking forward in the future to seeing blue waters come online at school and hopefully sometime get a chance to mess around with it a bit.</p>
<div id="social-essentials" class="se_left"><div class="se_button se_button_small" style="width:85px;margin:0px 0px 0px 0px"><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://charliemeyer.net/blog/2010/06/up-close-and-personal-with-blue-waters/" data-text="up close and personal with blue waters" data-via="cemeyer2" data-counturl="http://charliemeyer.net/blog/2010/06/up-close-and-personal-with-blue-waters/" data-count="horizontal" data-lang="en">Tweet</a></div><div class="se_button se_button_small" style="width:72px;margin:0px 0px 0px 0px"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href=http%3A%2F%2Fcharliemeyer.net%2Fblog%2F2010%2F06%2Fup-close-and-personal-with-blue-waters%2F&amp;send=false&amp;layout=button_count&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font" scrolling="no" frameborder="0" allowTransparency="true"></iframe></div><div class="se_button se_button_small" style="width:60px;margin:0px 0px 0px 0px"><g:plusone size="medium" href="http://charliemeyer.net/blog/2010/06/up-close-and-personal-with-blue-waters/" count="true"></g:plusone></div></div><div class="clear"></div><style type="text/css">#call_to_action h4{padding:0px 5px;}</style><img src="http://feeds.feedburner.com/~r/CharlieOnSoftware/~4/H-f4FZs6w3Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://charliemeyer.net/blog/2010/06/up-close-and-personal-with-blue-waters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://charliemeyer.net/blog/2010/06/up-close-and-personal-with-blue-waters/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced

Served from: charliemeyer.net @ 2012-12-19 11:16:35 -->
