Archive for the ‘Uncategorized’ Category

A Better CAPTCHA

Wednesday, May 14th, 2008

I don’t yet have any need to implement CAPTCHA myself, but if I did, it wouldn’t be your standard distorted and scribbled on text. It would be one of these:

Microsoft Asirra

With Asirra, to identify yourself as a human you have to identify a series of pictures as cats (excluding the dogs). It seems like a sound approach, but on the face it looks so nonsensical that I feel compelled to use it. Picture this internet argument: “Well you plainly have no idea what you’re talking about on this issue, so I won’t keep wasting my valuable time trying to fight with your stupidity! As soon as I click on these cats, you’ll never hear from me again!”

reCAPTCHA

This one is more serious, and has a purpose too. Instead of displaying random obscured characters, it displays a real scanned image of two words from an old book. One of these words has been identified and the other has not. The user types both words, the computer verifies the user’s humanity with the known word, and records what the human said the unknown word was. Through this process the un-digitized book becomes completely digitized. They’re turning CAPTCHA tests, a “lesser evil” annoyance, into something that’s actually good.

Why so many microsoft shops?

Tuesday, May 13th, 2008

While looking for a job, I’ve been surprised by the number of places developing on a Microsoft platform. I didn’t know that it was so common, at least in Chicago. If you’re using a Microsoft OS, service, or language and it works for you then great, but aren’t there open source alternatives that are just as good and not as expensive? Especially MS SQL server; whenever I see that I can’t help but wonder why they aren’t using MySQL or Postgresql. Does anyone reading this work in the Microsoft world at work? What keeps your company there?

Rot13 Utility

Friday, January 11th, 2008

Rot13 is a common method for obfuscating text, often used to randomize passwords or to hide “spoilers” from online discussions. The tool I most commonly use to translate rot13′d text is http://www.rot13.com/, and that works well for translating long sections of ciphertext back in to plaintext. However, often there is just one or a few words to be translated from plaintext to ciphertext, and I find the site to be too much overhead for the task.

That’s why I made a simple php script on my website to do my rot13 translations from now on. The key difference between mine and rot13.com is that the form on mine uses the GET method rather than POST. This allows me to make a firefox bookmark to translate text directly from the url bar. To do this, bookmark this url: http://timsaylor.com/tools/rot13.php?plaintext=%s. Then in the bookmark’s properties add a value to the keyword field. My keyword is “rot”, so now whenever I type “rot [text]” into my url bar, it sends that to my script and opens a page with the ciphertext.

It’s just a simple utility, and writing this blog post about it took longer than actually making the script itself. I just had to rot13 something today, though, and I remembered wishing that I could do it more simply. A quick search turned up this rot13 php function, which meant all the hard work was done. I just wrapped that up in an html form and put it online. The source is here.

Internet Famous

Thursday, November 1st, 2007

Today I was informed that a project that Dan and I collaborated on recently received a bit of attention on the internets. Our “In Case of Revolution Break Glass” box, pictured below.

Mask box

Dan had the idea, I did the woodwork, and Dan painted and lettered. One major reason that Dan wanted to make this was so he could post it on a “Show off stuff you’ve made” thread on Something Awful. From there it was cross posted to Digg (edit: and made the #1 spot apparently!), then on to this blog, which was Reddited, and then on to College Humor today. There were many more too, 3,580 hits on Google. The only credit we got was someone in the digg comments saying “This is from Something Awful, a goon did it” (half true), but that’s to be expected. I’m still pleased. And next time it’ll say “timsaylor.com” across the bottom. :-)

Using Screen for Unreliable Connections

Friday, June 8th, 2007

The other day I was working in a coffee shop and their internet connection went down a couple times. Unfortunately, I was ssh’ed into another box where my work was. Fortunately, I was using screen. I figured my session would disconnect and be sitting there ready for me to reconnect when the link came back up. Sure enough, it was. Saved me a lot of hassle reopening my files and saving more frequently. Here’s the article that describes how to reconnect to a lost screen session after your ssh session times out (not that it’s that difficult, but I’m sure I’ll forget and have to reference this).

Proxying web.py through apache

Sunday, April 29th, 2007

I’ve been wanting to try web.py for a while. It seems like it’s easier to learn than Django for making python web applications. I made the hello world app quickly and simply, and decided I’d use it for a project I’m working on.

That’s when it turned south. I have to use php for another project I’m doing, and I use cgi-irc (in perl through CGI) on that server, so I didn’t want to re-setup all that stuff on lighttpd (the recommended method for running web.py). I tried running it through apache with cgi. After a few hours of that not working I switched to trying fastcgi on apache, also to no avail. I got fastcgi to the point where I was having an error that was common enough to be in an FAQ: I was getting 500 responses from apache because fastcgi/web.py wasn’t starting fast enough for the flup WSGI library to realize it, so it would start them over and over until it eventually gave up. I decided I just wanted to see the thing work at this point, so I installed lighttpd and went through the setup for that. When that method didn’t work I was fed up with their install instructions. I decided to try a method that John Quigley recommended. He said I should just run it with the internal http server that I’ve already used successfully and proxy the requests through apache to web.py. This might not achieve the goal of making the server large scale production ready, but I don’t really have to worry about that so much at this point. It does achieve my more important goal of making my php, cgi, and web.py applications all available through a single url and port, so I gave it a shot.

I looked up apache proxying and found it was done through mod_proxy, and each protocol you want to proxy has it’s own module as well. So I installed mod_proxy and mod_proxy_http and added the following line to my apache2.conf file:


ProxyPass /lifelog http://192.168.1.20:8888

192.168.1.20 being the IP address of the server in question. It would be better to get it resolving localhost so this line can be used on other servers, but I didn’t want to bother with it yet. I also had to change the proxy permission rules in proxy.conf to this:


ProxyRequests Off

<Proxy *>
AddDefaultCharset off
Order allow,deny
Allow from all
</Proxy>

This allows any user online to use my ProxyPass rule. Note that I left “ProxyRequests” set to “Off”. If I turned that on, I would be an open proxy that spammers and hackers could use to hide their identity during their nefarious behavior.

Now all that’s left is to start up my web.py server on port 8888 as specified in apache2.conf and whenever I go to /lifelog/* through apache, it’ll send the request to web.py.

Cgi::irc and Ubuntu

Thursday, April 26th, 2007
I don’t like using Pidgin(Gaim) or Mirc for an irc client when I’m on windows, and I’d rather just not bother having a client on whatever machine I’m using in general, so I usually install cgi::irc on a server and use that. I recently reinstalled Ubuntu on my server and had to reinstall cgi::irc. After that, when I tried to connect to any server I kept getting the error:




***Access Denied: No connections allowed


I tried to find an error log somewhere on the system but there wasn’t one. Eventually I grepped the source for “No connections allowed” and found it on line 715 of nph-irc.cgi. This is in the code to handle ip access restrictions. So I go to the config file and find a file called “ipaccess” which only contains a rule to allow connections from 127.0.0.1. This was the problem. I didn’t care about ip restrictions, so I went to the main config file and commented out the line:




ip_access_file = ipaccess


Now I can log in to my cgi::irc no problem. I could also have added more rules to “ipaccess”, but I didn’t want to fiddle with it, and I’d probably end up with the same situation as I have now.



It’s important to note that the default Ubuntu (7.04 Feisty Fawn) cgi::irc package comes configured like this and doesn’t tell you that you have to change it in order to make it useful. Maybe this should have a configuration prompt on installation as is done with packages like Postfix.

Python User-Defined Exceptions and Error Handling in Python DbAPI 2.0

Thursday, April 26th, 2007

I just spent some time figuring out how to handle exceptions using the pysqlite library. I couldn’t find a good description of how it works online, so I’m making one.

In python, all exceptions are classes. This means they can use any of the capabilities that regular python classes have, but generally all they do is define a few instance values in the __init__ method. These values are available in the exception object (the instance of the exception class) when it is caught in a “try … except” block.

If you’re receiving a user defined exception from a foreign module and don’t know how to handle it, I’d recommend first wrapping the offending code in a “try…except” like this:

try:
    c.execute(sql)
except:
    logfile.write(”ERROR: %s %s %s” % (sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))

The function sys.exc_info() returns a tuple containing 1) the type of exception being handled, 2) the associated parameter (usually some helpful descriptor), and 3) a traceback to where the exception occurred.

This hopefully tells you two things: a description of why this happened, and more importantly for my situation, the exception type. When I ran that I got something like this:

ERROR: <class ‘pysqlite2.dbapi2.OperationalError’> table something already exists <traceback object at 0xb7da3cd4>

So the exception being raised was at pysqlite2.dbapi2.OperationalError. Since the python dbapi returns sql errors through exceptions I can’t just fix the code here, I have to “try … except” it. Here’s what the final code snippet looked like:

try:
    c.execute(sql)
except pysqlite2.dbapi2.OperationalError, msg:
    logfile.write(”ERROR: %s” % msg)

To catch the other exceptions specified in the dbapi v2.0, you’d have to include several more exception handlers. The other exception classes are in the same location as the OperationalError class.

Further reading:

Version 2.0

Thursday, April 26th, 2007

I’m restarting this blog with a new focus. Before I would post amusing happenings and general bloggy type things, but now I’ve moved that to my livejournal (a much better place for that type of blog) and this will be exclusively for talking about ideas and technologies about anything, from software to ancient Greek siege weapons. I’m mostly writing these things down for my benefit, but maybe the information will be useful to someone else too.

Today in the news

Friday, June 3rd, 2005
  • Net porn plan labelled ‘obscene’: Because, as we all know, ICANN’s job is to help humanity. I think .xxx is a good idea. It’ll make it clear what you’re going to see if you click on a link, and it makes it easy to filter porn from a computer by just blocking .xxx links. This of course assumes that porn is forbidden (and that ban is effective) on other tld’s. However, putting the issue aside, ICANN is not supposed to “[give] priority to socially positive domain name proposals” because then, someone has to decide what’s socially positive and I’m sure Mr. Auerbach and I would disagree on what is socially positive.
  • Niger scorns ‘free food’ demands: What a bunch of commies! They’re all mad because they don’t have any food and the government won’t give it to them.
    The organisers of the march, the Democratic Co-ordination of Niger Civil Society (CDSN), accuse the government of not doing enough to prepare for the “hungry season” which was bound to follow a poor rainy season last year. The rainy season finished last October and it was obvious that supplies would not last through until the next harvest, they say.

    I accuse the Nigerians of not doing enough to prepare their own families for the “hungry season” that was “obviously” coming.

  • Babies in freezer shock Austria: This doesn’t come as a surprise to me, Austria’s pretty close to Germany.