pylibmc now on GitHub!

My Python bindings for the memcached client library libmemcached is now on GitHub, for your forking needs.

They're fast as hell too, just like the C-level library is.

And guess what? It doesn't even use ctypes!

pylibmc on GitHub


Introducing iptraq

My server has a way of going down every now and then due to my ISP being crap as hell.

The problem is that my server is at my home in Stockholm, together with the rest of my family. And I'm ~400 km away from Stockholm.

It then becomes a problem if my server changes IP address, like it always has to do when the Internet connection goes down for an extended period of time - I can't find my own darn server.

Coincidentally, I love Google App Engine for small projects, so I decided to jot down an application which tracks the latest "pings" from a machine, and more precisely its IP address.

Thus, I present to you: iptraq.appspot.com!

Being me, it doesn't really have a user interface at all. No really, it doesn't, at all.

You set it up by following this simple list of instructions:

  1. Send an HTTP POST to the root: curl -d '' iptraq.appspot.com
  2. Copy the character blurb after IPMark:
  3. Send an HTTP POST to /<your blurb>/, like: curl -d '' iptraq.appspot.com/agZpcHRyYXFyDgsSBklQTWFyaxi3mQIM/
  4. Send an HTTP GET to the same place to get a list of updates within the last 24 hours. I suggest you add a bookmark for it.

And that's it. All you need is for your server(s) to ping the URL every half hour or so. I do that using cron, like this:

0,30 * * * * /home/toxik/bin/update_iptraq

And the contents of ~/bin/update_iptraq:

#!/bin/bash
exec /usr/bin/curl -s -d '' 'http://iptraq.appspot.com/<my blurb>/' >/dev/null

I don't silence stderr using 2>&1 because I'd really rather want to know when it doesn't work (a well-setup system will mail you whenever cron scripts print anything to stderr.)

I also use the full path to curl because you can't rely on your environment in a cron script -- everything has to be set explicitly. (In theory.)

And that's it, now you too can track the IP address of your machines.

Update: Good news, everyone! iptraq is now on GitHub.


Doing logging wrong: python-markdown

Python Markdown 2.0.1 contains this very interesting snippet of code, observe:

def message(level, text):
    """ A wrapper method for logging debug messages. """
    logger =  logging.getLogger('MARKDOWN')
    if logger.handlers:
        # The logger is configured
        logger.log(level, text)
        if level > WARN:
            sys.exit(0)
    elif level > WARN:
        raise MarkdownException, text
    else:
        warnings.warn(text, MarkdownWarning)

This function is used to implement so-called "logging", and calls to it are spread throughout the distribution's code.

Among other things, the author(s) thought it'd be neat to log each and every text parsed, so if you're debugging - good luck reading any of your logs.

But that's not the real issue here. If you were to be clever and do the following:

import logging

class NullHandler(logging.Handler):
    def emit(self, record): pass

markdown_logger = logging.getLogger("MARKDOWN")
markdown_logger.addHandler(NullHandler())

Then the sys.exit(0) part triggers.

Add a hypothetical situation, your application is a Web application (not an uncommon use for Markdown) and you deploy your code with FastCGI and a WSGI bridge.

When Markdown fails parsing some code or otherwise errors, it'll... Exit the process. Just like that.

Complete and utter disaster. What we're seeing is application code in a library.

How to stop this from happening then? Well, um... Monkey-patch markdown.message is the only real solution to the problem.

The other solution, which at least stops you from being spammed with crap from Markdown, is to do logging.getLogger("MARKDOWN").setLevel(logging.INFO).


Released simples3 0.5

Just released simples3 0.5, which now supports copying files intra-S3 (from and to S3 buckets.)

This also enables you to update the metadata of an object without sending the contents again.

Have fun with it!

simples3 0.5 on PyPI


Updating An Object's Metadata On S3

One complaint I've seen a lot around the internet is that you can't update the metadata of an object on S3.

While this is partly true, there's a way to do it.

What you do is using the copy method, an HTTP PUT with a x-amz-copy-source header, you set the metadata with the x-amz-metadata-directive and copy to the same object!

Using simples3, you can do this with:

bucket.copy(bucket.name + "/obj.txt", "obj.txt", metadata={"new": "metadata"},
            acl="public-read", mimetype="text/plain")

One thing to note here is that S3 doesn't copy anything but the object data! That includes content type, ACL, and previous metadata.

You might like to make an info request first, to get these values so you can merge with new values. But note that it won't be atomic!


Terminal.app and Its Necessary Additions

People who work a lot with Terminal.app in OS X know it has limitations. In Tiger, it was so severely crippled as to be unusable, but in Leopard, you can actually make it useful.

Step one is changing the font. ProFontX is my favorite, because it's compact and readable. (Though I don't use it for my coding.)

Step two is getting nicer Terminal colors. I for one like having brighter colors, partly because my monitor isn't great at contrast with dark colors on black.

To be able to change colors, you need SIMBL and a plugin for SIMBL. SIMBL basically lets you hook arbitrary code into GUI applications on OS X.

See http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal for more information on getting that to work.

Step three is changing what Cmd+[0-9] does. The original behavior never even worked for me, as I'm an avid Spaces user, I'd suspect that borks something up.

What you want is map the keys to switching tab, and this too is doable with a SIMBL plugin.

See http://ciaranwal.sh/2007/12/10/tab-switching-in-terminal for that.

Lastly I also use something called Blurminal, again SMIBl. It blurs the background of the terminal, so you can use translucency without going nuts.

See http://ciaranwal.sh/2007/11/16/blurminal for that...

... Noticed something yet? All of the SIMBL plugins were from one man, Ciarán Walsh. Thanks, dude.

fan kollar du på då va

Internet Explorer reaches new heights of retardedness

Internet Explorer 7 can't set cookies for two-letter domains. No, really! In KB310676, they explain that two-letter domains can't have cookies.

Unless... Unless you set a registry key, aptly called SpecialDomains. It contains a space-separated list of TLDs for which to allow two-letter domain cookies. But wait, there's more: you do it in reverse. Yes, reverse. So for making it work with yo.se, the key should be "es.". Really!

Some people on the Internet have said that Internet Explorer is simply following the URL RFC 2396, which is wrong, because here's what it states:

hostport    = host [ ":" port ]
host        = hostname | IPv4address
hostname    = *( domainlabel "." ) toplabel [ "." ]
domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
toplabel    = alpha | alpha *( alphanum | "-" ) alphanum

In other words, domain label is "either an alphanumeric character, or an alphanumeric character followed by any number of alphanumeric characters or dashes, ended by an alphanumeric character."

In other words, it only requires the hostname to be at least one alphanumeric character, and that it might not begin or end in a dash.

So yeah, kind of sucks to be us. Seriously, I have no idea how to work-around this bug. No idea at all.


RSS 2.0