Note: this is adapted from http://justin-hayes.com/2009-04-08/installing-apache-tomcat-6-and-solr-nightly-on-ubuntu-804.

Install Java 6 JDK:

sudo apt-get install sun-java6-jdk

First off, forget about using the Ubuntu packages of Tomcat and Solr, they’re broken, as well as outdated. Download the latest release of Tomcat from their site, and grab a nightly build of Solr from here using wget or whatever method you prefer. Untar both of them in your home directory.

wget http://www.eng.lsu.edu/mirrors/apache/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.tar.gz

tar xfzv apache-tomcat-6.0.20.tar.gz
wget http://people.apache.org/builds/lucene/solr/nightly/solr-2009-08-11.tgz
tar xfzv solr-2009-08-11.tgz

Now, move Tomcat to wherever you want to have it installed, I chose to put it in /usr/local/tomcat6.

sudo mv apache-tomcat-6.0.20/ /usr/local/tomcat6/

Next, copy the Solr .war file from apache-solr-nightly/dist/ to the webapps/ directory of tomcat6/, and the example webapp from apache-solr-nightly/example/solr/ to the tomcat6/ root directory.

sudo cp apache-solr-nightly/dist/apache-solr-nightly.war /usr/local/tomcat6/webapps/solr.war
sudo cp -r apache-solr-nightly/example/solr/ /usr/local/tomcat6/solr/

Now that all the files are in place, we need to create a config file to run Solr.

sudo mkdir /usr/local/tomcat6/conf/Catalina/
sudo mkdir /usr/local/tomcat6/conf/Catalina/localhost/
sudo nano /usr/local/tomcat6/conf/Catalina/localhost/solr.xml

In this file, insert the following code:

<Context docBase=”/usr/local/tomcat6/webapps/solr.war” debug=”0″ crossContext=”true” >
   <Environment name=”solr/home” type=”java.lang.String” value=”/usr/local/tomcat6/solr” override=”true” />
</Context>

Edit your .bashrc file in your home directory and add the following to it:

export JAVA_HOME=/usr/lib/jvm/java-6-sun
export JAVA_OPTS=”$JAVA_OPTS -Dsolr.solr.home=/usr/local/tomcat6/solr

If all went well, you should be able to start Tomcat and browse to http://your.servers.ip:8080/solr/admin and see the Solr admin page.

/usr/local/tomcat6/bin/startup.sh

If this worked, great, but now it’s time to get Tomcat to autostart itself when your server reboots. First, open a new script in your /etc/init.d/ directory.

sudo nano /etc/init.d/tomcat6

Insert the following code:

# Tomcat auto-start
#
# description: Auto-starts tomcat
# processname: tomcat
# pidfile: /var/run/tomcat.pid

export JAVA_HOME=/usr/lib/jvm/java-6-sun
export JAVA_OPTS=”$JAVA_OPTS -Dsolr.solr.home=/usr/local/tomcat6/solr

case $1 in
start)
   sh /usr/local/tomcat6/bin/startup.sh
   ;;
stop)
   sh /usr/local/tomcat6/bin/shutdown.sh
   ;;
restart)
   sh /usr/local/tomcat6/bin/shutdown.sh
   sh /usr/local/tomcat6/bin/startup.sh
   ;;
esac
exit 0

Finally, to make sure it autostarts, run this command:

sudo update-rc.d tomcat6 start 91 2 3 4 5 . stop 20 0 1 6 .

Congratulations! If you’ve followed this how-to exactly, you should have a working install of Apache Tomcat and Solr.

Links I got tips from:

http://wiki.apache.org/solr/SolrTomcat

http://www.tc.umn.edu/~brams006/solr_ubuntu.html
http://www.howtogeek.com/howto/linux/installing-tomcat-6-on-ubuntu/
http://lethain.com/entry/2009/mar/06/solango-and-tomcat-6-on-ubuntu-intrepid/
http://markmail.org/message/2xxiyry4y42hpodd
http://ubuntuforums.org/showthread.php?t=194559

This is a Python script to check a mailbox for Twitter emails. New followers are followed. Direct messages from administrators (defined in a list) are twittered by the bot.

import twitter

import logging

from imaplib import *
from email.Parser import Parser
import datetime, time, email, email.Utils
import re

import settings

# logging
logging.basicConfig(filename=settings.LOG_FILENAME,level=logging.DEBUG,)
logger = logging.getLogger('artandcode_twitter')

logger.debug('starting')
try:
    # Connect to email server
    server = IMAP4(settings.MAIL_SERVER)
    server.login(settings.EMAIL_USERNAME, settings.EMAIL_PASSWORD)
    r = server.select("INBOX")

    # Find all mail
    r, data = server.search(None, "(ALL)")

    # If there are messages in inbox
    if len(data[0]) > 0:

        api = twitter.Api(username=settings.TWITTER_USERNAME, password=settings.TWITTER_PASSWORD)

        p = Parser()

        # Loop through emails in inbox
        for num in data[0].split():

            r, fetch_data = server.fetch(num,
            '(BODY[HEADER.FIELDS (DATE SUBJECT FROM X-TwitterEmailType X-TwitterSenderScreenName X-TwitterCreatedAt X-TwitterRecipientScreenName)])')
            msg = p.parsestr(fetch_data[0][1])
            who = msg.__getitem__('From')
            matchemail = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}')
            email_addy = matchemail.findall(who)[0]

            twitter_sender_screen_name = msg.__getitem__('X-TwitterSenderScreenName')

            if msg.__getitem__('X-TwitterRecipientScreenName') == settings.TWITTER_USERNAME:
                # if the message is a following message
                if msg.__getitem__('X-TwitterEmailType') == 'is_following':

                    # follow the user
                    api.CreateFriendship(twitter_sender_screen_name)

                # If the email is a direct message sent from Twitter
                if msg.__getitem__('X-TwitterEmailType') == 'direct_message':
                    # if the sender is an administrator
                    if [twitter_sender_screen_name in settings.ADMINISTRATORS]:
        	               # When direct message sent, convert to epoch seconds
                        twitter_time = msg.__getitem__('X-TwitterCreatedAt').strip()
                        time_tuple = email.Utils.parsedate(twitter_time)
                        epoch_seconds = time.mktime(time_tuple)

                        # Get body of email sent by Twitter
                        r, body_data = server.fetch(num, '(RFC822.TEXT)')
                        body = body_data[0][1]
                        twitter_direct_message = body.split("\r\n\r\n")[0].strip()

                        api.PostUpdate(twitter_direct_message[:140-1])

        # copy the messages out of the INBOX
        server.copy(','.join(data[0].split(' ')), 'PROCESSED')

        # mark the messages as deleted
        # Loop through emails in inbox
        for num in data[0].split():
            server.store(num, '+FLAGS', '\\Deleted')

        # expunge the messages. Not sure if this is needed
        server.expunge()

    # delete the messages on close
    server.close()

    # Logout of email server
    server.logout()
except Exception, error:
    logger.exception(str(error))

logger.debug('finished')

These instructions will install PIL properly on Mac OS X 10.5. The instructions are adapted from here.

Go to here and download PIL.

Now we set up the environment so that you can install it.

In Terminal, create a symbolic link for the system’s Python.framework
in the location expected by the pythonmac.org tools, like so:

cd /Library/Frameworks
sudo ln -s /System/Library/Frameworks/Python.framework/ Python.framework

Now run the installer. It should not complain and it should install successfully.

The final step installs PIL in your Python site packages.

cd /Library/Python/2.5/site-packages/
echo "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages
" > PIL.pth

Test your new PIL install with:

python -c "from PIL import Image"

if you do not get an error, then you have a correct PIL install!

I recently deployed a Django 1.0.2 site using mod_python. Turns out this was a mistake. I should have used mod_wsgi. Mod_python is no longer under development. See Django ticket about recommending mod_wsgi.

[Corrected: wrong link]

The link on the website is broken, the correct link is: mod python mailing list archives

Another algorithmic drawing program hit the scene this week in Top Draw, a Mac-only program from Google. Much like Processing or OpenFrameworks, it provides a language to write code that produces images.

Top Draw was developed by one Dan Waylonis. You write object-oriented JavaScript code that is translated into images. The object-orientation differs from Processing and OpenFrameworks (and OpenGL and JOGL), where you write using the methods of one big class. And the methods are different. So for someone used to Processing-style methods (which are shared with OpenFrameworks), it’s a bit of a learning curve.

The big thing that Top Draw brings to the table is access to Apple’s CoreImage filters. Among other things, they allow you to transform 2D space with bumps and holes. Processing does not have this stuff built in, and I don’t think anyone has created a library to either use CoreImage on the Mac, or implemented the filters in Java. It would be cool stuff. ActionScript also has filters.

There’s some confusing extra functionality that lets you make a drawing your desktop image, or rotate through drawings. Neat, but really almost a separate program.

Top Draw is written in C and is licensed under the apache 2.0 license. The source code and the download is available on Google code.

So is it a Processing killer? I don’t think so. On the plus side has the CoreImage filters going for it. On the other hand, the language is awkward. The biggest issue is that it’s not a web application; even though you write in JavaScript, the library itself is in C. Processing sketches can be shown on the web using the moribund Java applet technology, and ActionScript can create Flash applications. It seems to me that almost everything must run on the web these days. Processing even has a JavaScript implementation (processing.js) that lets you run sketches using JavaScript in the browser. In this way it’s more like OpenFrameworks or OpenGL, which can’t run in a browser. And of course Top Draw only runs on Mac.

All in all, a good way to play with CoreImage filters.

Imagine that you could get people to do valuable things for you for free, like writing and distributing book reviews. That’s exactly what’s happening on the web today. Clay Shirky, in his book ‘Here Comes Everybody’, looks at the effects of the internet on producing economic value without the effort and expense of establishing an organization. He argues that the cost of organizing certain activities, such as publishing book reviews, has fallen to almost zero. Web services, such as Flickr, blogger.com, Amazon reviews, and Wikipedia are successful because they allow people to voluntarily contribute to a goal with minimal organizational effort.

Many of the examples in the book are well known (though some, like the use of blogs to organize protests in Belarus, are less known and wonderful). What makes Shirky’s book useful is the analysis that he does of the examples. Various models are proposed; a particularly useful model is promise, tool, bargain. He argues that a new group makes a promise (‘lets put together photos of mermaid parades’), then provides tools to achieve that promise (Flickr), then makes bargains to achieve the goal (the agreement not to post off-topic images).

A quick read for a pretty good payoff.

Here Comes Everybody: The Power of Organizing Without Organizations

I created a tracking map for Tour Divide that lets you see aerial views.

The new version of Processing includes better XML manipulation and a way to load an SVG from memory. Thus, new avenues are opened for incorporating drawings into Processing sketches.

Here are some first results. The XML parser / SVG renderer is efficient enough to support high framerates.




Source code, originally uploaded by chazmatazz.

I have posted some processing sketches in the processing.org flickr group. I create a random set of RGB colors and then place them in the correct location in a 3D RGB colorspace (so the coordinate and the colors are the same). The user then uses the mouse to move the colorspace around the window, creating a drawing. The source code is only 48 lines.