this is aaronland

The Year That Meat Ate

5 Things I Have Learned About Python for Series 60, 3rd Edition

  1. Ensymble is the best thing ever. Say it with me :
    /usr/local/bin/ensymble.py py2sis \
        --caps="LocalServices+NetworkServices+ReadUserData+WriteUserData+UserEnvironment" \
        --verbose \
        /path/to/your/script.py
    Profit!
  2. The part where you learned to wrap every application in a loop model that created a lock, told the lock to wait, then finally signaled the lock when the Exit button was pushed : Irrelevant. In fact, the only benefit in defining a custom abort method seems to be the ability to wedge your phone in a single click.
  3. If you want to yield, you will need to add the following at the top of your code :
    from __future__ import generators
  4. Likewise, if anything requires the enumerate method you will have to define it yourself :
    def enumerate (list) :
        # list of tuples
        lot = []
        
        for i in list :
            lot.append((len(lot), i))
    
        return lot
  5. I have no idea whether the Series 60 Python byte order is big or not but do not bother asking the sys library because it doesn't know either and in typical Python fashion will blow its brains out if you ask.

I know all of these things because there is still no built-in XML parser.

This morning, over coffee, I decided to see if I could port the many properly abstracted classes in Bob Ippolito's simplejson.py in to one massive ugly file that could be copied and pasted in to a pre-SIS-ified Python script to account for the part where installing custom libraries is so inconvenient as to be impossible.

And I did. At least enough to get it to parse an incoming JSON string :

    import appuifw
    import e32
    import httplib

    c = httplib.HTTPConnection('twitter.com');
    c.request('GET', '/statuses/public_timeline.json')
    r = c.getresponse()

    s = simplejson()
    
    try :
        posts = s.loads(r.read())

        for tw in posts :
            msg = tw['text']
            
            if e32.in_emulator() :
                appuifw.note(unicode(msg), 'note')
            else :
                import audio
                audio.say(msg)
                
            break
        
    except Exception, e :
        appuifw.note(unicode(e), 'error')

This is all still in the alpha alpha disco-ball; no refunds accepted stage and, frankly, I'm hoping that Simon will save me the trouble of having to clean it up and just send a patch.

In the meantime : s60-simplejson.py

The Papernet

Part One

The other day I stuck my nose in to the local travel-book store and asked if they had gotten any of the new city notebooks published by the Moleskin people. Like most people I had seen the initial press release, was curious, and like everyone else couldn't really imagine how they'd pull it off. Travel books, whether they are guides or organizers, seem to suffer the same fate of trendy but bad restaurants : Too much of everything and not enough of anything.

Everybody, especially if you've grown up reading William Gibson novels, dreams of walking around with a cross between a bag of holding and a miniature Cornell box (preferably connected and at the same time hidden from the Network.) What we've gotten so far are mostly inelegant pieces of molded plastic that overheat and don't nicely fit in your pockets and which are fast enough only to drain the battery for whose charger you have the wrong power adapter.

Or coffee-table sized printed books which can only be carried around in a backpack. The backpack is a whole other essay which I will save for another day but the short version is : What the fuck do you have in that backpack and what about life frightens you so much that you think you're actually going to need, let alone use, any of it?

The exception to the rule in all of this being L'Indispensable's Plan de Paris which is about the size of, well, a Moleskin (or vice versa, depending on how you look at these things) and the only sane way to get around the city.

The Moleskin is not a travel guide in any traditional sense. I think that it is supposed to be the sort of artifact that is passed on from traveller to traveller to visitor to traveller and whose value comes from an accumulation of textures : The wear and tear of the pages; the stains on the cover; a record of places and events long since crushed by the present; a sense of privilege and exclusivity.

It's a bit forced and cheesy in the execution, though. There's a section for addresses, complete with dorky graphics, and pages with tabs and stickers with canned headers. Beyond some pretty maps there's nothing really there except the sense that you're being sold an idea of how you'd like to experience and share a place more in the telling than in the reality.

Had there been a San Francisco edition, I probably would have bought one just to carry it around and see whether I used it. Maps and blank pages and the sex appeal of a hard-bound notebook may be all anyone wants these days.

Part Two

Not having built anything with it yet, I have no real opinion about Ruby on Rails. My only concern is that I don't trust frameworks and the fervour with which people sell Rails has always suffered from Man With a Hammer -itis syndrome. But a lot of people's whose opinion I respect like it so I make a point of badgering them about it.

Finally, one of them said to me : It is a really great tool to quickly build a website for you and your 5, 000 closest friends. On the face of it, that may seem like a pejorative but I don't think it is at all. In fact, I think it's fantastic and, whether it works or not, is probably why companies like Apple have started bundling it in with their own products. If you've ever done any contracting work at all, you will know that no one uses so-called out of the box solutions out of the box.

Every single one of them is a series of ugly patches shoe-horned to the original solution with duct tape. If something like Rails can give a small office, or a school, or an NGO the ability to make a computer do something useful for them, from the ground up, quickly and cheaply and on their own terms then I am all for it. Save Plone for the Enterprise.

I mention all of this because, a few months later I was washing the dishes and thinking about a good bottle of wine I'd had wondering whether I would forget its name in five minutes or five hours.

This is a website for friends and family to keep notes on wines they've enjoyed.

It was created because the otherwise excellent website Cork'd does not have the necessary glue to do the kinds of searching I want or to write handy computer programs to talk to their database from my cell phone.

I wrote that about a week later.

Unlike the Cork'd people, I did not use Rails although I considered it. I thought : This would be a good exercise to learn Rails. Then I thought : I do not need any more half-finished learning curves in my life. I just want a place where I can quickly jot down wines that I like and get at them from my cell phone.

Jeffrey Zeldman summed it up well :

10 Things I Learned at Mobile 2.0
       1. Mobile 2.0 = The Web.
       2. The mobile web browser is the next killer app.
Plus eight more things! 

Part Three

I still do not like wikis.

I have learned, however, that I dislike them less than fucking around defining database schemas and object models. There is more than a little untruthiness in that last statement given the amount of work I ended up having to do make the following useful :

{{wine|Pavi|Dolcetto|2004|red}}
{{grapes|Dolcetto}}
{{region|USA|California|Napa Valley}}
= Recommendations =
{{recommendation|Aaron|again}}

By useful, I mean four things :

  1. The syntax is only sightly more complicated than any other wiki syntax.
  2. It renders nicely as a formatted web page.
  3. There is no prohibition on writing free-form text and it too is formatted.
  4. It allows me to do fancy searching : Wines from the California region that have a recommendation of again. On my phone :

By really useful, I mean two things :

  1. The syntax is easy to parse in insert your favourite programming language here. (It is not easy enough to infer meaning using your computer's Do What I Mean engine but, uh, well...so what?)
  2. It is easy to clone.

Shortly after the wine site went up, a friend asked if I could create a similar site for restaurants. The argument being : I don't want to share all my favourite restaurants with Yelp. So I did :

{{restaurant|Joe Beef|French}}
{{tags|french|meat}}
{{address|2491|Notre Dame|Montreal|Quebec|Canda}}
{{crossstreets|Atwater}}
{{neighbourhoods|St. Henri|Little Burgundy}}
{{phone|514-935-6504}}
{{details|alcohol=yes|creditcards=yes|wheelchairaccess=yes|vegetarianfriendly=no}}
{{reviews|http://www.montreald.com/restos/joebeef.html}}
= Recommendations =
{{recommendation|Aaron|againagain}}

Having still yet to build anything in Rails I have no idea whether I spent more or less time fucking around first with Mediawiki templates and secondly patching the Semantic Mediawiki extensions to do queries on multiple properties. I have already written about this stuff at length so there's nothing much new to report except to say that I will submit patches and publish my own templates sometime soon.

I still have no ready solution for recipes. If restaurants are more complicated to define and, by extension, mark up than wines recipes are an order of magnitude more complicated than the two combined.

I gave up last week, created another wiki-based site and imported about two and half years worth of recipes as the plain vanilla text that they are. The only way I have to find things is to do brute-force text searching and the idea (the hope) is to use the collection as a sort of scratchbox and gradually start marking stuff up over time.

I will probably regret this decision (translation : it will never happen) but at a minimum it satisfies the goal of having recipes in more than one place at once, namely the Internets.

None of these websites are public. One of the nice things about using a wiki is that you don't have to deal with setting up user account tables, and all that. The flip-side is wiki-spam and my super-sophisticated approach to handling that is to not make things public. If you want to play, send me an email.

Part Four

When we went to Paris, last spring, we house sat for a friend of a friend in the 12th. We sent an email to the woman whose apartment we were watching asking if she would share any of her favourite places in the city. She quickly replied sending a 32-page Word document organized by neighbourhood. It was awesome. We were obviously not the first people she had done this for and you could almost read her entire history with the city in the pages. Sound familiar?

Our stay in Paris would have been immeasurably more complicated without three things : Our friend's list of places to eat, a simplied map of the city's metro system with the neighbourhoods overlayed and the aforementioned Plan de Paris.

Days would typically start with a trip to a bakery or a pastry shop and the assumption that we'd be unlikely to stray further than a neighbourhood or two in any direction. So we'd figure out which metro stop we'd start from, work out the neighbourhoods nearby and then pull out those pages from the J.'s opus, scribble some notes and fold them in to the Plan.

I used to be a bag person but somewhere along the way I adopted the principle that if I couldn't fit it in a pocket, its usefulness would always fight an uphill battle against the annoyingness of having to lug it around.

By the end of the trip I was full of ideas for community driven websites where you could build and print your day's (or your week's) journey and fold it all in to a handy little booklet that would fit in your back pocket. Like most of these things, it quickly got crushed by too many ambitions and too many moving parts. And then there's the folding thing which is compounded by lack of consumer grade printers to print on anything but letter-sized paper.

Maybe a piece of paper folded in four is good enough for most people but I've always been fond of index cards and am lazy enough that I don't like having to do any more than quickly glance at something I've made notes on. Maybe that's just because I am sensitive to being marked as a tourist from a hundred yards away. I am okay admitting as much because, let's face it, being marked as a tourist a hundred yards away really sucks.

At least in Europe, you can do worse than wearing proper shoes and not having a backpack with you everywhere you go.

Part Five

Have you ever had to generate a PDF file using a programming language?

It's a horrible experience. Working with PostScript is enough to make you want to die and writing XSL-FO is a close second. There are lots of wrapper libraries that try to hold your hand but none (most?) of them ever provide that one utility method that most people really care about : Please, do not make me keep track of carriage returns and page breaks. Dealing with that crap is like crossing the abyss of print and typographical minutiae that make PostScript seem like a poetry reading.

I said most, right? There is at least one called FPDF that is written in pure PHP and defines my new favourite function ever : MultiCell :

This method allows printing text with line breaks. They can be automatic (as soon as the text reaches the right border of the cell) or explicit (via the \n character). As many cells as necessary are output, one below the other.

Like every other PDF library, FPDF will also draw lines. Which is interesting because if you fold a piece of letter-sized paper in three along its height, each section is about the size of an index card or a Moleskin page. If you fold it again once width-wise you basically have an index card. Or an accordion of three index cards with some space left over for notes.

Something like this :


                        # Simple - aaPDF subclasses FPDF and takes care
                        # of drawing lines and ensuring that no text is
                        # placed on the folds

                        $title = "Hello World";
                        $body = "This page left intentionally blank";

                        $aa = new aaPDF(array($title => $body));
                        $aa->draw();

                        # Not simple - tablePDF subclasses aaPDF 
                        # and redefines the 'render' method to
                        # generate formatted text from $tbl

                        $page = 'Joe Beef';

                        $mw = new mwExport('example.com');
                        list($title, $body, $url) = $mw->export($page);

                        $tbl = new table($url, $body);

                        $pdf = new tablePDF(array($tbl));
                        $pdf->draw();
                    

That's about as complicated a document as I've created so far, between the map which is pulled in on the fly and the QR codes (one points to the wiki page used to generate the document; the other contains a vCard of the restaurant's address and website) but the principle is the same whether it's a recipe, a bottle of wine or a restaurant : A letter-sized page folded three times with a chunk of text that may or may not be formatted.

Print a bunch of them out and you have a book that you can stick in your bag on the way out the door. (If you're wondering about multi-page documents, the short answer is : I'm not dealing with that problem just yet.)

The plan is to release the code (and examples) for aaPDF.php but it needs a few more days of testing and little things like documentation.

Part Six

Information wants to be used not managed.

I have near continuous access to the Internets these days and I get to play with most of the cool mobile nerd toys. I even have a Moleskin, not that I ever use it for anything except tearing out pages and scribbling notes and maps for other people.

I want to use the Internets for the things they are good at — like distribution and searchification — but I am not ready to give up something I can hold in my hands. I am not ready to have all my actions dictated by the physical contraints of a device that is little more than over-priced landfill outside of a limited set of conditions.

It's true that paper is no match for, say, molasses or fire but then neither are computers.

Paper, on the other hand, can suffer water and power failures; can be folded and sat on; can be thrown; can be copied by humans and machines alike; is about eight million times less irritating at the dinner table.

The really great thing about digital publishing tools and mobile devices connected to the Internets is that we have almost reached to the point where we can toggle seamlessly (hahahaha....sorry) between physical and digital artifacts without needing to say really assinine things like : Paper is dead.

We can use the computers to generate paper things to use and hold in the comfort of our own privacy and to share with friends and barcodes (or something similar — the first one of you to say RFID gets a punch in the head) to link them back to a larger community.

Granted, it's all still a bit rough around the edges.

I'm guessing we are only a couple years away from people being able to print custom, limited edition (like editions of one) books of all and any flavour at a price where they won't just be lifestyle porn. I bet the Moleskin people will be there or if they're not they should probably start thinking about it. I hope Derek is there.

Until then, I will stick to pieces of 8.5 x 11 folded and kept in a small metal box.

Small pieces of paper, loosely joined.