Index: unk/BookmarkApp.pm
===================================================================
--- /trunk/BookmarkApp.pm	(revision 59)
+++ 	(revision )
@@ -1,477 +1,0 @@
-package BookmarkApp;
-use strict;
-use warnings;
-use base qw{CGI::Application};
-
-use CGI::Application::Plugin::TT;
-
-use Encode;
-use HTTP::Date qw{time2isoz time2iso time2str str2time};
-use JSON;
-use Bookmarks;
-use URI;
-
-sub setup {
-    my $self = shift;
-    $self->mode_param(path_info => 1);
-    $self->run_modes([qw{
-        list
-        feed
-        view
-        view_field
-        create
-        edit
-    }]);
-
-    my $url = $self->query->url;
-    $url .= '/' unless $url =~ m{/$};
-    my $base_uri = URI->new($url);
-
-    my $bookmarks = Bookmarks->new({
-        dbname   => $self->param('dbname'),
-        base_uri => $base_uri,
-    });
-
-    $self->param(
-        base_uri  => $base_uri,
-        bookmarks => $bookmarks,
-    );
-}
-
-sub _bookmarks { $_[0]->param('bookmarks') }
-
-sub _get_list_links {
-    my $self = shift;
-    my ($self_type, $query) = @_;
-    my @links = (
-        {
-            text => 'JSON',
-            type => 'application/json',
-            query => {
-                %$query,
-                format => 'json',
-            },
-        },
-        {
-            text => 'XBEL',
-            type => 'application/xml',
-            query => {
-                %$query,
-                format => 'xbel',
-            },
-        },
-        {
-            text => 'Atom',
-            type => 'application/atom+xml',
-            path => 'feed',
-            query => {
-                %$query,
-            },
-        },
-        {
-            text => 'CSV',
-            type => 'text/csv',
-            query => {
-                %$query,
-                format => 'csv',
-            },
-        },
-        {
-            text => 'URI List',
-            type => 'text/uri-list',
-            query => {
-                %$query,
-                format => 'text',
-            },
-        },
-        {
-            text => 'HTML',
-            type => 'text/html',
-            query => {
-                %$query,
-            },
-        },
-    );
-
-    for my $link (@links) {
-        $link->{rel}  = $link->{type} eq $self_type ? 'self' : 'alternate';
-        $link->{href} = URI->new_abs($link->{path} || '', $self->param('base_uri'));
-        $link->{href}->query_form($link->{query});
-    }
-
-    return @links;
-}
-
-sub list {
-    my $self = shift;
-    my $q = $self->query;
-
-    # check for a uri param, and if there is one present,
-    # see if a bookmark for that URI already exists
-    if (defined(my $uri = $q->param('uri'))) {
-        my $bookmark = $self->_bookmarks->get_bookmark({ uri => $uri });
-        if ($bookmark) {
-            # redirect to the view of the existing bookmark
-            $self->header_type('redirect');
-            $self->header_props(
-                -uri => $q->url . '/' . $bookmark->{id},
-            );
-            return;
-        } else {
-            # bookmark was not found; show the form to create a new bookmark
-            $bookmark->{uri} = $uri;
-            $bookmark->{title} = $q->param('title');
-            $self->header_props(
-                -type    => 'text/html',
-                -charset => 'UTF-8',
-                -status  => 404,
-            );
-            return $self->tt_process(
-                'bookmark.tt',
-                $bookmark,
-            );
-        }
-    }
-
-    # list all the bookmarks 
-    my $mtime = $self->_bookmarks->get_last_modified_time;
-
-    my $format = $q->param('format') || 'html';
-
-    my @tags = grep { $_ ne '' } $q->param('tag');
-    my $query = $q->param('q');
-    my $limit = $q->param('limit');
-    my $offset = $q->param('offset');
-    my @resources = $self->_bookmarks->get_bookmarks({
-        query  => $query,
-        tag    => \@tags,
-        limit  => $limit,
-        offset => $offset,
-    });
-    my @all_tags = $self->_bookmarks->get_tags({ selected => $tags[0] });
-    my @cotags = $self->_bookmarks->get_cotags({
-        query  => $query,
-        tag    => \@tags,
-    });
-    
-    my $title = 'Bookmarks' . (@tags ? " tagged as " . join(' & ', @tags) : '') . ($query ? " matching '$query'" : '');
-
-    if ($format eq 'json') {
-        $self->header_props(
-            -type    => 'application/json',
-            -charset => 'UTF-8',
-        );
-        return decode_utf8(
-            JSON->new->utf8->convert_blessed->encode({
-                bookmarks => \@resources,
-            })
-        );
-    } elsif ($format eq 'xbel') {
-        require XML::XBEL;
-        #TODO: conditional support; if XML::XBEL is not present, return a 5xx response
-
-        my $xbel = XML::XBEL->new;
-
-        $xbel->new_document({
-            title => $title,
-        });
-
-        for my $bookmark (@resources) {
-            my $cdatetime = time2isoz $bookmark->ctime;
-            my $mdatetime = time2isoz $bookmark->mtime;
-            # make the timestamps W3C-correct
-            s/ /T/ foreach ($cdatetime, $mdatetime);
-
-            $xbel->add_bookmark({
-                href     => $bookmark->uri,
-                title    => $bookmark->title,
-                desc     => 'Tags: ' . join(', ', @{ $bookmark->tags }),
-                added    => $cdatetime,
-                #XXX: are we sure that modified is the mtime of the bookmark or the resource?
-                modified => $mdatetime,
-            });
-        }
-
-        $self->header_props(
-            -type    => 'application/xml',
-            -charset => 'UTF-8',
-        );
-
-        return $xbel->toString;
-    } elsif ($format eq 'text') {
-        $self->header_props(
-            -type    => 'text/uri-list',
-            -charset => 'UTF-8',
-        );
-        return join '', 
-            map {
-                sprintf "# %s\n# Tags: %s\n%s\n",
-                $_->title,
-                join(', ', @{ $_->tags }), 
-                $_->uri
-            } @resources;
-    } elsif ($format eq 'csv') {
-        require Text::CSV::Encoded;
-        my $csv = Text::CSV::Encoded->new({ encoding => 'utf8' });
-        my $text = qq{id,uri,title,tags,ctime,mtime\n};
-        for my $bookmark (@resources) {
-            my $success = $csv->combine(
-                $bookmark->id,
-                $bookmark->uri,
-                $bookmark->title,
-                join(' ', @{ $bookmark->tags }),
-                $bookmark->ctime,
-                $bookmark->mtime,
-            );
-            $text .= $csv->string . "\n" if $success;
-        }
-
-        # include the local timestamp in the attchment filename
-        my $dt = time2iso;
-        $dt =~ s/[^\d]//g;
-
-        $self->header_props(
-            -type       => 'text/csv',
-            -charset    => 'UTF-8',
-            -attachment => 'bookmarks-' . join('_', @tags) . "-$dt.csv",
-        );
-        return $text;
-    } else {
-        $self->header_props(
-            -type    => 'text/html',
-            -charset => 'UTF-8',
-        );
-
-        # set the base URL, adding a trailing slash if needed
-        my $base_url = $q->url;
-        $base_url .= '/' if $base_url =~ m{/bookmarks$};
-
-        return $self->tt_process(
-            'list.tt',
-            {
-                base_url     => $base_url,
-                title        => $title,
-                query        => $query,
-                selected_tag => $tags[0],
-                search_tags  => \@tags,
-                links        => [ $self->_get_list_links('text/html', { q => $query, tag => \@tags }) ],
-                all_tags     => \@all_tags,
-                cotags       => \@cotags,
-                resources    => \@resources,
-            },
-        );
-    }
-}
-
-sub feed {
-    my $self = shift;
-    my $q = $self->query;
-
-    my $query = $q->param('q');
-    my @tags = grep { $_ ne '' } $q->param('tag');
-    my $title = 'Bookmarks' . (@tags ? " tagged as " . join(' & ', @tags) : '');
-
-    require XML::Atom;
-    $XML::Atom::DefaultVersion = "1.0";
-
-    require XML::Atom::Feed;
-    require XML::Atom::Entry;
-    require XML::Atom::Link;
-    require XML::Atom::Category;
-
-    my $feed = XML::Atom::Feed->new;
-    $feed->title($title);
-
-    my $feed_uri = URI->new_abs('feed', $self->param('base_uri'));
-    $feed_uri->query_form(tag => \@tags);
-    $feed->id($feed_uri->canonical);
-
-    for my $link ($self->_get_list_links('application/atom+xml', { q => $query, tag => \@tags })) {
-        my $atom_link = XML::Atom::Link->new;
-        $atom_link->type($link->{type});
-        $atom_link->rel($link->{rel});
-        $atom_link->href($link->{href}->canonical);
-        $feed->add_link($atom_link);
-    }
-
-    # construct a feed from the most recent 12 bookmarks
-    for my $bookmark ($self->_bookmarks->get_bookmarks({ query => $query, tag => \@tags, limit => 12 })) {
-        my $entry = XML::Atom::Entry->new;
-        $entry->id($bookmark->bookmark_uri->canonical);
-        $entry->title($bookmark->title);
-        
-        my $link = XML::Atom::Link->new;
-        $link->href($bookmark->uri);
-        $entry->add_link($link);
-        
-        $entry->summary('Tags: ' . join(', ', @{ $bookmark->tags }));
-
-        my $cdatetime = time2isoz $bookmark->ctime;
-        my $mdatetime = time2isoz $bookmark->mtime;
-        # make the timestamp W3C-correct
-        s/ /T/ foreach ($cdatetime, $mdatetime);
-        $entry->published($cdatetime);
-        $entry->updated($mdatetime);
-        
-        for my $tag (@{ $bookmark->tags }) {
-            my $category = XML::Atom::Category->new;
-            $category->term($tag);
-            $entry->add_category($category);
-        }
-
-        $feed->add_entry($entry);
-    }
-
-    $self->header_props(
-        -type => 'application/atom+xml',
-        -charset => 'UTF-8',
-    );
-    return $feed->as_xml;
-}
-
-sub view {
-    my $self = shift;
-    my $id = $self->param('id');
-    my $format = $self->query->param('format') || 'html';
-
-    my $bookmark = $self->_bookmarks->get_bookmark({ id => $id });
-    if ($bookmark) {
-        # check If-Modified-Since header to return cache response
-        if ($self->query->env->{HTTP_IF_MODIFIED_SINCE}) {
-            my $cache_time = str2time($self->query->env->{HTTP_IF_MODIFIED_SINCE});
-            if ($bookmark->mtime <= $cache_time) {
-                $self->header_type('redirect');
-                $self->header_props(
-                    -status => 304,
-                );
-                return;
-            }
-        }
-        
-        if ($format eq 'json') {
-            $self->header_props(
-                -type    => 'application/json',
-                -charset => 'UTF-8',
-            );
-            return decode_utf8(JSON->new->utf8->convert_blessed->encode($bookmark));
-        } else {
-            # display the bookmark form for this bookmark
-            $bookmark->{exists} = 1;
-            $bookmark->{created} = "Created " . localtime($bookmark->ctime);
-            $bookmark->{created} .= '; Updated ' . localtime($bookmark->mtime) unless $bookmark->ctime == $bookmark->mtime;
-            $self->header_props(
-                -type    => 'text/html',
-                -charset => 'UTF-8',
-                -Last_Modified => time2str($bookmark->mtime),
-            );
-            return $self->tt_process(
-                'bookmark.tt',
-                $bookmark,
-            );
-        }
-    } else {
-        $self->header_props(
-            -type    => 'text/html',
-            -charset => 'UTF-8',
-            -status  => 404,
-        );
-        return "Bookmark $id Not Found";
-    }
-}
-
-sub view_field {
-    my $self = shift;
-    my $id = $self->param('id');
-    my $field = $self->param('field');
-
-    my $bookmark = $self->_bookmarks->get_bookmark({ id => $id });
-    if ($bookmark) {
-        # respond with just the requested field as plain text
-        my $value = eval { $bookmark->$field };
-        if ($@) {
-            if ($@ =~ /Can't locate object method/) {
-                $self->header_props(
-                    -type    => 'text/plain',
-                    -charset => 'UTF-8',
-                    -status  => 404,
-                );
-                return qq{"$field" is not a valid bookmark data field};
-            } else {
-                die $@;
-            }
-        }
-        $self->header_props(
-            -type    => 'text/plain',
-            -charset => 'UTF-8',
-        );
-        return ref $value eq 'ARRAY' ? join(' ', @{ $value }) : $value;
-    } else {
-        $self->header_props(
-            -type    => 'text/html',
-            -charset => 'UTF-8',
-            -status  => 404,
-        );
-        return "Bookmark $id Not Found";
-    }
-}
-
-sub create {
-    my $self = shift;
-    my $q = $self->query;
-    my $uri = $q->param('uri');
-    my $title = $q->param('title');
-    my @tags = split ' ', $q->param('tags');
-    my $bookmark = $self->_bookmarks->add({
-        uri   => $uri,
-        title => $title,
-        tags  => \@tags,
-    });
-
-=begin
-
-    my $location = URI->new($q->url);
-    $location->query_form(uri => $uri) if defined $q->url_param('uri');
-    $location->fragment('updated');
-
-=cut
-
-    # return to the form
-    $self->header_type('redirect');
-    $self->header_props(
-        -uri => $bookmark->bookmark_uri->canonical,
-        -status => 303,
-    );
-}
-
-sub edit {
-    my $self = shift;
-    my $q = $self->query;
-    my $id = $self->param('id');
-
-    my $bookmark = $self->_bookmarks->get_bookmark({ id => $id });
-    if ($bookmark) {
-        # update the URI, title, and tags
-        $bookmark->uri($q->param('uri'));
-        $bookmark->title($q->param('title'));
-        $bookmark->tags([ split ' ', $q->param('tags') || '' ]);
-
-        # write to the database
-        $self->_bookmarks->update($bookmark);
-
-        # return to the form
-        $self->header_type('redirect');
-        $self->header_props(
-            -uri => $bookmark->bookmark_uri->canonical,
-            -status => 303,
-        );
-    } else {
-        $self->header_props(
-            -type    => 'text/html',
-            -charset => 'UTF-8',
-            -status  => 404,
-        );
-        return "Bookmark $id Not Found";
-    }
-}
-
-1;
Index: /trunk/app.psgi
===================================================================
--- /trunk/app.psgi	(revision 59)
+++ /trunk/app.psgi	(revision 60)
@@ -108,8 +108,4 @@
 };
 
-#builder {
-#    sub { $router->dispatch(shift); };
-#};
-
 builder {
     enable_if { $_[0]->{REMOTE_ADDR} eq $config->{proxy_ip} } 'ReverseProxy';
