The Saga of Blog

Last night, I did a complete ground-up rewrite of Blog. I was very, very happy with it, until radix asked why I wasn't using Form. (I used InputHandlers in the way I had originally written them, and finally got them to work) While with InputHandlers, the validators were able to validate one piece of data and call a method when input was valid, Form just collects multiple Arguments (InputHandlers, encapsulation of input validation code) into a MethodSignature and lets you bind the method signature to a method. If you use a FormProcessor, passing the bound FormMethod, and all input validation passes, the method gets called. Simple.

But it's not so simple. There are lots of moving parts I don't fully understand... why are MethodSignature construction and FormMethod binding separate steps? Couldn't you just pass the method to MethodSignature's constructor, and have the FormMethod functionality on the MethodSignature object? Also, are you meant to subclass FormProcessor and override errorViewFactory and viewFactory? I think it would be nicer to pass a callback and errback to FormProcessor. Maybe if I talk to glyph about it, we can simplify the interaction between all these parts, ditch InputHandler, and write some documentation.


Personal Web Proxy

I wrote this as a comment on 0xDECAFBAD, and thought I would duplicate it here:

Personally, I am very interested in developing and using the PersonalWebProxy. The first thing I thought about writing was a look-ahead accellerator -- when you visit a page, the proxy fetches that page and all the pages that are linked from that page, so when you click a link the page is already downloaded.

Another thing I'd like is a permanent history. Whenever I use any browser to browse through the proxy, the PWP should keep track of where I have been, and allow me to review this history chronologically, and also perhaps automatically sort things by keyword. I'd also like this history to be (once I have set up PWP to do so) synchronized with a remote server, so for example, when I am browsing at home, my history file gets synchronized with my web host, and when I am browsing at work, the same history file on my web host is updated.

Something that goes along with this idea is a permanent bookmarks interface. Visiting the PWP application on a certain web port should show me a list of bookmarks and allow me to add to them, categorize them, etc. The big advantage here would be the syncronization I just talked about with my web host space. My bookmarks would then be available from any host on the internet; no matter what machine I am using (as long as I'm running PWP), my bookmarks would also be locally available.

Another idea I have been thinking about ever since you started talking about the PersonalWebProxy project is something like a mail proxy. The way it would work is, you would set up the PWP to connect to your mail account as a client. It would then download certain mail messages (more about that later) and re-serve them as a local mail server. You would then set up your email client to talk to the mail server running inside PWP. Thus, the same sort of transformation that occurs while you're browsing web pages occurs to your email.

The first thing I would do with this is set up the server only to download email from email addresses in a certain list. Then I would allow rules based sorting. Of course, this functionality is all present in a basic email client, but once you're relatively sure you're not downloading spam you can start doing more interesting things. (The idea of only downloading email messages from people in a list is similar to only accepting instant messages from people in your buddy list)

So things start to get more interesting: We index email for searching, and synchronize email with the email repository on my web host; we parse email messages from friends looking for URLs and have the web proxy immediately download the pages so they are on the hard drive for later, instant viewing; we can send ourselves commands in a simple command language from anything that can send email. Commands could be things like "Bookmark this URL that I don't have time to look at right now"; "Delay delivery of this reminder until the event is near"; etc.

Anyway, this is all just wild pie-in-the-sky dreaming, which I don't normally do. But the prospects of improving our daily internet experience with these ideas, using an application built on Twisted, is very exciting, and very possible.



It really is time to finish Blog. It is the reason I started developing Woven, and as usual I got sidetracked into developing framework for months and months. A weblog is such a simple web application and finishing Blog is just a matter of setting aside the time to do it...

Blogger is such a primitive tool.


I have been following the PyObjC development for a few years now. I think I even have commit privileges at sourceforge. But unfortunately I haven't had any projects which would allow me to build a GUI application that runs only on Mac OS X. I have been following the mailing list with great interest, and now that I have some time off I got a chance to play with it, finally.

Holy shit.

This is everything I dreamed could be possible way back in the Rhapsody days -- a truly RAD, truly OO GUI development environment, so far ahead of anything else it's mind boggling.

Needless to say, I will be producing some applications immediately.


Woven progress

Last weekend while I was up in Paradise with my Dad, I started working on the WebConduit2 client side javascript event queue. It's such a simple concept -- queue up messages that the client wants to send to the server in an Array, and send them one at a time using the input IFrame, waiting until the server has replied to send the next message. However, IE on Mac OS X complains that the Array doesn't have an 'unshift' method. It works on Chimera.

Well, since I haven't written the node-replacement code for IE yet either, I guess I can wait to debug the event queue. The node-replacement code for IE should be incredibly easy with the outerHTML property.

Glyph checked in his Tapestry controller. I really like the implementation, although sometimes I worry a little about too much magic. Especially prepending a capital V to the view name -- I think we could do without that. Either use the full name including V in your HTML template, or leave off the V in the Python module. Anyway, the concept of having a main Resource object that dispatches to other Resource objects using getChild is a strong one. Using wchild_ is ok if your URLs are static, but I'll definately have to write a short tutorial on building dynamic URL heirarchies using getChild. It's so easy and powerful, but I have a feeling most people just don't know how to use it.

I'm going to try posting to my weblog more frequently. I'd like more people to know about my design decisions and progress on Woven.


WebConduit: Two-way Live Asynchronous Web Page

This is a project I have been working on for a while now, and I have been working on the idea (a graphical MOO environment) for almost 8 years now! It's a live, two way, asynchronous web page; a web page that never has to refresh the entire page, either to send data to the server or for the server to send data to the web page.

Of course, the same thing is possible in Flash with the XMLSocket object; in fact, the first actual implementation I did of a MOO client in a web page used a small Flash movie as the inputline/output controller. But this version requires no plug ins; is fairly cross browser compatible; and works great!

I will most certainly be including the ability to send JavaScript to a web page asynchronously in my web framework, WebMVC, based on the Twisted network framework, written in Python. If you're interested, you can run the WebConduit yourself by downloading twisted and the files here.

See the output of LambdaMOO in a whole new light!


Disabling fink

Mach-O MacPython IDE in the CVS tree

Jack has made significant progress with the Mach-O Framework build of Python lately, and has posted instructions for people interested in testing what will become the out of the box distribution of Python 2.3 for Mac OS X. There has been a slight amount of difficulty getting things to work properly, however, so I thought I'd summarize some of the issues people have run into and provide step-by-step instructions for those interested in getting this working.

First, make sure the machine you will install on has not had it's default UNIX software overridden by fink. There have been problems reported by users with fink-installed software on their systems, and it's probably best if you attempt this on a system on which no fink software has been installed. However, if you have installed fink and still wish to try, you may be able to get things to work by disabling fink temporarily using these instructions (it worked for me.)

  • Open a new, fresh terminal.

  • Check your path by typing
    echo $PATH

  • If you see any path entries starting with /sw/, these entries were made by fink.
  • If you have fink entries, set your path for this terminal session by typing
    setenv PATH /bin:/usr/bin:/usr/local/bin

Checking python out of CVS

Check python out of cvs using the instructions at http://sourceforge.net/cvs/?group_id=5470

  • Type
    cvs -d:pserver:anonymous@cvs.python.sourceforge.net:/cvsroot/python login

  • At the password prompt, press return.

  • Type
    cvs -z3 -d:pserver:anonymous@cvs.python.sourceforge.net:/cvsroot/python co

  • Wait while cvs checks out the latest python source files from the tree.

Downloading WASTE

In order to run the MacPython IDE, you need to be able to compile the waste module. There is a binary library available which, when placed in the correct place, the python build process will find and link the python waste module against.

  • Visit http://www.merzwaren.com/waste/

  • Under Downloadable Files, get the latest 2.1 release.

  • If necessary, unstuff and mount the disk image.

  • In the Finder, navigate to ~/python/dist

  • While holding down option, drag the WASTE disk from your desktop or another finder window into ~/python/dist
    • If you don't hold down option, OS X may try to make an alias instead of copying.

  • Rename the folder "waste"

  • This may not be necessary any more, but it cannot hurt: In a terminal, type
    ranlib ~/python/dist/waste/Static\ Libraries/libWASTE.a

Compile and install Python as a Framework

Make sure you are in a terminal whose PATH does not include fink directories, as described above.

  • Change to the python source directory.
    cd ~/python/dist/src

  • ./configure --enable-framework

  • make

  • make frameworkinstall

  • make osxapps

If all went well, you should now have some very useful python applications in /Applications/Python! If anything went wrong, please let the PythonMac mailing list know.


Linebreaks and Advanced Editor.py in the Mach-O MacPython IDE

I finally got some time and energy to pick up on the Mach-O MacPython project again today. I had been poking around in aetools, writing some code that will allow me to control Mac applications with Python, and was using the Mach-O MacPython IDE basically for it's "Run all" button. Since the underlying Python that is running the Mach-O IDE is really UNIX Python, it expects to see \n as the line ending character, but WASTE doesn't do a linebreak when it sees \n. So basically, you end up with one really, really long line. But, happily, the "Run all" button would faithfully tell UNIX Python to run the file, \n line endings and all, so it was at least of some utility.

After I had finished poking around with the ae* modules and gensuitemodule.py, I made a diff and applied it to a fresh CVS checkout on my Boss' laptop, since he was eager to play with the code I have been generating. (Side note: I figured out how to use diff and patch; "cvs diff | mydiff.diff" on one machine and "patch -p0
The patch applied quite easily, and soon enough I was controlling InDesign from Python. I thought to myself, "if only you could actually use the editor in the IDE..." Jack is working the political machinery on Python-dev trying to get his universal newlines patch accepted, and once he does, none of this will be required, but meanwhile, how about this hack...

When you open a file in the IDE, it gets read into a string. Check to see what kind of newlines the file has, and keep a record of it. Then, convert every newline in the string to \r.

When you save to disk, convert \r to the original newline character.

Ugly as hell, but it works! And isn't that really all that matters to most people?

While I was at it, I added the Advanced Editor from here, as well. All I needed to do was add "from Carbon " in front of all of the toolbox import statements.

Good things are happening in the world of UNIX/MacPython integration...

Here's a screenshot of the MacPython IDE opening and editing files with UNIX line endings, with the Advanced Editor patch applied.