Index: trunk/lib/BookmarksApp.pm
===================================================================
--- trunk/lib/BookmarksApp.pm	(revision 81)
+++ trunk/lib/BookmarksApp.pm	(revision 81)
@@ -0,0 +1,106 @@
+package BookmarksApp;
+
+use strict;
+use warnings;
+
+use parent qw{Plack::Component};
+use Plack::Util::Accessor qw{config_file config _app _controller};
+
+use YAML;
+use Plack::Builder;
+use Plack::Request;
+use Router::Resource;
+
+use Bookmarks::Controller;
+
+sub prepare_app {
+    my $self = shift;
+
+    -e $self->config_file or die "Config file " . $self->config_file . " not found\n";
+
+    my $config = YAML::LoadFile($self->config_file);
+    $self->config($config);
+
+    my $router = router {
+        resource '/' => sub {
+            GET {
+                # check for a uri param, and if there is one present,
+                # see if a bookmark for that URI already exists; if so
+                # redirect to that bookmark, and if not, show the form
+                # to create a new bookmark
+                if (defined $self->_controller->request->param('uri')) {
+                    return $self->_controller->find_or_new;
+                }
+
+                # otherwise return a list
+                return $self->_controller->list;
+            };
+            POST {
+                # create the bookmark and redirect to the new bookmark's edit form
+                return $self->_controller->create_and_redirect;
+            };
+        };
+
+        resource '/list' => sub {
+            GET {
+                return $self->_controller->list;
+            };
+        };
+
+        resource '/feed' => sub {
+            GET {
+                return $self->_controller->feed;
+            };
+        };
+
+        resource '/{id}' => sub {
+            GET {
+                my ($env, $params) = @_;
+                return $self->_controller->view($params->{id});
+            };
+            POST {
+                my ($env, $params) = @_;
+                return $self->_controller->update_and_redirect($params->{id});
+            };
+        };
+
+        resource '/{id}/{field}' => sub {
+            GET {
+                my ($env, $params) = @_;
+                return $self->_controller->view_field($params->{id}, $params->{field});
+            };
+        };
+    };
+
+    $self->_app(
+        builder {
+            enable_if { $_[0]->{REMOTE_ADDR} eq $config->{proxy_ip} } 'ReverseProxy';
+            enable_if { $_[0]->{REQUEST_METHOD} ne 'GET' } 'Auth::Digest', (
+                realm           => 'Bookmarks',
+                secret          => $config->{digest_key},
+                password_hashed => 1,
+                authenticator   => sub { $config->{digest_password} }
+            );
+            sub { $router->dispatch(shift); };
+        }
+    );
+}
+
+sub call {
+    my $self = shift;
+    my $env = shift;
+
+    # initialize the controller based on this request
+    $self->_controller(
+        Bookmarks::Controller->new({
+            request => Plack::Request->new($env),
+            dbname  => $self->config->{dbname},
+        })
+    );
+
+    # dispatch to the app
+    $self->_app->($env);
+}
+
+# module return
+1;
