root/lang/perl/Catalyst-Controller-Atompub/trunk/samples/MyBlog/lib/MyBlog/Controller/EntryCollection.pm @ 1860

Revision 1860, 4.0 kB (checked in by takemaru, 7 years ago)

lang/perl/Catalyst-Controller-Atompub: imported

Line 
1package # hide from PAUSE
2    MyBlog::Controller::EntryCollection;
3
4use strict;
5use warnings;
6
7use Atompub::DateTime qw( datetime );
8use Atompub::MediaType qw( media_type );
9use HTTP::Status;
10use POSIX qw( strftime );
11use String::CamelCase qw( camelize );
12use Time::HiRes qw( gettimeofday );
13
14use base qw( Catalyst::Controller::Atompub::Collection );
15
16my $ENTRIES_PER_PAGE = 10;
17my $TABLE_NAME       = 'entries';
18
19my $MODEL = join '::', 'DBIC', camelize( $TABLE_NAME );
20
21sub get_feed :Atompub(list) {
22    my ( $self, $c ) = @_;
23
24    ## URI without parameters
25    my $uri = $self->collection_resource->uri;
26
27    my $feed = $self->collection_resource->body;
28
29    my $page = $c->req->param('page') || 1;
30
31    my $attr = {
32        offset   => ( $page - 1 ) * $ENTRIES_PER_PAGE,
33        rows     => $ENTRIES_PER_PAGE,
34        order_by => 'edited desc',
35    };
36
37    my $rs = $c->model( $MODEL )->search( {}, $attr );
38
39    while ( my $resource = $rs->next ) {
40        my $entry = XML::Atom::Entry->new( \$resource->body );
41        $feed->add_entry( $entry );
42    }
43
44    $feed->alternate_link( $c->req->base . 'html' );
45    $feed->first_link( $uri );
46    $feed->previous_link( "$uri?page=" . ($page-1) ) if $page > 1;
47    $feed->next_link( "$uri?page=" . ($page+1) ) if $rs->count >= $ENTRIES_PER_PAGE;
48
49    return $self;
50}
51
52sub create_resource :Atompub(create) {
53    my ( $self, $c ) = @_;
54
55    # URI of the new Entry, which was determined by C::C::Atompub
56    my $uri = $self->entry_resource->uri;
57
58    return $self->error( $c, RC_CONFLICT, "Resource name is used (change Slug): $uri" )
59        if $c->model( $MODEL )->find( { uri => $uri } );
60
61    my $entry = $self->entry_resource->body;
62
63    # Edit $entry if needed
64
65    my $vals = {
66        edited => $self->edited->iso,
67        uri    => $uri,
68        etag   => $self->calculate_new_etag( $c, $uri ),
69        body   => $entry->as_xml,
70    };
71
72    $c->model( $MODEL )->create( $vals )
73        || return $self->error( $c, RC_INTERNAL_SERVER_ERROR, 'Cannot create new resource' );
74
75    return $self;
76}
77
78sub get_resource :Atompub(read) {
79    my ( $self, $c ) = @_;
80
81    my $uri = $c->req->uri;
82
83    my $rs = $c->model( $MODEL )->find( { uri => $uri } )
84        || return $self->error( $c, RC_NOT_FOUND );
85
86    $self->entry_resource->body( XML::Atom::Entry->new( \$rs->body ) );
87
88    return $self;
89}
90
91sub update_resource :Atompub(update) {
92    my ( $self, $c ) = @_;
93
94    my $uri = $c->req->uri;
95
96    # Edit $entry if needed
97
98    my $rs = $c->model( $MODEL )->find( { uri => $uri } )
99        || return $self->error( $c, RC_NOT_FOUND );
100
101    my $vals = {
102        edited => $self->edited->iso,
103        uri    => $uri,
104        etag   => $self->calculate_new_etag( $c, $uri ),
105        body   => $self->entry_resource->body->as_xml,
106    };
107
108    $rs->update( $vals )
109        || return $self->error( $c, RC_INTERNAL_SERVER_ERROR, "Cannot update resource: $uri" );
110
111    return $self;
112}
113
114sub delete_resource :Atompub(delete) {
115    my ( $self, $c ) = @_;
116
117    my $uri = $c->req->uri;
118
119    my $rs = $c->model( $MODEL )->find( { uri => $uri } )
120        || return $self->error( $c, RC_NOT_FOUND );
121
122    $rs->delete
123        || return $self->error( $c, RC_INTERNAL_SERVER_ERROR, "Cannot delete resource: $uri" );
124
125    return $self;
126}
127
128sub make_edit_uri {
129    my ( $self, $c, @args ) = @_;
130
131    my @uris = $self->SUPER::make_edit_uri( $c, @args );
132
133    # return, if $uris[0] is not used
134    return wantarray ? @uris : $uris[0]
135        unless $c->model( $MODEL )->find( { uri => $uris[0] } );
136
137    my ( $sec, $usec ) = gettimeofday;
138    my $dt = strftime '%Y%m%d-%H%M%S', localtime( $sec );
139    $usec  = sprintf '%06d', $usec;
140
141    # insert $dt-$usec before extension
142    $_ =~ s{(\.[^./?]+)$}{-$dt-$usec$1} for @uris;
143
144    return @uris;
145}
146
147sub find_version {
148    my ( $self, $c, $uri ) = @_;
149
150    my $rs = $c->model( $MODEL )->find( { uri => $uri } ) || return;
151
152    return ( etag => $rs->etag );
153#    return ( etag => $rs->etag, last_modified => datetime( $rs->edited )->str );
154}
155
156sub calculate_new_etag {
157    my ( $self, $c, $uri ) = @_;
158    my ( $sec, $usec ) = gettimeofday;
159    my $dt = join '-', strftime( '%Y%m%d-%H%M%S', localtime($sec) ), sprintf( '%06d', $usec );
160    join '/', $uri, $dt;
161}
162
1631;
Note: See TracBrowser for help on using the browser.