Annotation of todotxt/Text-Todo/bin/dudelicious.pl, Revision 1.10
1.8 andrew 1: #!/usr/bin/perl
1.1 andrew 2:
1.2 andrew 3: package Dudelicious;
4:
1.10 ! andrew 5: use 5.010;
1.6 andrew 6: use Data::Dumper;
1.4 andrew 7: use version; our $VERSION = qv('0.1.0');
8:
1.6 andrew 9: BEGIN {
10: use FindBin;
11: use lib "$FindBin::Bin/../lib";
1.8 andrew 12: use lib "$FindBin::Bin/../mojo/lib";
1.6 andrew 13: }
1.2 andrew 14:
1.5 andrew 15: use Carp qw/ carp croak /;
1.6 andrew 16: use Digest::MD5 qw/ md5_hex /;
17: use Text::Todo;
1.5 andrew 18:
1.1 andrew 19: use Mojolicious::Lite;
1.6 andrew 20: use Mojo::JSON;
1.5 andrew 21:
22: app->home->parse( $ENV{DUDELICIOUS_HOME} ) if $ENV{DUDELICIOUS_HOME};
1.1 andrew 23:
1.6 andrew 24: plugin 'json_config' => {
25: file => 'dudelicious.conf',
26: default => { todo_dir => $ENV{DUDELICIOUS_HOME} || '.', },
27: };
1.1 andrew 28:
1.10 ! andrew 29: app->renderer->add_helper(
! 30: todo => sub {
! 31: state $todo = Text::Todo->new( shift->stash('config') );
! 32: return $todo;
! 33: }
! 34: );
! 35:
! 36: app->renderer->add_helper(
! 37: get_list => sub {
! 38: my ( $self, $file ) = @_;
! 39:
! 40: $self->helper('todo')->load($file) if $file;
! 41:
! 42: my $line = 1;
! 43: return [
! 44: map {
! 45: line => $line++,
! 46: md5 => md5_hex( $_->text ),
! 47: text => $_->text,
! 48: done => $_->done,
! 49: },
! 50: $self->helper('todo')->list
! 51: ];
! 52: }
! 53: );
! 54:
1.5 andrew 55: get '/' => sub {
1.1 andrew 56: my $self = shift;
1.5 andrew 57:
1.10 ! andrew 58: my $dir = $self->helper('todo')->file('todo_dir');
1.5 andrew 59: opendir my $dh, $dir or croak "Unable to opendir $dir: $!";
60: my @files = grep {/\.te?xt$/ixms} readdir $dh;
61: closedir $dh;
62:
63: $self->render( files => \@files, layout => 'todotxt' );
64: } => 'index';
65:
1.9 andrew 66: get '/todotxt' => 'todotxt';
67:
1.5 andrew 68: get '/l/:file' => sub {
1.6 andrew 69: my $self = shift;
70: my $file = $self->stash('file') . '.txt';
71: my $format = $self->stash('format') || 'html';
1.10 ! andrew 72: my $list = $self->helper( 'get_list' => $file );
1.5 andrew 73:
1.6 andrew 74: if ( $format eq 'json' ) {
1.7 andrew 75: $self->render_json($list);
1.6 andrew 76: }
77: else {
1.7 andrew 78: $self->render( list => $list, layout => 'todotxt' );
1.6 andrew 79: }
1.5 andrew 80: } => 'list';
81:
1.6 andrew 82: get '/l/:file/e/:line' => sub {
83: my $self = shift;
84: my $file = $self->stash('file') . '.txt';
85: my $format = $self->stash('format') || 'html';
1.10 ! andrew 86: my $entry
! 87: = $self->helper( 'get_list' => $file )->[ $self->stash('line') - 1 ];
1.6 andrew 88:
89: if ( $format eq 'json' ) {
1.7 andrew 90: $self->render_json($entry);
1.6 andrew 91: }
92: else {
1.7 andrew 93: $self->render( entry => $entry, layout => 'todotxt' );
1.6 andrew 94: }
1.5 andrew 95: } => 'entry';
1.1 andrew 96:
1.3 andrew 97: app->start unless caller();
1.5 andrew 98:
1.1 andrew 99: __DATA__
100:
1.5 andrew 101: @@ list.txt.ep
1.6 andrew 102: % foreach my $entry (@{ $list }) {
103: %== include 'entry', entry => $entry;
1.5 andrew 104: % }
105:
106: @@ entry.txt.ep
1.6 andrew 107: <%= $entry->{text} %>
1.5 andrew 108:
109: @@ layouts/todotxt.txt.ep
110: %= content
111:
1.1 andrew 112: @@ index.html.ep
1.5 andrew 113: % foreach my $file (@{ $files }) {
114: <%== $file %> <br />
115: % }
116:
117: @@ list.html.ep
118: <h1><%= $file %></h1>
119: <ol>
1.6 andrew 120: % foreach my $entry (@{ $list }) {
1.5 andrew 121: <li>
1.6 andrew 122: %= include 'entry', entry => $entry;
1.5 andrew 123: </li>
124: % }
125: </ol>
1.1 andrew 126:
1.5 andrew 127: @@ entry.html.ep
1.6 andrew 128: <%= $entry->{text} %>
1.5 andrew 129:
130: @@ layouts/todotxt.html.ep
1.1 andrew 131: <!doctype html><html>
1.9 andrew 132: <head>
133: <title>Funky!</title>
134: <link rel="stylesheet" href="<%= url_for 'todotxt', format => 'css' %>">
135: </head>
1.1 andrew 136: <body><%== content %></body>
137: </html>
1.4 andrew 138:
1.9 andrew 139: @@ todotxt.css.ep
140: body {
141: background: LightGoldenRodYellow;
142: color: DarkSlateBlue;
143: }
144:
145: .inplaceeditor-saving {
146: background: url(images/saving.gif) bottom right no-repeat;
147: }
148:
149:
1.4 andrew 150: __END__
151:
152: =head1 NAME
153:
154: dudelicious - A Mojolicous interface to your todotxt files
155:
156: =head1 VERSION
157:
158: Since the $VERSION can't be automatically included,
159: here is the RCS Id instead, you'll have to look up $VERSION.
160:
1.10 ! andrew 161: $Id: dudelicious.pl,v 1.9 2010/04/30 17:30:57 andrew Exp $
1.4 andrew 162:
163: =head1 SYNOPSIS
164:
165: dudelicious daemon
166:
167: Then browse to http://localhost:3000/
168:
169: =head1 DESCRIPTION
170:
171: A Mojolicous web app for access to your todotxt files
172:
173: The modules are there to give more access to my todo.txt file from more
174: places. My goal is a web API for a web interface and then a WebOS version for
175: my Palm Pre.
176:
177: For more information see L<http://todotxt.com>
178:
179: =head1 USAGE
180:
181: See todo.pl -h
182:
183: =head1 OPTIONS
184:
185: See todo.pl -h
186:
187: =head1 REQUIRED ARGUMENTS
188:
189: See todo.pl -h
190:
191: =head1 CONFIGURATION AND ENVIRONMENT
192:
193: =head1 DIAGNOSTICS
194:
195: =head1 DEPENDENCIES
196:
197: Perl Modules:
198:
199: =over
200:
201: =item Text::Todo
202:
203: =item Mojolicous::Lite
204:
205: =item version
206:
207: =back
208:
209:
210: =head1 BUGS AND LIMITATIONS
211:
212: No bugs have been reported.
213:
214: =head1 AUTHOR
215:
216: Andrew Fresh C<< <andrew@cpan.org> >>
217:
218:
219: =head1 LICENSE AND COPYRIGHT
220:
221: Copyright (c) 2010, Andrew Fresh C<< <andrew@cpan.org> >>. All rights reserved.
222:
223: This module is free software; you can redistribute it and/or
224: modify it under the same terms as Perl itself. See L<perlartistic>.
225:
226:
227: =head1 DISCLAIMER OF WARRANTY
228:
229: BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
230: FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
231: OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
232: PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
233: EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
234: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
235: ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
236: YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
237: NECESSARY SERVICING, REPAIR, OR CORRECTION.
238:
239: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
240: WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
241: REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
242: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
243: OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
244: THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
245: RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
246: FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
247: SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
248: SUCH DAMAGES.
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>