27
Oct
09

Webkit feature test

The last few days I’ve been writing a 3D game.

  • Not just a game, an online multiplayer game.
  • Not just a 3D game, but one run in my browser.
  • Not just in my browser, but only with CSS and HTML(and some JS and server side stuff of course).
  • Not just AJAX, but Comet.
  • Not just PHP+MySQL, but only ±30 lines of Bash.

Don’t believe me? Watch this:

It started out a few days back when I read about Comet. I found out about the new EventSource support in Webkit, but I was in doubt how to implement this on the server. My first thought was throwing some PHP+MySQL at it, but I decided otherwise.

Normal Ajax is pull data transfer. You push data to the server, but every time you need data you request it and PHP in turn requests it with the database.

Doing Comet with PHP+MySQL would make the server push data to the client, but the server still does pull transfer with the database.

Then I came up with named pipes, and because named pipes are the easiest in Bash I used that. Now every listening transfer creates a FIFO and all new data is just written to them. This system creates on big U-turn where everything submitted is instantly sent back to all the clients.

This is all the bash code I’m using:

submit.sh:

#!/bin/bash

echo "Content-type: text/plain"
echo ""

cd data
echo -e "event:message\ndata:$QUERY_STRING\n" | tee -a $(ls -1)

data.sh:

#!/bin/bash
cd data

if [ $(ls -1 | wc -l) -lt 5 ]
then
    echo "Content-type: text/event-stream"
    echo ""

    mkfifo data$$
    trap rm\ data$$ SIGTERM SIGKILL EXIT

    while [ -p data$$ ]
    do
        cat data$$
    done
else
    echo "Content-type: text/plain"
    echo "Status: 503"
    echo ""
    echo "Sorry, server to busy!"
fi

For the client side all I had to do is set up an AJAX form submitting player information and move players when an event occurred. The 3D part is done entirely with Webkit 3D transforms. The only downside about using EventSource and -webkit-transform is that you can only play my game with a nightly of Webkit(if you’re unsure if you have one you don’t).

I would love to share my game, but my host refuses to run it. It’s using gzip compression so all events are queued up until the request times out. You can however throw comet.zip from the box.net widget in your cgi-bin and try it yourself.

15
Oct
09

“Hacking your own Twitter widget” for beginners

In the last few days I received 2 questions about how to get a Twitter widget on your site to display some data other than a user timeline. Since I love writing stuff I know that people like instead of what I think they will like, I’m going to write a short howto on getting your custom widget.

Getting your user timeline in a widget is easy; Go to Twitter and grab the code from this page: http://twitter.com/widgets/html_widget

If you look at the code you’ll see a link like this http://twitter.com/statuses/user_timeline/pepijndevos.json?callback=twitterCallback2&count=5 Go ahead and click it! It’s a JSON file with my latest tweets.

The cool part is that Twitter has a whole API of urls you can use to get your data. The default widget is using statuses/user_timeline. Note the XML structure at the bottom. We can replace this url with any public url that returns the same structure, that means statuses containing a user, not users containing a status.

Here is a list of a few API calls you could use:

  • http://twitter.com/statuses/public_timeline.json?callback=twitterCallback2&count=5 — Show the public timeline.
  • http://twitter.com/favorites/pepijndevos.json?callback=twitterCallback2&count=5 — Get a users favorites.
  • http://search.twitter.com/search.json?tag=jython&from=pepijndevos&rpp=5&callback=twitterCallback2 — Search will only work after the next version of the API, where it will return the same result as the rest.

An example using my favorites would look like:

<div id="twitter_div">
<h2>Twitter Updates</h2>
<ul id="twitter_update_list">
</ul>
<a href="http://twitter.com/pepijndevos" id="twitter-link" style="display:block;text-align:right;">follow me on Twitter</a>
</div>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/favorites/pepijndevos.json?callback=twitterCallback2&count=5"></script>

You can now paste this html code anywhere you want it to appear!

11
Oct
09

[updated] Mobile Safari better then Safari 4?

[update]: The latest Webkit does support 3D transitions! Examle

Screen shot 2009-10-11 at 3.20.07 PM

Today I was reading about developing web apps for my iPod touch. While reading this article about CSS animations I downloaded the example. To my surprise the example said it required iPhone simulator to run. Stubborn as I am I tried to open it with Safari 4… This gave the following result(try for yourself!):

Picture 11

Surprised as I was I opened it with the iPhone simulator, which yields this result:

Picture 13

It seems that the iPhone supports 3D and perspective css statements that Safari 4 does not support. Isn’t it strange that a mobile device can do things a full sized computer can’t(except for trowing with it while holding a drink in your other hand)? My first thought was that the Mobile Safari was released after Safari 4, so it might have a newer version of Webkit(that’s what powers Safari and Chrome). But the oposite is true, Safari 4 runs Webkit 530.18 and my iPod Touch runs  528.18. I’m to lazy to compile a nightly build of Webkit to see if it works, but until then I got no clue why Safari 4 can’t do this CSS magic.

Here are 2 screenshots of the browser string of both:

Picture 12IMG_0007

08
Oct
09

PyMouse 0.3

Hey there!

Some great stuff has happened to PyMouse since 0.2

  • It has been listed on Softpedia.
  • Mac Snow Leopard should be working.
  • Linux now works via xlib instead of the non-default xtest extension, which I admit was a burden.
  • Support for separate click and release, screen size and mouse position.
  • PyMouse is no longer an one-man-project, wido.gg has made xlib possible and is now an official commiter :D

So that means you should download the latest version and I should notify Softpedia that they’re lagging behind.

04
Oct
09

PyML(Python Markup Language) template engine

I know it’s been a while since my last post. I’ve been busy with setting up and pulling down pepijndevos.nl(after I decided to go for another blog system), I’ve spend a good deal of time working on PyMouse and worked on some projects for myself and for clients.

I want to share one of those projects with you. I decided to make a CMS like Jekyll and Hyde(not the book!), since I liked neither of the previous systems. So like a lot of people who like reinventing wheels I started to look for a nice markup language for the user and a nice template language for the designer.

I choose for Markdown right away, end of story here…

Because of the little experience I have with Pylons I looked ad Genshi and Mako initially(can’t help the Chinese feeling these names give me). Personally the ugly tags in most template languages make me run away, so I threw Make out of the window, together with all the other ugly-tag-based languages.

I like the idea of working with valid XML attributes for templating, so I started of with Genshi initially, especially since speed isn’t a major point for a static blog!

Days later I came across this wiki page on the Python website: http://wiki.python.org/moin/Templating

Looking at Dirty I remembered my own attempts to write a template language implemented as Python objects(extending dict, for free functionality).

The problem with writing such a thing is described in the code below, I mailed the developer of Dirty about how he solved the problem — he didn’t.

>>> def div(*content, **attributes):
...     pass
...
>>> div("hello world!", id="test") # Doesn't html have the attributes first!? Ugly!
>>> def div(**attributes, *content): # Not allowed!
  File "", line 1
    def div(**attributes, *content):
                        ^
SyntaxError: invalid syntax
>>> def div(atributes, *content):
...     pass
...
>>> div({'id':'test'}, "hello world!") # Even uglier!

But then I came up with this slightly brilliant solution:

When you define __call__ on a class it allows you to call the class, no big deal, eh? Wrong! It allows you to write this:

html(xmlns="http://www.w3.org/1999/xhtml")(
    head( # No atributes
        title("Hello world")
    ),
    body(
        p(id="test")(
            "Hi", br(),
            "How are you?"
        ),
        img(src="test.img", alt="just a test") # No content
        ul(
            *[li(c) for c in xrange(10)] # Now that is cool!
        )
    )
)

In short PyML is a pure Python combination of a string and a dict looking like html when written and printed!

You can do all sorts of things with this that you normally do with dictionaries, strings and lists, like sorting and filtering them, change a p into a div or getting/setting attributes later with square brackets. You could define functions to return a snippet or you could include templates into others. If you’re finished with them, just print the object!

Oh, about the speed? Quite good for my hobby project! (Unreliable micro benchmark ahead!)

Render time Engine
0.03160 PyML
0.50618 Genshi
0.01813 Mako

You can get it here if you want! Or wait for my complete CMS of course…

09
Sep
09

[update] PyMouse

Today I spend my day trying to improve PyMouse.

  • I added some suggested changes to the Windows part, please test them.
  • I modified the Mac part according to a comment on this blog. [Currently broken under Snow Leopard!]
  • Unix part unchanged…

Please let me know if and how it works. Especially if you know something about PyObjc…

05
Sep
09

[Update] PyMouse

Remember the post a few weeks ago about my Python mouse control library? If not, this is the link: http://metapep.wordpress.com/2009/07/10/control-the-mouse-on-mac-with-python/ and this the Google project: http://code.google.com/p/pymouse/

It has been added to Softpedia! I just received a mail about it. It’s listed under Mac products, but it’s cool anyway and it encourages me to continue to work on it.(just as much as it encourages me to see reactions and patches from people!)

http://mac.softpedia.com/get/Developer-Tools/pymouse.shtml

03
Sep
09

pepijndevos.nl

This is just a short notice that I’ve started up another blog about WordPress and PHP in Dutch. I’ll continue to post my Python stuff in English here. so that means:

  • My English Python stuff: right here
  • My Dutch WordPress stuff: pepijndevos.nl
  • English WordPress stuff: there’s enough on the internet about that, right?
23
Aug
09

About __main__

I think most Python programmers have written it a thousand times:

if __name__ == '__main__':
    #some code

I also assume you know what the result is of the following code:

class test(object):
    pass

print test.__name__
#test

So lets assume the __name__ variable contains the current class name, what would the __main__ class be? It’s the invisible main class of course! But there’s something strange going on:

print test
#<class '__main__.test'>

print __main__
#NameError: name '__main__' is not defined

So… the test function is a member of __main__, but main itself does not exist? Strange… When I was frustrated by this I experimented some, lets check the following piece of code:

import __main__

print __main__
#<module '__main__' (built-in)> 

print dir(__main__)
#['__builtins__', '__doc__', '__main__', '__name__', 'test']

__main__.test2 = 'Hello world!!!'
print test2
#Hello world!!!

Isn’t that amazing? We imported __main__, saw it had the test class assigned to it, we assigned a new variable and saw the module scope updated!

This might sound quite pointless, but you can do a lot of dirty tricks with it, for example assign variables by strings:

name = raw_input('Enter a variable name: ')
setattr(__main__, name, 'Dirty trick')
print dir(__main__)
#['__builtins__', '__doc__', '__main__', '__name__', 'test', 'test2', '<your input here>']

This method is used in my xhtml generator to assign partitial functions for xhtml tags to the module scope(to have a(href=”test”) instead of SomeClass.a(href=”test”) or even SomeClass.html(‘a’, href=”test”).

01
Aug
09

Kill those spam followers! – BETA

It happens to everyone on Twitter: spam/fake followers. Do you want to get rid of them?

Inspired on this post I started working on a anti-spam app to block these spammers. My app checks your followers list on the 3 points explained in that post, being:

  1. Names with a number
  2. A 10/1 ratio of friends/followers
  3. Posts via the API

The app is currently in the testing phase, and I need your help! I tested it on my own little followers list, but who knows what happens when you try it on your followers!

Currently the app only checks your followers and gives some output. I need you to run the app and report false positives/negatives. I’ll explain you how you can try this in a moment. The output looks like this:

Username (-- SPAM) <-- name and if it's spam or not
63 <-- percentage of spaminess
{'individual': 23, 'test: 0, 'results': 40} <-- results per test

Instructions for testing my anti-spam app:

  1. If you don’t have a Python environment set up, roughly follow this howto and another one. (and google for PYTHONPATH afterwards)
  2. Open a terminal and type: easy_install simplesjon
  3. Download antispam.py from the box.net widget
  4. Get back to your terminal and type: cd /the/dir/where/my/app/is
  5. Open antispam.py in a text editor and replace USERNAME and PASSWORD at the bottom with your Twitter username and password
  6. Get back to your terminal and type: python antispam.py
  7. Watch the output roll over your screen…

If you get stuck somewhere, just leave a comment. If you found a false positive/negative, also leave a comment including a part of the output.

If you’re realy confident of the workings of the app you can remove the # sign before user.tag_as_spam and user.block_user at the bottom of the file, now my app is realy going to block and report people!

If enough people tested this version I’ll make an easy to use exe with a graphical user interface(which would eliminate the four toughest steps). The Python version will still be available for Mac and Linux users.




Me

This is me

Blog Stats

  • 3,342 hits

@PepijnDeVos

  • 5 minuten Twitter stilte voor het sterven van mij trouwe thee beker :( 22 hours ago
  • Alternating between Mac and Ubuntu to get grub-efi working while falling asleep while waiting for people on #grub to answer my questions. 1 day ago
  • @karoen Sneller dan ons internet, maar langzamer dan een normale netwerk kabel. 1 day ago