Skip to content

Commit

Permalink
update todo app for my own use
Browse files Browse the repository at this point in the history
Now this is a useful app. I just need to write a README for other people
and a blog post
  • Loading branch information
preaction committed Jan 1, 2019
1 parent d5645fa commit 44f015b
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 48 deletions.
10 changes: 1 addition & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,12 @@ matrix:
- perl: "5.26"
env: COVERAGE=1

- perl: "5.26"
- perl: "5.28"
env:
- TEST_YANCY_EXAMPLES=1
services:
- postgresql
addons:
postgresql: "9.5"
apt:
packages:
- libdbd-pg-perl
install:
- cpan-install --deps
- cpan-install --coverage
- cpan-install Mojo::Pg
- cpan-install Mojo::SQLite Mojolicious::Plugin::PODViewer
- cpan-install Mojolicious::Command::export
- cpan-install DateTime DateTime::Event::Recurrence
Expand Down
4 changes: 2 additions & 2 deletions eg/todo-app/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
db.log
cpanfile.snapshot
db
local
data.db-*
4 changes: 2 additions & 2 deletions eg/todo-app/cpanfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
requires 'Mojolicious', '7';
requires 'Mojolicious::Plugin::Yancy', '0.023';
requires 'Mojo::Pg', '4';
requires 'Mojolicious::Plugin::Yancy', '1.018';
requires 'Mojo::SQLite', '3';
requires 'DateTime';
requires 'DateTime::Event::Recurrence';
9 changes: 9 additions & 0 deletions eg/todo-app/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

root=$(dirname $0)
scp $root/cpanfile preaction.me:app/todo-app
scp $root/myapp.pl preaction.me:app/todo-app
scp $root/todo-app.service preaction.me:.config/systemd/user
ssh preaction.me 'cd app/todo-app && carton install'
ssh preaction.me 'systemctl --user daemon-reload'
ssh preaction.me 'systemctl --user enable todo-app.service'
ssh preaction.me 'systemctl --user restart todo-app.service'
98 changes: 63 additions & 35 deletions eg/todo-app/myapp.pl
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
#!/usr/bin/env perl
use v5.24;
use experimental qw( signatures postderef );
use Mojolicious::Lite;
use Mojo::Pg;
use Mojo::SQLite;
use Mojo::Util qw( trim unindent );
use DateTime;
use DateTime::Event::Recurrence;
use Scalar::Util qw( looks_like_number );

helper pg => sub { state $pg = Mojo::Pg->new( 'postgres:///myapp' ) };
app->pg->auto_migrate(1)->migrations->from_data;
helper sqlite => sub {
state $sqlite = Mojo::SQLite->new(
'sqlite:' . app->home->child( 'data.db' ),
);
};
app->sqlite->auto_migrate(1)->migrations->from_data;

if ( my $path = $ENV{MOJO_REVERSE_PROXY} ) {
my @parts = grep { $_ } split m{/}, $path;
app->hook( before_dispatch => sub {
my ( $c ) = @_;
push @{$c->req->url->base->path}, @parts;
});
}

plugin Yancy => {
backend => { Pg => app->pg },
backend => { Sqlite => app->sqlite },
read_schema => 1,
collections => {
mojo_migrations => {
'x-hidden' => 1,
},
todo_item => {
title => 'To-Do Item',
description => unindent( trim q{
Expand All @@ -37,16 +48,12 @@
interval => 1,
},
properties => {
title => {
'x-order' => 1,
},
period => {
description => 'How long a task is available to do.',
'x-order' => 2,
enum => [qw( day week month )],
},
interval => {
description => 'The number of periods each between each instance.',
'x-order' => 3,
},
start_date => {
description => 'The date to start using this item. Defaults to today.',
Expand Down Expand Up @@ -112,15 +119,15 @@ sub _parse_ymd {
SELECT COUNT(*) FROM todo_log
WHERE todo_item_id = ? AND start_date = ?
SQL
my $result = $c->pg->db->query( $exists_sql, $todo_item->{id}, $start_dt->ymd );
my $result = $c->sqlite->db->query( $exists_sql, $todo_item->{id}, $start_dt->ymd );
my $exists = !!$result->array->[0];
if ( !$exists ) {
my $end_dt = _build_end_dt( $todo_item, $start_dt );
my $insert_sql = <<' SQL';
INSERT INTO todo_log ( todo_item_id, start_date, end_date )
VALUES ( ?, ?, ? )
SQL
$c->pg->db->query( $insert_sql,
$c->sqlite->db->query( $insert_sql,
$todo_item->{id}, $start_dt->ymd, $end_dt->ymd,
);
}
Expand All @@ -132,7 +139,7 @@ sub _parse_ymd {

# Fetch all to-do items
my $sql = 'SELECT * FROM todo_item WHERE start_date <= ?';
my $result = $c->pg->db->query( $sql, $dt->ymd );
my $result = $c->sqlite->db->query( $sql, $dt->ymd );
my $todo_items = $result->hashes;
for my $todo_item ( @$todo_items ) {
my $series = _build_recurrence( $todo_item );
Expand All @@ -142,28 +149,33 @@ sub _parse_ymd {
}
};

get '/:date' => { date => '' }, sub {
get '/' => sub {
my ( $c ) = @_;
my $dt = $c->stash( 'date' ) ? _parse_ymd( $c->stash( 'date' ) ) : DateTime->today;
$c->redirect_to( 'todo.list', date => DateTime->today->ymd( '-' ) );
};

get '/:date' => sub {
my ( $c ) = @_;
my $dt = _parse_ymd( $c->stash( 'date' ) );
$c->build_todo_log( $dt );
my $sql = <<' SQL';
SELECT log.id, item.title, log.complete
FROM todo_log log
JOIN todo_item item
ON log.todo_item_id = item.id
WHERE log.start_date <= ?::date
AND log.end_date >= ?::date
WHERE log.start_date <= ?
AND log.end_date >= ?
SQL
my $result = $c->pg->db->query( $sql, ($dt->ymd) x 2 );
my $result = $c->sqlite->db->query( $sql, ($dt->ymd) x 2 );
my $items = $result->hashes;
return $c->render(
template => 'index',
template => 'todo/list',
date => $dt,
next_date => $dt->clone->add( days => 1 ),
prev_date => $dt->clone->add( days => -1 ),
items => $items,
);
} => 'index';
} => 'todo.list';

post '/log/:log_id' => sub {
my ( $c ) = @_;
Expand All @@ -172,29 +184,38 @@ sub _parse_ymd {
? DateTime->today->ymd
: undef;
my $sql = 'UPDATE todo_log SET complete = ? WHERE id = ?';
$c->pg->db->query( $sql, $complete, $id );
$c->sqlite->db->query( $sql, $complete, $id );
my $start_date =
$c->pg->db->query( 'SELECT start_date FROM todo_log WHERE id = ?', $id )
$c->sqlite->db->query( 'SELECT start_date FROM todo_log WHERE id = ?', $id )
->hash->{start_date};
return $c->redirect_to( 'index', date => $start_date );
return $c->redirect_to( 'todo.list', date => $start_date );
} => 'update_log';

app->yancy->plugin( 'Auth::Basic', {
collection => 'users',
username_field => 'username',
password_digest => {
type => 'SHA-1',
},
route => app->routes,
} );

app->start;
__DATA__
@@ index.html.ep
@@ todo/list.html.ep
% layout 'default';
% title 'Welcome';
<div class="row">
<div class="col-md-12">
<div class="d-flex justify-content-between align-items-center">
<a class="btn btn-outline-dark" href="<%= url_for index => ( date => $prev_date->ymd ) %>">
<a class="btn btn-outline-dark" href="<%= url_for 'todo.list' => ( date => $prev_date->ymd ) %>">
&lt; <%= $prev_date->ymd %>
</a>
<h1><%= $date->ymd %></h1>
<a class="btn btn-outline-dark" href="<%= url_for index => ( date => $next_date->ymd ) %>">
<a class="btn btn-outline-dark" href="<%= url_for 'todo.list' => ( date => $next_date->ymd ) %>">
<%= $next_date->ymd %> &gt;
</a>
</div>
Expand Down Expand Up @@ -229,27 +250,35 @@ sub _parse_ymd {
<html>
<head>
<title><%= title %></title>
<link rel="stylesheet" href="/yancy/bootstrap.css" />
%= stylesheet '/yancy/bootstrap.css'
</head>
<body>
<main class="container">
<%= content %>
</main>
<footer class="container mt-2 d-flex justify-content-between">
<a href="/" class="btn btn-secondary">Today</a>
<a href="/yancy" class="btn btn-secondary">Edit</a>
</footer>
</body>
</html>
@@ migrations
-- 1 up
CREATE TYPE todo_interval AS ENUM ( 'day', 'week', 'month' );
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL
);
CREATE TABLE todo_item (
id SERIAL PRIMARY KEY,
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
period todo_interval NOT NULL,
period VARCHAR(20) NOT NULL,
interval INTEGER DEFAULT 1 CHECK ( interval >= 1 ) NOT NULL,
start_date DATE NOT NULL DEFAULT CURRENT_DATE
);
CREATE TABLE todo_log (
id SERIAL PRIMARY KEY,
id INTEGER PRIMARY KEY AUTOINCREMENT,
todo_item_id INTEGER REFERENCES todo_item ( id ) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
Expand All @@ -258,5 +287,4 @@ sub _parse_ymd {
-- 1 down
DROP TABLE todo_log;
DROP TABLE todo_item;
DROP TYPE todo_interval;
DROP TABLE users;
12 changes: 12 additions & 0 deletions eg/todo-app/todo-app.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=To-do list app
After=nginx.service

[Service]
Environment=MOJO_HOME=/home/doug/app/todo-app
Environment=MOJO_REVERSE_PROXY=/todo
WorkingDirectory=/home/doug/app/todo-app
ExecStart=/usr/bin/carton exec perl myapp.pl daemon -l http://*:6037

[Install]
WantedBy=multi-user.target

0 comments on commit 44f015b

Please sign in to comment.