Showing posts with label Nevow. Show all posts
Showing posts with label Nevow. Show all posts

7/11/2005

LivePage rules

At SuperHappyDevHouse last weekend, I finally got the time to update the Chatola example to the latest livepage APIs, which I was developing in a series of branches named livepage-completion-notification. Since all the examples are now updated and the new API is relatively robust and stable, I merged this long-standing branch into trunk today.



These API changes were the major thing I wanted to get done before releasing Nevow 0.5. Unfortunately, after the 0.4.1 release the other major change occurred: Depending on zope.interface. formless.annotate.TypedInterface did some things with Interface that zope.interface doesn't like at all. So I'll have to decide how to deal with this; right now I'm leaning towards hacking them out using any means necessary. It won't be pretty.



With livepage solidifying, formless next up to be put through the refactoring ringer, and a planned context refactoring in the future, Nevow is really starting to move towards a stable 1.0 target.



One last thing... I have a secret LivePage project that I have been working on which I am very eager to show the world. Some of you know about it; don't tell anybody what it is yet, I want it to be a surprise :-)




5/18/2005

Multiuser Programming

When I was in High School, LambdaMOO opened to the public. I spent a lot of time in high school and college hanging out there, programming, and even did my first web application development on E_MOO, which had an HTTP server implemented in moocode. After E_MOO went down, I decided that I wanted to recreate the MOO experience as a graphical multiuser networked programming environment. The ability to log in to a machine, edit some code, manipulate the "object" whose code you just edited, and hand it to your friend halfway around the world for debugging is a very compelling experience. I hadn't seen it recreated to my satisfaction and I wanted to do it.



I spent a few years coding, but it was slow going. Both network applications and GUI applications require a different mindset than the batch process style of programming which is what you learn in computer science classes. Event driven programming takes a lot of getting used to, and even when you understand what you are doing, it can be difficult to write and debug event-driven in C or C++, the language of choice in the mid 90s.



In 1999, I was doing a lot of Flash work and saw how it might be possible to tie a Flash front end to a multiuser back end server. When Flash 5 came out, I decided to revive the idea of a graphical front end to a multiuser programing environment. I wrote a simple HTML page which contained some JavaScript DHTML code I put together for mutating the DOM and embedded a small, wide Flash movie towards the bottom of the page. The movie contained an input text box and some ActionScript which sent the contents of the box over an XMLSocket when the user pressed return.



Because the XMLSocket used null bytes to delineate each message sent across the wire, I hacked the C source of the MOO server (running a MOO core my friend Pictwe and I had been running since 1995 -- MOOf) to send null bytes between each "line" of output from the server. Because of restrictions Flash placed on the hosts and ports to which you could open an XMLSocket, I had to create an application server capable of both serving the HTML, JavaScript, and Flash files, and proxying the XMLSocket connection to the actual MOO server. I had done a few simple CGIs in perl and thought about using that, but perl sucked. I did a bit of web searching and discovered Python.



After reading the socket and threading documentation (old habits die hard) I had a simple server working. You could load the web page, type commands in a text box, press return, and your command would be sent to the server where it was executed like it came from any other client being used to access the MOO. Any time the MOO generated any output on your connected socket, the intermediary server would push it into the browser over the XMLSocket, the ActionScript would unpack it and send it to JavaScript using LiveConnect, and the JavaScript would use DHTML to change the page. Sound like AJAX? :-)



Shortly thereafter I got a full-time job writing Python web applications. After developing for a few years in Webware and Zope, I decided to play around with some ideas I had for an easier to use templating system. This led to the creation of DOMTemplate, Woven, and Nevow, and it turned out to be a longer process than I had hoped. Sometime in late 2002 I decided to revisit the idea of performing out-of-band communications with a server to allow the web application running serverside to push and pull information into and out of the browser. I called it LivePage, and it was based on a highly transparent Model-View-Controller design, where controllers received events from the browser, updated models, and views automatically re-rendered themselves based on model dependencies. The results were then shipped to the browser and some DOM hackery was employed to replace the old DOM fragment with the newly rendered view.



The original Woven implementation of LivePage used Flash XMLSocket as the out-of-band event conduit. XMLHttpRequest was around at the time, and I did attempt to use it, but it reeked of MSIE nastiness and wasn't very standard cross-browser. XMLHttpRequest also has the distinct disadvantage of being based on HTTP. XMLSocket is a persistent, two-way, asynchronous socket architecture that made it delightfully easy to implement both Client-to-Server events and Server-to-Client events. XMLHttpRequest can only send data to the server once, and if you repeatedly send data from the server to the client and handle it incrementally, the document will consume memory without bound.



People thought I was crazy to even try to make web browsers do the things I wanted to do. It'll never work, it'll never be cross-browser, browsers can't handle it, people won't understand it... But I persevered. Browser stability was a real problem. After leaving a live page open for a while, with lots of changes being sent, browsers would leak all over the place and eventually crash. Both IE and Mozilla crashed like crazy. Eventually, after Gmail came out, the browser vendors seemed to get things under control and DOM mutation is relatively reliable now.



In October of 2003 when I sat down to spend a bit of hacking to try to come up with ways to simplify Woven, Nevow went from proof-of-concept to ready to use in a weekend. It wasn't until Gmail was in private beta that I decided it was time to revisit LivePage. This time, the aim was to keep the implementation as short and easy to understand as possible, with the hopes that other people would be able to figure out how and why to use it. I also decided to use XMLHttpRequest as an experiment, to reduce the number of dependencies. XMLHttpRequest makes some aspects of the architecture more difficult (Server-to-Client events) but in some ways makes other parts of the implementation much easier.



Since I only get to work on LivePage in my spare time, it has been slow going. However, the implementation as it is in Nevow is now almost ready to tackle the task of constructing very dynamic, complex applications. There are some implementation details which, after being exposed to the real world for a while, need refactoring. I have a few ideas on how to make it even easier to use from an end-user programmer's perspective. Finally, a coherent idea of how error handling occurs between client and server is starting to take shape. In the latest livepage branch which includes some unfinished improvements, which I hope to merge in the next week or so, the server can reliably handle an exception which occurs on the client. That's right, Python code can be written to handle client-side JavaScript exceptions. Also, LivePage as it exists in the 0.4.1 release has very robust "User has left the page" notification support. If the user clicks the back button, closes the browser, or even crashes their machine, the server is guaranteed to know about it no more than a minute or so later.



I have spent 10 years of my life, on and off, working towards this dream I have. Nevow and LivePage are the latest incarnations of puzzle pieces which fit into the mosaic of this dream. Hopefully someday very soon I will start fitting the pieces together and start to see what a true multiuser web application looks like. We already have a taste for what collaboration can enable; sharing information using weblogs, instant messengers, wikis, file sharing applications, and tools like SubEthaEdit allows to more rapidly fine-tune our idea of what others are thinking. Only a few pieces are missing; a more graphical, spatial ability to arrange information, where information can be picked up easily and carried from place to place in order to sort and categorize it; a more real-time sense of community where presence information gives us a sense of who we are near and allows us to easily communicate with them; and a more immediate programming model where changes can be made to live applications and applied immediately, with results available for all to see. All the pieces are there, they just need to be put together to complete the puzzle.




3/22/2005

LiveTest

I'm at PyCon this week. PyCon is my favorite conference, ever. This year it is better than ever, with tons of people at the sprints and lots of activity.



amk told me "if you're sprinting and have gotten something
accomplished, please weblog it.", so I am :-)



Zac Bir and I sprinted on a simple PyObjC app which scratches a simple itch I have occasionally. He describes it more eloquently than I could.




While MacGregor is incredibly cool and fun, the exciting Nevow related thing I completed is LiveTest, a browser-based functional web testing framework. Since it lives in the browser and triggers actual browser events, it is capable of testing highly JavaScript based apps, such as LivePage apps. There is an example of using it to test a LivePage application, LiveAnimal, in Nevow now.



Finally, I released Nevow 0.4! There are lots of improvements and bugfixes in this release, which is available for download from here.



9/26/2004

Nevow 0.3!

Nevow 0.3 is now out! Go get it!



There has been a lot of development over the past five months, and I have been feeling overdue for doing a Nevow release for a while now. So finally today I mustered the strength to write all the ChangeLogs, READMEs, and update the examples and documentation needed for a release. And what a release it is. This release encompasses some pretty major refactorings and additions:





  • freeform-patterns: This branch rewrote almost all of the freeform form rendering code (now called webform). It makes use of the Nevow pattern/slot paradigm to allow customization of the automatically generated forms down to the finest detail.

  • ubiquitous-context: This branch focused on making the Nevow APIs more consistent by passing a context object to the URL traversal APIs. Nevow keeps track of the objects involved in URL traversal and page rendering using a stack of context objects which you can use to make information available to your components.

  • LivePage improvements: LivePage is now cross browser! Mozilla, Firefox, WinIE6, and Safari browsers are all supported. Adding support for browsers such as Opera and Konqueror should be possible as long as they support XmlHttpRequest. Also, some python-side APIs were added which make mutating the in-browser DOM a breeze: set, append, alert, and call. All these python-side objects take stan, so you can pass them XML fragments composed using Python code or extracted from XML/XHTML documents. No JavaScript skills required!

  • New Fragment class: Fragment is a Page base class which implements just those APIs required to expose data_* and render_* methods in a stan tree. It's now easy to break out your frequently used components into self-contained classes, instantiate and return them from a Page.render_* method or even another Fragment.render_* method.

  • url.URL improvements: Some new APIs make it easy to manage view state using query arguments rather than server-side sessions, which expire and aren't friendly with the back button.

  • nevow.canvas: In the tradition of LivePage comes the experimental Canvas module, which gives you a server-side Python API for drawing lines, curves, and text in the browser, with control over line thickness, border color, and opacity. Canvas gives you a socket you can keep open as long as you need to draw animations in the client browser.

  • XML Compliance: xmlfile and xmlstring now properly retain doctypes, comments, and xmlns attributes.

  • IFoo(ctx) syntax: ctx.locate(IFoo) has been deprecated in favor of the more uniform adaption syntax IFoo(ctx).

  • WSGI Implementation: This release contains a simple, incomplete WSGI application implementation. It is now possible to use Nevow to render CGI or WSGI pages without Twisted installed.

  • guard improvements: guard.SessionWrapper now works properly when it is installed in locations other than the root.

  • Chatola: Chatola, the LivePage demonstration application, has bloomed into a fully operational web-based chat server!

  • inevow.IQ: The Interface for Querying is the beginnings of a DOM querying API. Currently, it contains only the patternGenerator, onePattern, and allPatterns APIs.




Visit the web site for more information about Nevow.



7/05/2004

Canvas

Dave Hyatt has been writing about the features which have been added to WebKit to support the Dashboard in Tiger, and today he writes about a spookily familiar new feature -- the canvas.



I say it is spooky because a few weeks ago, I had the great idea to expose the Flash MX drawing API to Python on the server side using Nevow. It really was a great idea, too. In less than a week, I had a working implementation and a nice demo application, which I wrote about here.



The original idea was not to specifically have Flash glue, but to devise a server side api for drawing which would use whatever client side drawing technology was available. I originally thought of SVG as the non-flash example, but the WebKit canvas would be excellent glue to write a Nevow canvas implementation with. It would provide some things that Flash currently does not (if only on Safari), such as better integration with actual HTML.



5/02/2004

Debugging JavaScript

One of the things I hate about web development is the absolute pain in the ass that is JavaScript. It's not a terribly bad language in itself, with a decent anonymous function syntax and prototype-based object system (even if it's completely useless because there is no object database). But the fact that errors often pass silently and the debugging tools available are tedious and a pain to use makes developing with JS almost unbearable. I have often wished for the staple, the crutch of development in tool-poor environments, of the 'print' statement.


Here is how to configure Mozilla so that calls to 'dump()' will show up in the console:


Fire up Mozilla and type 'about:config' in the url bar.


Right click and choose 'New->Boolean'


Type 'browser.dom.window.dump.enabled'


Type 'true'


Start Mozilla from a shell, and you will finally be able to debug complex javascripts by printing things to the console using the 'dump' function.


By the way, to start Mozilla from the Terminal on Mac OS X, execute the binary:


'Mozilla.app/Contents/MacOS/mozilla-bin'



2/11/2004

Have you met my Evil Twin?

Well, I finally did it. I re-implemented LivePage in Nevow. It was a piece of cake, really. The hardest part was coming up with the right design for how to allow programmers access to the client object which represents a user's browser. After talking to itamar about it at length, I finally realized that the cred 'mind' concept was the perfect solution. With very little code, a programmer can write a new realm which mediates for the entire application. It can then be the central point for all the clients to communicate with each other, such as in a chat application.

I wrote a simple example chat application called Chatola. You can get the source here:

http://soundfarmer.com/content/code/chatola/

Download all three files and run the tac file using:

twistd -noy chatola.tac

Currently, you will need to have Twisted (http://twistedmatrix.com) and a recent CVS checkout of Quotient (http://divmod.org) installed. Soon, nevow will be released as a standalone package.