#!/usr/bin/perl
package Dudelicious;
use 5.010;
use Data::Dumper;
use version; our $VERSION = qv('0.1.0');
BEGIN {
use FindBin;
use lib "$FindBin::Bin/../lib";
use lib "$FindBin::Bin/../mojo/lib";
}
use Carp qw/ carp croak /;
use Digest::MD5 qw/ md5_hex /;
use Text::Todo;
use Mojolicious::Lite;
use Mojo::JSON;
app->home->parse( $ENV{DUDELICIOUS_HOME} ) if $ENV{DUDELICIOUS_HOME};
plugin 'json_config' => {
file => 'dudelicious.conf',
default => { todo_dir => $ENV{DUDELICIOUS_HOME} || '.', },
};
app->renderer->add_helper(
todo => sub {
my ($self) = @_;
state $todo = Text::Todo->new( $self->stash('config') );
my $file = $self->stash('file');
if ($file) {
$file =~ s/(?:\.txt)?$/\.txt/ixms;
$todo->load($file);
}
return $todo;
}
);
app->renderer->add_helper(
get_list => sub {
my ($self) = @_;
my $line = 1;
return [
map {
line => $line++,
md5 => md5_hex( $_->text ),
text => $_->text,
done => $_->done,
},
$self->helper('todo')->list
];
}
);
get '/' => sub {
my $self = shift;
my $dir = $self->helper('todo')->file('todo_dir');
opendir my $dh, $dir or croak "Unable to opendir $dir: $!";
my @files = grep {/\.te?xt$/ixms} readdir $dh;
closedir $dh;
$self->render( files => \@files, layout => 'todotxt' );
} => 'index';
get '/todotxt' => 'todotxt';
get '/l/:file' => sub {
my $self = shift;
my $format = $self->stash('format') || 'html';
if ( $format eq 'json' ) {
$self->render_json( $self->helper('get_list') );
}
else {
$self->render(
list => $self->helper('get_list'),
layout => 'todotxt'
);
}
} => 'list';
get '/l/:file/e/:line' => sub {
my $self = shift;
my $format = $self->stash('format') || 'html';
my $entry = $self->helper('get_list')->[ $self->stash('line') - 1 ];
if ( $format eq 'json' ) {
$self->render_json($entry);
}
else {
$self->render( entry => $entry, layout => 'todotxt' );
}
} => 'entry';
get '/l/:file/t' => sub {
my $self = shift;
my $format = $self->stash('format') || 'html';
if ( $format eq 'json' ) {
$self->render_json( $self->helper('todo')->known_tags );
}
else {
$self->render(
tags => $self->helper('todo')->known_tags,
layout => 'todotxt'
);
}
} => 'tags';
get '/l/:file/t/:tag' => sub {
my $self = shift;
my $format = $self->stash('format') || 'html';
my $items = $self->helper('todo')->listtag( $self->stash('tag') );
if ( $format eq 'json' ) {
$self->render_json($items);
}
else {
$self->render( items => $items, layout => 'todotxt' );
}
} => 'tag';
app->start if !caller();
1;
__DATA__
@@ list.txt.ep
% foreach my $entry (@{ $list }) {
%== include 'entry', entry => $entry;
% }
@@ entry.txt.ep
<%= $entry->{text} %>
@@ tags.txt.ep
% foreach my $tag (keys %{ $tags }) {
<%= $tag %>, <%= $tags->{$tag} %>
% }
@@ tag.txt.ep
# <%= $tag %>
% foreach my $item (@{ $items}) {
<%= $item %>
% }
@@ layouts/todotxt.txt.ep
%= content
@@ index.html.ep
% foreach my $file (@{ $files }) {
<%== $file %>
% }
@@ list.html.ep