September 22nd, 2005

diesel, learning, evil, sweeti

When TODO items bite you in the ass

Whilst developing EventQueue I've had my Apache error log open for debugging processes and kept seeing someone looking for TODO files in mailing list archives. Which puzzled me.

host on the IP address showed that it was the MSNBot and a bit of investigation showed that, ages ago, when we were writing Mariachi we'd clearly meant to finish the next and prev links because we'd stuck TODO as the URL. Doh!

really must get round to rewriting Mariachi sometime soon.

diesel, learning, evil, sweeti

All laid out

I wanted to show all the events in a day spanning over 24 horizontal markers to represent 24 hours. Of course this has the problem that if two events are happening simultaneously then they'll overlap. So, in this scenario you move the later one right and keep going. I first attempted to do this with tables but it got real messy real fast. Then I tried with CSS and that was tricky too for a bunch of reasons.

Then Ian Malpass stepped up to the plate with this nifty bit of code

    function arrangeEvents () {
        var divs = document.getElementsByTagName( 'div' ); // find all divs
        var events = new Array;
        // find all events
        for ( var d = 0; d < divs.length; d++ ) {
            if ( divs[d].className == 'event' ) events.push( divs[d] ); 
        }
        events.sort( sortByTop ); // sort into vertical position order
        for ( var objEvent = 1; objEvent < events.length; objEvent++ ) {
            var objEventTop  = emToNum( events[objEvent], 'top'  );
            var objEventLeft = emToNum( events[objEvent], 'left' );
            for ( var refEvent = 0; refEvent < objEvent; refEvent++ ) {
                var refEventLeft   = emToNum( events[refEvent], 'left'   );
                var refEventTop    = emToNum( events[refEvent], 'top'    );
                var refEventHeight = emToNum( events[refEvent], 'height' );
                if ( refEventLeft != objEventLeft ) continue;  // not in same col
                if ( refEventTop + refEventHeight > objEventTop ) {
                    objEventLeft += increment; // are in same col - shift right
                } else {
                    break; // fine where it is
                }
            }
            events[objEvent].style.left = objEventLeft+"em"; // position event
        }
    }

which finds all divs of the class event and arranges them based on top and height which we've previously set by calculating the events' start times and durations and then multiplying by $minutes_per_division and $ems_per_division. Groovy!

diesel, learning, evil, sweeti

Aesthetically challenged

What's actually been the biggest problem is the design and usability - because I suck at that and I suck at DHTML and Javascript and CSS and AJAX and for all the pissing and moaning you get about Open Source stuff looking horrible there's no coherent resource for getting usability and designery type people to work on your open source stuff.

To be honest, I don't know who's to blame, per se - the programmers for being usability hostile or the designers for not getting involved. Chicken and Egg problem I suspect.

diesel, learning, evil, sweeti

EventQueue is go

Ages ago I wrote a web based calendar and it was good.

All this calendaring stuff has been about the aformentioned EventQueue and I finally got round to sitting down and banging out the framework for finally building it.

It's actually all come together really quickly and has shaken out a load of bugs and edgecases in Data::ICal::DateTime and, currently, it can fetch events from a number of (potentially remote) sources and collate them using the two current providers - the ICalendar one and the DBI one.

So, what's left to do?

* Multiple views

There needs to be an easy way to display in different views so that I can have .ics, RSS and hCalendar as well.

* Build and install scripts

It should be trivial to get EventQueue up and running. Stealing a trick from PHP Gallery (worst. name. EVAR!) I'm using .htaccess files to handle trick bits so it should be as easy as just doing

    % eventqueue-install 

and then editing a .config file. Although I could detect whether one exists and run a config generator if not.

* Themes

Everybody's got to have them

And basically flesh outt he interface a bit more. Going on to v2.0 I'd like to add Palm DB and SyncML providers and put in support for multiple users with an ACL. But I'll have to think about that.

diesel, learning, evil, sweeti

Speaking of Behemoths

Little known fact - Module::Pluggable grew out of an article I was writing for Perl.com about why some code needn't go into modules and should just be copied and pasted. Of course now it's a burgeoning monstrosity because it fell foul of feature creep and ... euuch. It's horrible.

Fortunately Mark Fowler has stepped up and, in the quest to make Module::Pluggable work with PAR has refactored the whole thing massively and documented some of the design descisions. Maybe when he's done I can bung in the immediate instantiation which Module::Pluggable::Fast has and maybe they can kill that once and for all.

Bitter about people forking my code without asking - me? No!