Hola Paul,
Post by Paul GearI've been talking to Lance & Pat on IRC about some ideas i want to work
on with respect to the the way my email works. They tell me that much
of it is on the radar for Dragonfly, but that a) it's not going to be
there for quite a while, and b) the web UI is not even working at the
moment.
I've replied to your other off-list email, but hopefully this goes a bit
more in depth. I'll just be discussing the code that I had been working
on before. Perhaps somebody would be nice enough to wikify some of this?
There are two major bits that make up the new web stack. There's
Crystal, which is basically the backend server bits (so, ideally, we'd
just use Crystal to host our admin, web UI stuff, mobile interfaces, and
whatever else), and Avocado, which is our neato Dragonfly replacement.
For everyone's reference, there's two wiki pages that describe how to
grab hold of the code and install it (in order):
* http://www.bongo-project.org/Installing_Crystal
* http://www.bongo-project.org/Installing_Avocado
The new code I've written works reasonably well as a basic read-only
webmail system. The following things haven't been implemented yet that
I'd like to see before we do a release with it:
* Pagination (this one is easy, probably good way to get a feel of the
codebase).
* Ability to delete, star and mark messages as unread/read.
* Some sort of framework that enables users to trivially add/remove
plugins.
* Composition support (UI implemented, just needs to be hooked up)
* Proper authentication - the main reason this hasn't been properly
done was because it hadn't been decided how authentication was going
to work (ie just do some sessionless thing like DF, perhaps a mix).
It looks like we'll probably just go with Dragonfly's idea, unless
anyone wants to suggest anything else. The server does support BASIC
authentication against the store in its current stage.
The backend - Crystal - requires Python 2.4, and a nice lightweight WSGI
web framework called Werkzeug. It doesn't directly depend on any Bongo
bits; however, you can choose from a store backend, a simple testing
flat file backend, or alternatively an IMAP4 backend that I've been
cooking up (performance is *crap* for the IMAP backend unless you're
running it on the local system). Do note that if you're using any system
other than store, you don't get nice things like conversations support,
or nice search (though, this doesn't work in newer versions of store
anyway). Crystal is licensed under the MIT/X11 license (although I can
dual-license it if need be).
The frontend - Avocado - is written in Javascript and uses a lightweight
JS library called MooTools. The visual style is almost identical to
Dragonfly. Avocado itself is really quite modular; most of the
functionality will end up being provided by plugins, so you can pick and
choose what bits you want (and optionally, users can pick what extra
features they want). For example, all the mail support is being added as
a plugin, so you can just choose not to load that module and it'll still
work fine. Avocado's base libraries (ie the cool code that communicates
with the server and things) is licensed under MIT/X11, while the actual
UI bits, core client code and plugins are licensed under GPLv2 or later.
Post by Paul Gearhttp://paul.gear.dyndns.org/node/297
A number of the ideas you've suggested there are along the lines of what
I was thinking; particularly about getting the user to provide the inbox
as a list of items that need sorting, and then using the sorted GTD
categories to actually finish tasks. I have some mockups somewhere
around here, I might scan them and put them somewhere when I get time.
http://www.bongo-project.org/Avocado#Ideas were some of the ideas I came
up with when doing my brainstorming sessions. There are also some
interesting papers that you might want to read that I've put up on the
wiki at http://www.bongo-project.org/Inspirational_Material#Papers
Post by Paul GearWhere do i go to start learning & hacking on Dragonfly?
This bit gets a bit technical. Read through it and try to understand if
you'd like. I'm probably assuming some background technical knowledge in
Python and/or Javascript here, but hey.
Server wise, the structure is somewhat simple. There are three
directories: crystal, demodata and serve.
'crystal' contains the WSGI application. application.py, utils.py and
views.py are core code that is provided to all modules. The only core
views that are provided is a simple index redirect (/) and a version
information JSON document (/version).
The authentication subdirectory contains authentication modules. These
should probably be subclassed (rather than their parent being just
'object'). 'datastores' obviously describes the different backends
available (these should also be subclassed).
The 'modules' subdirectory contains the different web applications that
are hosted by Crystal. At the moment, the only one that actually
contains code is 'dragonfly'. 'avocado' should probably be removed,
since it's empty, and just confuses.
'demodata' contains some simple mail messages stored as textfiles that
get used by the flat file backend (ie. if you don't have store going).
'serve' contains all the other files that get hosted up if there's no
matching URL in one of the 'modules'. This is where you install Avocado
to (you can even make this a symbolic link to elsewhere if you like).
Generally, the code to produce data for new views is really simple.
Here's an example from mail.py in 'dragonfly':
@expose('/user/<user>/mail/message/<guid>')
@requires_auth
def mail_show (request, user, guid):
"""Dumps a message in the store to a JSON 'message' object."""
datastore = local('application').datastore
msg = datastore.get_message (guid)
datastore.cleanup ()
if not msg:
return render_error (4225, "No such message")
return render_json (msg)
Easy, huh? That works with anything, no matter what the backend (store,
file, IMAP, etc).
The web frontend is a bit more interesting. I've devised this notion of
'clients', and each client can have whatever look and feel, layout, and
whatever else. However, each client can work with the same plugins, so
that the same mail plugin code works no matter whether you're using a
mobile client (eg index-iphone.html) or the desktop client (index.html).
Oh, by the way, most of the core classes have decent documentation on
each function and their purpose, but I'll try to outline briefly below.
Each client basically just defines what HTML elements have what purpose,
manage hooking up clicking the 'Login' button to actually logging a user
in, general UI janitorial stuff, and creating HTML elements for the
SourceManager. Take a look at Dragonfly.js/Client.js (abstract class).
SourceManager, you ask? Each 'tab' on the side in the web UI (or item in
the iPhone client) represents a source. When defining a source, you
basically detail its name, ID, HTML class, actions, what toolbars it
needs, the content it provides, and any other callback functions you
might want (eg things dropped, source activated).
You can talk to the SourceManager and ask it to add or remove a source,
activate anything that's already been added, or turn an HTML object into
something that can be dragged and dropped onto a source (eg a message
onto a calendar to create an appointment with the two linked).
To communicate with the server, we use the DataQuery class. It's really
quite cool - it handles caching and requesting objects merely by passing
a dictionary of the information you know about an object that uniquely
identifies it. You'll probably want to check out the documentation for
that, since it's easier to look at code examples for this than explain
it.
If you're doing some of the Javascript hacking, you can actually just
look at the documentation for most of the core JS classes by running
the ./make-html-docs.sh script in the base checkout directory.
You might also want to check out the MooTools documentation over at
http://mootools.net/docs/
Hopefully that wasn't _too_ much to digest. ;)
Cheers,
Alex Hixon