source: bookmarks/trunk/BookmarkApp.pm @ 5

Last change on this file since 5 was 5, checked in by peter, 12 years ago

Switched to using CGI::Application and CGI::Application::Dispatch for the web application organization and dispatching, instead of the custom dispatch code

File size: 4.7 KB
Line 
1package BookmarkApp;
2use strict;
3use warnings;
4use base qw{CGI::Application};
5
6use DBI;
7use Encode;
8use JSON;
9use Template;
10use Bookmarks;
11
12my $template = Template->new;
13
14my $dbname = 'new.db';
15my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", "", "", { RaiseError => 1 });
16my $bookmarks = Bookmarks->new({
17    dbh => $dbh,
18});
19
20sub setup {
21    my $self = shift;
22    $self->mode_param(path_info => 1);
23    $self->run_modes([qw{
24        list
25        view
26        edit
27    }]);
28}
29
30sub list {
31    my $self = shift;
32    my $q = $self->query;
33
34    # check for a uri param, and if there is one present,
35    # see if a bookmark for that URI already exists
36    if (defined(my $uri = $q->param('uri'))) {
37        my $bookmark = $bookmarks->get_bookmark({ uri => $uri });
38        if ($bookmark) {
39            # redirect to the view of the existing bookmark
40            $self->header_type('redirect');
41            $self->header_props(
42                -uri => $q->url . '/' . $bookmark->{id},
43            );
44            return;
45        } else {
46            # bookmark was not found; show the form to create a new bookmark
47            $bookmark->{uri} = $uri;
48            $bookmark->{title} = $q->param('title');
49            $self->header_props(
50                -type    => 'text/html',
51                -charset => 'UTF-8',
52                -status  => 404,
53            );
54            $template->process(
55                'bookmark.tt',
56                $bookmark,
57                \my $output,
58            );
59            return $output;
60        }
61    }
62
63    # list all the bookmarks
64    my $format = $q->param('format') || 'html';
65    my $tag = $q->param('tag');
66    my @resources = $bookmarks->get_resources({ tag => $tag });
67    my @all_tags = $bookmarks->get_tags({ selected => $tag });
68    my @cotags = $bookmarks->get_cotags({ tag => $tag });
69
70    if ($format eq 'json') {
71        $self->header_props(
72            -type    => 'application/json',
73            -charset => 'UTF-8',
74        );
75        return decode_utf8(
76            encode_json({
77                resources => \@resources,
78            })
79        );
80    } else {
81        $self->header_props(
82            -type    => 'text/html',
83            -charset => 'UTF-8',
84        );
85
86        # set the base URL, adding a trailing slash if needed
87        my $base_url = $q->url;
88        $base_url .= '/' if $base_url =~ m{/bookmarks$};
89
90        $template->process(
91            'list.tt',
92            {
93                base_url     => $base_url,
94                selected_tag => $tag,
95                tags         => \@all_tags,
96                cotags       => \@cotags,
97                resources    => \@resources,
98            },
99            \my $output,
100        );
101        return $output;
102    }
103}
104
105sub view {
106    my $self = shift;
107    my $id = $self->param('id');
108    my $field = $self->param('field');
109
110    my $bookmark = $bookmarks->get_bookmark({ id => $id });
111    if ($bookmark) {
112        if ($field) {
113            # respond with just the requested field as plain text
114            $self->header_props(
115                -type    => 'text/plain',
116                -charset => 'UTF-8',
117            );
118            my $value = $bookmark->{$field};
119            return ref $value eq 'ARRAY' ? join(',', @{ $value }) : $value;
120        } else {
121            # display the bookmark form for this bookmark
122            $bookmark->{exists} = 1;
123            $bookmark->{created} = "Created " . localtime($bookmark->{ctime});
124            $bookmark->{created} .= '; Updated ' . localtime($bookmark->{mtime}) unless $bookmark->{ctime} == $bookmark->{mtime};
125            $self->header_props(
126                -type    => 'text/html',
127                -charset => 'UTF-8',
128            );
129            $template->process(
130                'bookmark.tt',
131                $bookmark,
132                \my $output,
133            );
134            return $output;
135        }
136    } else {
137        $self->header_props(
138            -type    => 'text/html',
139            -charset => 'UTF-8',
140            -status  => 404,
141        );
142        return "Bookmark $id Not Found";
143    }
144}
145
146#TODO: split this into edit and create methods
147sub edit {
148    my $self = shift;
149    my $q = $self->query;
150    #TODO: get the bookmark based on the id and edit it directly?
151    #TODO: deal with changing URIs
152    my $uri = $q->param('uri');
153    my $title = $q->param('title');
154    my @tags = split ' ', $q->param('tags');
155    $bookmarks->add({
156        uri   => $uri,
157        title => $title,
158        tags  => \@tags,
159    });
160
161=begin
162
163    my $location = URI->new($q->url);
164    $location->query_form(uri => $uri) if defined $q->url_param('uri');
165    $location->fragment('updated');
166
167=cut
168
169    # return to the form
170    $self->header_type('redirect');
171    $self->header_props(
172        -uri => $ENV{REQUEST_URI},
173        -status => 303,
174    );
175}
176
1771;
Note: See TracBrowser for help on using the repository browser.