Archive for the ‘Python’ Category

Cherokee 0.7.0 “Land Shark” released!

A couple of months after the previous Cherokee stable release, and once a lot of work and testing has been done, here it is: Ladies and gentlemen, Cherokee 0.7.0 is out!. You could take a look at the official announcement, but what you should really do is try it out. Seriously. Every single one of us is working hard on the project -make that extra-extra-hard working in Alvaro‘s case-, and the results are clearly visible.

Cherokee Webserver

We have a lot of fresh ideas, and as always feedback and feature requests are more than welcome at the mailing list. The Summer is almost here, and this one will prove to be extremely productive. Just trust me for now. It will ;-)

Here is the download link.

Read the rest of this entry »

Wiilson: Wii-Skybot extreme (Skybot + Wii + PWM)

A couple of days ago I mentioned this in the post about extending libStargate for a class assignment we had. The team was formed by Miguel, Gonzalo and myself, and we received a pretty good grade, by the way. I wanted to write again after having some patches sent to the main author of libStargate by the end of this week, but it turns out I won’t be able to properly test them until after that. Since a lot of friends have been having problems with their own projects, ours is going to be temporarily cannibalized until their time is up. Wish them luck! ;)

Anyway, I’ll post again once  I have the things properly tested and I’ve spoken to the people of IEArobotics. For now, here is the link to download Wiilson if you want to try it out.

As mentioned earlier, it is just a PWM Wiimote implementation to control a Skybot. The Wiimote is interfaced thanks to the excellent pywii library, Orienting the Wiimote makes the bot move and it goes faster or slower depending on the inclination of the controller. Changing from mode ‘A’ to ‘B’ (or ’1′ to ’2′) overrides this behavior and controls the bot with the direction keys of the Wiimote, being able to alter speeds with the ‘Plus’ and ‘Minus’ buttons. It’s not pretty, but it is a quick hack and works fine. If you want something better you’ll have to wait for the release of pybot, a Python module to control (extended) libStargate managed robots with PWM support. The only class present right now is to control the Skybot as it is out of the box, so PWM support is software based -you’d have to rewire it if you wanted a hardware version of this, much better but totally out of the scope-.

Coming up soon, at least as soon as our bot gets de-cannibalized if that is even a word!

By the way… I think I’m getting to love this stuff. I’ll have to buy a Skypic or Arduino for myself. You can’t ever play around enough with these things. And to think it was always there and I never knew!

Read the rest of this entry »

Skybot, take two: extending libStargate

In a previous post I mentioned that we would be playing around with a bot project to interface our Skypic board and the Wiimote as an assignment in class.

Hacking these things has been fairly easy thanks to some pretty handy pieces of software we stumbled upon at IeaRobotics and a bit of Python magic. The tools of the trade were Pydownloader to program the Skypic, libStargate to interface the PC and the bot, and finally Pywii, a wonderful Wiimote library.

We ended up implementing a new server for the Skypic that should enable a smooth control of the acceleration applied to the Skybot in response to the Wiimote’s movements. To handle it we had to extend libStargate. Our job wasn’t particularly hard to do, but up until now you only had the chance of applying an all-or-nothing type of movement. Now the acceleration is proportional to the pitch and roll values of the controller. Since the controlling code is in the PIC instead of the computer, the effect is really smooth.

The bot has dual power. 6V for the Skypic and 9V for the servos. If only we had used 12V for these the effect would be nicer yet, but overall its fine.

I’ll clean the code a bit before submitting the patches to the project’s author, and I hope to have it ready and submitted this week along with a new wrapper class around libStargate to control specifically the SkyBots with PWM capabilities. It is called pySkybot, by the way.

Read the rest of this entry »

Cherokee 0.6.1 “Easter” released!

Precisely one week after releasing the long awaited 0.6 version of this web server, Cherokee 0.6.1 has been released minutes ago. As I’ve said once and again, the project has been gaining momentum and here you have the download link to prove it.

Cherokee Webserver

It is mostly a maintenance release since most of the development efforts are being put towards the future release of version 0.7 with a lot of goodies. I’ll be writing about that when the times comes. For now the list of changes in 0.6.1 includes support for “Personal Web” -a missing feature in this release that was requested for the administrative interface-, a fix for a bug introduced in handler dirlist right before the previous release, and some other minor bugs in documentation, compilation and cherokee-admin.

As before, you’ll have more information at Alvaro’s site and the official Cherokee Project’s website. We’ll be waiting for your input. Happy hacking!

Read the rest of this entry »

Cherokee 0.6.0 is out

As I anticipated some weeks ago, Cherokee 0.6.0 has finally been released. It was a couple of days ago but it caught me away and with no Internet access until now.

Anyway, the trunk was branched on March 6th and after some exhaustive testing and a little polishing here and there … here it is!!!

Cherokee

You should take a look at Alvaro’s site and at the official Cherokee Project’s website. Suffice it to say a lot of work has been put into the new release, and the effort has been well invested. Work will resume shortly to improve an already impressive web server, and as advancements are made towards 0.7 a lot of new features will be added. A fast look at the TODO file will give you an idea of what is yet to come: a bunch of new handlers and modules (WSGI, AJPv13, WebDAV, mod_evasive, upload progress module), generic caching, new header entry, AIO based fdpoll, memcached support, chunked encoding, Dtrace hooks, better language support…

As I said previously, stay tuned. You’ll be able to expect a lot from this project in the near future. That is a given ;)

UPDATE: I forgot to mention the most important thing. Here is the original announcement of the release at the official mailing list.

Read the rest of this entry »

Python Challenge level 23: “what is this module?”

As I understand it, this was the former last level of the game. Level 23. In time 10 more levels were added.

Hint 1: it can’t find it. this is an undocumented module.
Hint 2: va gur snpr bs jung?

One needs Python to solve this one. No other language will do. There’s no real need to use Python, but you doo need it.
After having spent some time in the forums for hints for some of the previous level, one gets to see that ‘encrypting’ things with ROT13 is a tradition over there. And the second hint is ROT13 for ‘in the face of what?’

I didn’t think about it at first, but the author said there that the solution was to take the hints literally. The answer to the riddle can be found in “Gur Mra bs Clguba, ol Gvz Crgref”. It looks like a Czech proverb, but it isn’t. At least that I konw of. After poking into every module, the only undocoumented module -as in ‘no a single comment in it’, not even oneliners!- is the answer to our prayers. It can be found a lot faster by just grepping for ‘the face of’:

taher@borg:/usr/lib/python2.5$ grep -i "va gur snpr bs" *
this.py:Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.

Heh! ‘this module is undocumented’. Nice one. Try importing module ‘this’ in your Python interpreter. It’s amusing. The famous “proverb” is attributed to Tim Peters, who went by the name of UncleTimmy in the forums.

You’ll find the key to the next level either in the previous link or in the allready mentioned this.py.
Next is Level 24.

There’s something left in this level:

TODO: do you owe someone an apology? now it is a good time to tell him that you are sorry. Please show good manners although it has nothing to do with this level.

The only one ever insulted would have been Leopold, and since he doesn’t like cookies one would figure the second best thing is to simply drop him a line. If you apologize and he’s in good mood, you’ll get a response like this one:

From: Leopold Mozart <leopold.moz@pythonchall… >
Subject: Re: sorry
Never mind that.

Have you found my broken zip?
md5: bbb8b499a0eef99b52c7f13f4e78c24b

Can you believe what one mistake can lead to?

I guess it’ll be useful in the future. This was one easy and really nice level. If it’s the first time you hear of The Zen of Python, you should take a look. You’ll like it!

Read the rest of this entry »

Python Challenge level 22: “emulate”

Level 22 got me stuck for a while.

Hint 1: or maybe white.gif would be more bright
Hint 2: image of a joystick

I didn’t know what to do with this one untill I notices it was a GIF89, which reminded me of animated GIFs. After opening it with Gimp I saw that it had 133 frames. Now I had something. It turns out one of the pixels is slightly lighter in each frame in one of several locations. Only 9 of them, actually. Just as the number of possible positions for a joystick. The code bellow is anything but pretty. Beware!

Fact 1: We’re looking for color 8, as shown below. This can be found using im.getcolors() in every frame

#!/usr/bin/env python
import Image,ImageDraw
def get_vectors():
    # Return a list of movement vectors extracted from wiggling pixels
    im = Image.open("white.gif")
    vectors=[]
    try:
        while True:
            pix=list(im.getdata()).index(8)
            y,x=divmod(pix,200)
            v=(x-100,y-100)
            vectors.append(v)
            im.seek(im.tell()+1)
    except EOFError:
        pass # end of sequence
    return vectors

max_x, h, w = 0, 50, 250
im = Image.new('RGB', (w,h))
draw = ImageDraw.Draw(im)
src = (max_x,h//2) # (x,y)
for v in get_vectors():
    if v==(0,0):
        max_x+=30
        src = (max_x,h//2)
        continue
    dst=(src[0]+v[0],src[1]+v[1])
    max_x=max(max_x,dst[0])
    draw.line([src, dst], fill='white')
    src=dst
im.save('22.jpg')

This renders the following image:

bonus

Thats our link for next level: Level 23.

Read the rest of this entry »

Python Challenge level 21: “hidden pack”

There’s no page for this challenge. From the previous level we get a hidden file that was “hiding at 1152983631″. It’s a zipfile with a password. Luckily back in level 20 we also got a tip “esrever ni emankcin wen ruoy si drowssap eht”, and a nickname: invader.

After extracting the archive, we get a text file with the hints, and a file named package.pack

Hint 1: We used to play this game when we were kids.
Hint 2: When I had no idea what to do, I looked backwards.
Hint 3: package.pack

The .pack extension suggested something, so after trying several compression modules the winner is zlib . Once extracted the file’s size is more or less the same. Suspicious. Still unreadable. The second hint comes in handy, and it looks like the tail of the file is a reversed bzip2 header. We already have experience with that thanks to previous levels, isn’t it? Again unreadable. Again reversible. Again compressed. And the show goes on. We’ll have to go back and forth several times to extract the content.

import zlib,bz2
st=open('21_package.pack').read()
log=''
log_len=len(log)
while True:
    try: #zlib
        st=zlib.decompress(st)
        log+=' '
    except:
        try: #bzip2
            st=bz2.decompress(st)
            log+='#'
        except: #reverse
            if log_len==len(log): break
            st=st[::-1]
            print log[log_len:]
            log_len=len(log)
open('21_package.unpack','wb').write(st)

After the whole run we get to read what’s in package.pack:

look at your logs

Originaly I kept a list with the number of zlib and bzip2 cycles en each run, expecting a banner(ish) run length encoding. I noticed that the sum of cycles needed to complete each direction was allways roughly the same. That is, before I had to reverse the string to start over, the sum of bzip+zip+bzip+… was more or less 73. And that meant that the output was meant to be directly graphical, so I sticked with a simpler log version that simplifies the code in turn.

The logs in question look like:

      ###          ###      ########    ########    ##########  ########
    #######      #######    #########   #########   #########   #########
   ##     ##    ##     ##   ##      ##  ##      ##  ##          ##      ##
  ##           ##       ##  ##      ##  ##      ##  ##          ##      ##
  ##           ##       ##  #########   #########   ########    #########
  ##           ##       ##  ########    ########    ########    ########
  ##           ##       ##  ##          ##          ##          ##   ##
   ##     ##    ##     ##   ##          ##          ##          ##    ##
    #######      #######    ##          ##          #########   ##     ##
      ###          ###      ##          ##          ##########  ##      ##

Will wonders never cease? Very nice level. It took me a while to figure out the representation for the logs and I never made sense of the first hint -something cultural I suppose-, but an excellent level nevertheless.

Copper is the next level. Level 22.

Read the rest of this entry »

Python Challenge level 20: “go away!”

Level 20 meant Chaos.

Hint 1: ‘unreal.jpg’, an image of a fence with the message “private property beyond this fence”
Hint 2: but inspecting it carefully is allowed.

As I said, this riddle was chaotic. Completely. Very interesting indeed, but it took some serious trial and error. From deeper inspection of the headers I got the following facts:

Fact 1: One of the headers is ‘Content-Range: bytes 0-30202/2123456789‘. I had to look for some info on this subject because I wasn’t familiar with it. Found some enlightenment in the appropriate RFC2616.

Fact 2: beyond the fence would be in the range 30203 – 2123456789. Such huge size is suspicous, so after trying a retrieval of the whole range at once, and after not getting any meanigful results, I stuck to getting some chunks along the stream. Some at the beginning of the fence boundary, some at the end of the range. There could be more interesting places between the values mentioned, by I do believe the most significant ones are retrieved in the following script.

Obviously I didn’t start with these values. I merely requested fragments from the beginning and the end of the stream, and selected the ones interesting for your convinience. I know, I know! I’m a nice guy, don’t mention it :-D

import urllib
url = 'http://butter:fly@www.pythonchallenge.com/pc/hex/unreal.jpg'

##Private info found
for i in [(30237,30337), (30284,30384), (30295,30395), (30313,30413),
            (2123456744,2123456788), (2123456712,2123456743)]:
    opener = urllib.FancyURLopener({})
    opener.addheader("range", "bytes=%d-%d" % i)
    f = opener.open(url)
    print f.read()

##Something hidden in this particular range.
opener = urllib.FancyURLopener({})
opener.addheader("range", "bytes=%d-%d" % (1152983631,1152983671))
f = opener.open(url)
print f.info()
open("20.zip", "w").write(f.read())

The relevant pieces of information I could come up with were:

Content-Range: bytes 30237-30283/2123456789
we can go on in this way for really long time.
Content-Range: bytes 30284-30294/2123456789
stop this!
Content-Range: bytes 30295-30312/2123456789
invader! invader!
Content-Range: bytes 30313-30346/2123456789
ok, invader. you are inside now.
Content-Range: bytes 2123456712-2123456743/2123456789
and it is hiding at 1152983631
Content-Range: bytes 2123456744-2123456788/2123456789
esrever ni emankcin wen ruoy si drowssap eht

To ‘be in’ must mean that this level has been solved. The catch is we don’t have an URL to refer to for level 21. Fortunately we do have a ZIP file. Discovering it’s misteries will be the next riddle, Level 21.

Read the rest of this entry »

Python Challenge level 19: “please!”

For level 19 I used two scripts.

Hint 1: there is an email in the source with an attached file

#!/usr/bin/env python
import email
mail=email.message_from_file(open('19.txt'))
for part in mail.walk():
    if part.get_content_maintype()=='audio':
        audio=part.get_payload(decode=1)
        open('19_indian.wav', 'wb').write(audio)

The only understandable thing in the file was the word “sorry”, and that page is not really useful. Theres more to the riddle than meets the ear.

Hint 2: the colors of the map seem to be inverted.

After trying reversing the info (utter jibberish), the hint is to be reinterpreted as “inverted India”, which I take as “inverted endian”. Nice longshot. And correct, for what it’s worth.

#!/usr/bin/env python
import array,wave
wi = wave.open('19_indian.wav','rb')
wo = wave.open('19_indian_inv.wav', 'wb')
wo.setparams(wi.getparams())
a = array.array('i')
a.fromstring(wi.readframes(wi.getnframes()))
a.byteswap()
wo.writeframes(a.tostring())
wi.close(),wo.close()

This part of the challenge was completely unexpected. I hadn’t even used the wave module untill today! And we get a nice file with these lyrics:

you are an idiot

And with a message from Leopold, we go to Level 20.

Read the rest of this entry »