diff --git a/.gitignore b/.gitignore index 90ac8b2..b7bf515 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,9 @@ inc/ /PostText.conf /PostText.yaml /PostText.yml +/post_text.conf +/post_text.yaml +/post_text.yml # AssetPack cache assets/cache/ diff --git a/PostText.pl b/PostText.pl index 5259c5a..cb8dec8 100755 --- a/PostText.pl +++ b/PostText.pl @@ -3,209 +3,8 @@ # PostText v0.1 # Jul 22 -use Mojolicious::Lite -signatures; -use Mojo::Pg; -use Data::Dumper; # For your debugging pleasure +use Mojo::Base -strict; +use lib qw{lib}; +use Mojolicious::Commands; -# Load the local modules too -use lib 'lib'; -use PostText::Model::Thread; -use PostText::Model::Remark; - -# Load Mojo plugins -plugin 'Config'; -plugin 'TagHelpers::Pagination'; -plugin AssetPack => {pipes => [qw{Css Combine}]}; - -# Helpers -helper pg => sub { - state $pg = Mojo::Pg->new(app->config->{app->mode}{'pg_string'}) -}; - -helper thread => sub { - state $thread = PostText::Model::Thread->new(pg => shift->pg) -}; - -helper remark => sub { - state $remark = PostText::Model::Remark->new(pg => shift->pg) -}; - -# Begin routing -under sub ($c) { - $c->session(expires => time + 31536000); - - 1; -}; - -# Root -get '/', sub ($c) { $c->redirect_to('list') }; - -# List -group { - under 'list'; - - get '/:list_page', [list_page => qr/[0-9]+/], {list_page => 1}, sub ($c) { - my $base_path = $c->match->path_for(list_page => undef)->{'path'}; - my $this_page = $c->param('list_page'); - my $last_page = $c->thread->last_page; - my $threads = $c->thread->by_page($this_page); - - $c->stash(status => 404) unless $threads->[0]; - - $c->stash( - threads => $threads, - this_page => $this_page, - last_page => $last_page, - base_path => $base_path - ); - - $c->render; - }; -}; - -# Post -group { - any [qw{GET POST}], '/post', sub ($c) { - my $v; - - $v = $c->validation if $c->req->method eq 'POST'; - - if ($v && $v->has_data) { - my $thread_author = $c->param('name' ); - my $thread_title = $c->param('title'); - my $thread_body = $c->param('post' ); - - $v->required('name' )->size(1, 63 ); - $v->required('title')->size(1, 127 ); - $v->required('post' )->size(2, 4000); - - if ($v->has_error) { - $c->stash(status => 400) - } - else { - $c->thread->create( - $thread_author, - $thread_title, - $thread_body - ); - - return $c->redirect_to('list'); - } - } - - return $c->render; - }; - - under '/post'; - - any [qw{GET POST}], '/:thread_id', [thread_id => qr/[0-9]+/], sub ($c) { - my ($thread_id, $v) = ($c->param('thread_id'), undef); - - $v = $c->validation if $c->req->method eq 'POST'; - - if ($v && $v->has_data) { - my $remark_name = $c->param('name'); - my $remark_body = $c->param('post'); - - $v->required('name')->size(1, 63 ); - $v->required('post')->size(2, 4000); - - if ($v->has_error) { - $c->stash(status => 400) - } - else { - $c->remark->create( - $thread_id, - $remark_name, - $remark_body - ); - - return $c->redirect_to( - 'thread_page', - {thread_id => $thread_id} - ); - } - } - - my $thread = $c->thread->by_id($thread_id); - my $last_remark = $c->remark->last_for($thread_id); - - $c->stash( - thread => $thread, - last_remark => $last_remark - ); - - return $c->render; - }; -}; - -# Thread -group { - under '/thread/:thread_id', [thread_id => qr/[0-9]+/]; - - get '/:thread_page', - [thread_page => qr/[0-9]+/], - {thread_page => 1}, sub ($c) { # My editor is so confused by this lol - my $thread_id = $c->param('thread_id'); - my $thread = $c->thread->by_id($thread_id); - my $base_path = $c->match->path_for(thread_page => undef)->{'path'}; - my $this_page = $c->param('thread_page'); - my $last_page = $c->remark->last_page_for($thread_id); - my $remarks = $c->remark->by_page_for($thread_id, $this_page); - - if (my $thread_body = %$thread{'body'}) { - $c->stash( - thread => $thread, - base_path => $base_path, - this_page => $this_page, - last_page => $last_page, - remarks => $remarks - ) - } - else { - $c->stash( - thread => [], - status => 404 - ) - } - - # Check for remarks or remark page number - $c->stash(status => 404) unless $remarks->[0] || 1 >= $this_page; - - $c->render; - }; -}; - -# Remark -group { - under '/remark'; - - get '/:remark_id', [remark_id => qr/[0-9]+/], sub ($c) { - my $remark_id = $c->param('remark_id'); - my $remark = $c->remark->by_id($remark_id); - - $c->stash(status => 404) unless $remark->{'id'}; - - $c->stash(remark => $remark); - - $c->render; - }; -}; - -# Configure things -app->secrets(app->config->{'secrets'}) || die $@; - -app->pg->migrations->from_dir('migrations')->migrate(5); - -if (my $threads_per_page = app->config->{'threads_per_page'}) { - app->thread->per_page($threads_per_page) -} - -if (my $remarks_per_page = app->config->{'remarks_per_page'}) { - app->remark->per_page($remarks_per_page) -} - -app->asset->process('main.css', 'css/PostText.css'); - -# Send it -app->start; +Mojolicious::Commands->start_app('PostText'); diff --git a/README.md b/README.md index ef6e7aa..d1006d5 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,10 @@ Run the tests locally (against development environment) ## TODOs -1. Grow into Mojo hybrid +1. I think I should revist the Post and Remark routes... +1. Grow into full blown Mojo? 1. More granular tests +1. Document post_text.conf (whoopsie) ## Crazy future ideas diff --git a/lib/PostText.pm b/lib/PostText.pm new file mode 100644 index 0000000..067c967 --- /dev/null +++ b/lib/PostText.pm @@ -0,0 +1,190 @@ +#!/usr/bin/env perl + +# Sep 22 + +package PostText; + +use Mojo::Base 'Mojolicious', -signatures; +use Mojo::Pg; +use PostText::Model::Thread; +use PostText::Model::Remark; + +sub startup($self) { + $self->plugin('Config'); + $self->plugin('TagHelpers::Pagination'); + $self->plugin(AssetPack => {pipes => [qw{Css Combine}]}); + + $self->helper(pg => sub { + state $pg = Mojo::Pg->new($self->config->{$self->mode}{'pg_string'}) + }); + $self->helper(thread => sub { + state $thread = PostText::Model::Thread->new(pg => shift->pg) + }); + $self->helper(remark => sub { + state $remark = PostText::Model::Remark->new(pg => shift->pg) + }); + + # Finish configuring some things + $self->secrets($self->config->{'secrets'}) || die $@; + + $self->pg->migrations->from_dir('migrations')->migrate(5); + + if (my $threads_per_page = $self->config->{'threads_per_page'}) { + $self->thread->per_page($threads_per_page) + } + + if (my $remarks_per_page = $self->config->{'remarks_per_page'}) { + $self->remark->per_page($remarks_per_page) + } + + $self->asset->process('main.css', 'css/PostText.css'); + + # Begin routing + my $r = $self->routes->under(sub ($c) { + $c->session(expires => time + 31536000); + + 1; + }); + + # Root redirect + $r->get('/', sub ($c) { $c->redirect_to('list') }); + + my $list = $r->under('/list'); + $list->get('/:list_page', [list_page => qr/[0-9]+/], {list_page => 1}, sub ($c) { + my $base_path = $c->match->path_for(list_page => undef)->{'path'}; + my $this_page = $c->param('list_page'); + my $last_page = $c->thread->last_page; + my $threads = $c->thread->by_page($this_page); + + $c->stash(status => 404) unless $threads->[0]; + + $c->stash( + threads => $threads, + this_page => $this_page, + last_page => $last_page, + base_path => $base_path + ); + + $c->render; + }); + + # Post + my $post = $r->under; + $post->any([qw{GET POST}], '/post', sub ($c) { + my $v; + + $v = $c->validation if $c->req->method eq 'POST'; + + if ($v && $v->has_data) { + my $thread_author = $c->param('name' ); + my $thread_title = $c->param('title'); + my $thread_body = $c->param('post' ); + + $v->required('name' )->size(1, 63 ); + $v->required('title')->size(1, 127 ); + $v->required('post' )->size(2, 4000); + + if ($v->has_error) { + $c->stash(status => 400) + } + else { + $c->thread->create( + $thread_author, + $thread_title, + $thread_body + ); + + return $c->redirect_to('list'); + } + } + + return $c->render; + }); + $post = $post->under('/post'); + $post->any([qw{GET POST}], '/:thread_id', [thread_id => qr/[0-9]+/], sub ($c) { + my ($thread_id, $v) = ($c->param('thread_id'), undef); + + $v = $c->validation if $c->req->method eq 'POST'; + + if ($v && $v->has_data) { + my $remark_name = $c->param('name'); + my $remark_body = $c->param('post'); + + $v->required('name')->size(1, 63 ); + $v->required('post')->size(2, 4000); + + if ($v->has_error) { + $c->stash(status => 400) + } + else { + $c->remark->create( + $thread_id, + $remark_name, + $remark_body + ); + + return $c->redirect_to( + 'thread_page', + {thread_id => $thread_id} + ); + } + } + + my $thread = $c->thread->by_id($thread_id); + my $last_remark = $c->remark->last_for($thread_id); + + $c->stash( + thread => $thread, + last_remark => $last_remark + ); + + return $c->render; + }); + + # Thread + my $thread = $r->under('/thread/:thread_id', [thread_id => qr/[0-9]+/]); + $thread->get('/:thread_page', [thread_page => qr/[0-9]+/], {thread_page => 1}, sub ($c) { + my $thread_id = $c->param('thread_id'); + my $thread = $c->thread->by_id($thread_id); + my $base_path = $c->match->path_for(thread_page => undef)->{'path'}; + my $this_page = $c->param('thread_page'); + my $last_page = $c->remark->last_page_for($thread_id); + my $remarks = $c->remark->by_page_for($thread_id, $this_page); + + if (my $thread_body = %$thread{'body'}) { + $c->stash( + thread => $thread, + base_path => $base_path, + this_page => $this_page, + last_page => $last_page, + remarks => $remarks + ) + } + else { + $c->stash( + thread => [], + status => 404 + ) + } + + # Check for remarks or remark page number + $c->stash(status => 404) unless $remarks->[0] || 1 >= $this_page; + + $c->render; + }); + + # Remark + my $remark = $r->under('/remark'); + $remark->get('/:remark_id', [remark_id => qr/[0-9]+/], sub ($c) { + my $remark_id = $c->param('remark_id'); + my $remark = $c->remark->by_id($remark_id); + + $c->stash(status => 404) unless $remark->{'id'}; + + $c->stash(remark => $remark); + + $c->render; + }); +} + +1;