From 4a5647092c9d8530775ebdd817456dc9c5704845 Mon Sep 17 00:00:00 2001 From: Manager Bot Date: Mon, 14 Nov 2022 19:53:29 +0000 Subject: [PATCH] Refactored --- Web/lib/MJB/Web/Controller/Dashboard.pm | 425 ++++++++++++++++-------- 1 file changed, 295 insertions(+), 130 deletions(-) diff --git a/Web/lib/MJB/Web/Controller/Dashboard.pm b/Web/lib/MJB/Web/Controller/Dashboard.pm index 120f22c..f1901ae 100644 --- a/Web/lib/MJB/Web/Controller/Dashboard.pm +++ b/Web/lib/MJB/Web/Controller/Dashboard.pm @@ -1,62 +1,103 @@ package MJB::Web::Controller::Dashboard; use Mojo::Base 'Mojolicious::Controller', -signatures; - +#== +# GET /dashboard | show_dashboard +#== sub index ($c) { push @{$c->stash->{blogs}}, $c->stash->{person}->search_related('blogs')->all; } +#== +# GET /dashboard/blog/:id/ | show_dashboard_blog { id => blog.id } +# +# Show the dashboard for a blog. +#== sub blog ( $c ) { - my $blog = $c->stash->{blog}; -} - -sub jobs ( $c ) { } +#== +# GET /dashboard/blog/:id/posts | show_dashboard_blog_posts { id => blog.id } +# +# This route shows a list of blog posts and allows editing or deleting the posts. +#== sub blog_posts ( $c ) { my $blog = $c->stash->{blog}; + $c->stash->{blog_posts} = [ map { $_->read } @{$c->jekyll($blog->domain->name)->list_posts} ]; +} + +#== +# GET /dashboard/blog/:id/post | show_dashboard_blog_post { id => blog.id } +# +# This route loads the editor for making a new blog post. +#== +sub blog_post ( $c ) { - my $blog_posts = $c->stash->{blog_posts} = [ map { $_->read } @{$c->jekyll($blog->domain->name)->list_posts} ]; } -sub blog_post_edit ( $c ) { +#== +# POST /dashboard/blog/:id/post | do_dashboard_blog_post { id => blog.id } +# postTitle | This is the title of the post, for the YAML header +# postDate | This is the date of the post, for the YAML header +# postContent | This is the content of the post, in markdown for the file contents +# +# This route creates a new blog post. +# +# The slug is created from the date and title. +#== +sub do_blog_post ( $c ) { my $blog = $c->stash->{blog}; - my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); + my $title = $c->stash->{form_title} = $c->param('postTitle'); + my $date = $c->stash->{form_date} = $c->param('postDate'); + my $content = $c->stash->{form_content} = $c->param('postContent'); - if ( ! $post ) { - $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); - } -} + my $jekyll = $c->jekyll($blog->domain->name); -sub blog_post_alter ( $c ) { - my $blog = $c->stash->{blog}; - my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); + my $post = $c->stash->{post} = $jekyll->new_post( _make_slug( $date, $title ) ); - if ( ! $post ) { - $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); - } -} + $post->markdown( $content ); + $post->headers->{title} = $title; + $post->headers->{date} = $date; + $post->headers->{layout} = 'post'; + + $jekyll->write_post( $post ); -sub do_blog_post_remove ( $c ) { - my $blog = $c->stash->{blog}; - - my $jekyll = $c->jekyll($blog->domain->name); - my $post = $jekyll->get_post( $c->param('file') ); - - $jekyll->remove_markdown_file( $post ); - $c->sync_blog( $blog ); - $c->flash( confirmation => "That post has been removed." ); + $c->flash( confirmation => "Created $title!" ); $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); } +#== +# GET /dashboard/blog/:id/post/edit | show_dashboard_blog_post_edit { id => blog.id } +# mdfile | This is the name of the mdfile for the post to edit. +# +# This route loads a post for editing with the simple editor. +#== +sub blog_post_edit ( $c ) { + my $blog = $c->stash->{blog}; + my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); + if ( ! $post ) { + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); + } +} + +#== +# POST /dashboard/blog/:id/post/edit | do_dashboard_blog_post_edit { id => blog.id } +# mdfile | This is the name of the file for the post to edit +# postTitle | This is the title of the post, for the YAML header +# postDate | This is the date of the post, for the YAML header +# postContent | This is the content of the post, in markdown for the file contents +# +# This route is used to edit a post. It will update the title, date and content of an existing +# markdown file. +#== sub do_blog_post_edit ( $c ) { my $blog = $c->stash->{blog}; @@ -79,61 +120,92 @@ sub do_blog_post_edit ( $c ) { $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); } -sub blog_post ( $c ) { +#== +# GET /dashboard/blog/:id/post/alter | show_dashboard_blog_post_alter { id => blog.id } +# mdfile | This is the name of the mdfile for the post to edit. +# +# This route loads a post for editing with the raw editor that allows editing the post headers. +#== +sub blog_post_alter ( $c ) { my $blog = $c->stash->{blog}; -} -sub _make_slug ( $date, $title ) { - - my $slug; + my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); - if ( $date =~ /^(\d{4}-\d{2}-\d{2})/ ) { - $slug = $1; + if ( ! $post ) { + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); } - - s/[^a-zA-Z0-9_-]+/-/g, s/^[^a-zA-Z0-9]+//, s/[^a-zA-Z0-9]+$// for $title; - - $slug .= "-$title.markdown"; - - return $slug; - } -sub do_blog_post ( $c ) { +#== +# POST /dashboard/blog/:id/post/alter | do_dashboard_blog_post_alter { id => blog.id } +# postContent | Text for the markdown section of the file +# postHeader | Text for the headers section of the file +# +# This route alters a post, it differs from the post editor in that it expects the full +# post headers as text. +#== +sub do_blog_post_alter ( $c ) { my $blog = $c->stash->{blog}; - my $title = $c->stash->{form_title} = $c->param('postTitle'); - my $date = $c->stash->{form_date} = $c->param('postDate'); - my $content = $c->stash->{form_content} = $c->param('postContent'); - - my $jekyll = $c->jekyll($blog->domain->name); - - - my $post = $c->stash->{post} = $jekyll->new_post( _make_slug( $date, $title ) ); + my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); + + my $content = $c->param('postContent'); + my $headers = $c->param('postHeaders'); + $post->set_headers_from_string( $headers ); $post->markdown( $content ); - $post->headers->{title} = $title; - $post->headers->{date} = $date; - $post->headers->{layout} = 'post'; - $jekyll->write_post( $post ); + $c->jekyll($blog->domain->name)->write_post( $post ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "Updated Post " . $post->headers->{title} . "!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); +} +#== +# POST /dashboard/blog/:id/post/remove | show_dashboard_blog_post_remove { id => blog.id } +# file | This is the name of the file for the post to remove +# +# This route is used to remove a blog post. +#== +sub do_blog_post_remove ( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + my $post = $jekyll->get_post( $c->param('file') ); + + $jekyll->remove_markdown_file( $post ); + $c->sync_blog( $blog ); - $c->flash( confirmation => "Created $title!" ); + $c->flash( confirmation => "That post has been removed." ); $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); } +#== +# GET /dashboard/blog/:id/settings | show_dashboard_blog_settings { id => blog.id } +# +# This route shows the blog settings in a simple editor. +#== sub blog_settings ($c) { my $blog = $c->stash->{blog}; my $data = $c->jekyll($blog->domain->name)->config->data; - my $title = $c->stash->{form_title} = $data->{title}; - my $desc = $c->stash->{form_desc} = $data->{description}; - my $email = $c->stash->{form_email} = $data->{email}; + $c->stash->{form_title} = $data->{title}; + $c->stash->{form_desc} = $data->{description}; + $c->stash->{form_email} = $data->{email}; } +#== +# POST /dashboard/blog/:id/settings | do_dashboard_blog_settings { id => blog.id } +# configTitle | The title of the blog +# configDesc | The description of the blog +# configEmail | The email address to show on the blog +# +# This route updates the blog configuration. +#== sub do_blog_settings ($c) { my $blog = $c->stash->{blog}; @@ -155,6 +227,11 @@ sub do_blog_settings ($c) { $c->redirect_to( $c->url_for( 'show_dashboard_blog_settings', { id => $blog->id } ) ); } +#== +# GET /dashboard/blog/:id/config | show_dashboard_blog_config { id => blog.id } +# +# This route shows the blog config as a single text file that can be edited. +#== sub blog_config ( $c ) { my $blog = $c->stash->{blog}; @@ -164,6 +241,12 @@ sub blog_config ( $c ) { my $config_text = $c->stash->{form_config} = $config->as_text; } +#== +# POST /dashboard/blog/:id/config | do_dashboard_blog_config { id => blog.id } +# blogConfig | The full text of the blog configuration file. +# +# This route updates the blog configuration. +#== sub do_blog_config ( $c ) { my $blog = $c->stash->{blog}; @@ -182,34 +265,32 @@ sub do_blog_config ( $c ) { $c->redirect_to( $c->url_for( 'show_dashboard_blog_config', { id => $blog->id } ) ); } -sub blog_builds ( $c ) { - my $blog = $c->stash->{blog}; +#== +# GET /dashboard/blog/:id/jobs | show_dashboard_blog_jobs { id => blog.id } +# +# This route shows the jobs interface with recently run jobs and their logs. +#== +sub jobs ( $c ) { } +#== +# GET /dashboard/blog/:id/media | show_dashboard_blog_media { id => blog.id } +# +# This route shows the media / static files hosted for this blog.. +#== sub blog_media ( $c ) { my $blog = $c->stash->{blog}; - my $media_files = $c->stash->{media_files} = $c->jekyll($blog->domain->name)->list_media; -} - -sub do_blog_media_remove( $c ) { - my $blog = $c->stash->{blog}; - - my $jekyll = $c->jekyll($blog->domain->name); - my $media_file = Mojo::File->new( $jekyll->repo_path . "/assets/media/" . $c->param('file') ); - - if ( $media_file->stat ) { - $jekyll->remove_file( $media_file->to_string, "Removed media file" . $media_file->basename ); - } - - $c->sync_blog_media( $blog ); - - $c->flash( confirmation => "Removed " . $media_file->basename ); - $c->redirect_to( $c->url_for( 'show_dashboard_blog_media', { id => $blog->id } ) ); - + $c->stash->{media_files} = $c->jekyll($blog->domain->name)->list_media; } +#== +# POST /dashboard/blog/:id/media | do_dashboard_blog_media { id => blog.id } +# upload | An HTTP file upload object +# +# This route uploads a file and then stores it in the blog as assets/media/filename +#== sub do_blog_media ( $c ) { my $blog = $c->stash->{blog}; @@ -240,12 +321,49 @@ sub do_blog_media ( $c ) { $c->redirect_to( $c->url_for( 'show_dashboard_blog_media', { id => $blog->id } ) ); } +#== +# POST /dashboard/blog/:id/media/*file | do_dashboard_blog_media { id => blog.id, file => name.ext } +# +# This route removes a static file that had been hosted. +# +# TODO: This should probably be /media/remove and then accept the file as a parameter. +#== +sub do_blog_media_remove( $c ) { + my $blog = $c->stash->{blog}; + + my $jekyll = $c->jekyll($blog->domain->name); + my $media_file = Mojo::File->new( $jekyll->repo_path . "/assets/media/" . $c->param('file') ); + + if ( $media_file->stat ) { + $jekyll->remove_file( $media_file->to_string, "Removed media file" . $media_file->basename ); + } + + $c->sync_blog_media( $blog ); + + $c->flash( confirmation => "Removed " . $media_file->basename ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_media', { id => $blog->id } ) ); + +} + +#== +# GET /dashboard/blog/:id/history | show_dashboard_blog_history { id => blog.id } +# +# Show the git history for this blog. +#== sub blog_history ( $c ) { my $blog = $c->stash->{blog}; - my $history = $c->stash->{history} = $c->jekyll($blog->domain->name)->history; + $c->stash->{history} = $c->jekyll($blog->domain->name)->history; } +#== +# POST /dashboard/blog/:id/history | show_dashboard_blog_history { id => blog.id } +# commit_hash | The commit hash to undo +# +# This route will undo the commit hash given and then deploy the website. +# +# TODO: This should use restore instead, it would make more sense. +#== sub do_blog_history ( $c ) { my $blog = $c->stash->{blog}; @@ -267,12 +385,62 @@ sub do_blog_history ( $c ) { } } +#== +# GET /dashboard/blog/:id/pages | show_dashboard_blog_pages { id => blog.id } +# +# This route shows a list of blog pages and allows editing or deleting the pages. +#== sub blog_pages ( $c ) { my $blog = $c->stash->{blog}; my $blog_pages = $c->stash->{blog_pages} = [ map { $_->read } @{$c->jekyll($blog->domain->name)->list_pages} ]; } +#== +# GET /dashboard/blog/:id/page | show_dashboard_blog_page { id => blog.id } +# +# This route loads the editor for making a new blog page. +#== +sub blog_page ( $c ) { + +} + +#== +# POST /dashboard/blog/:id/page | do_dashboard_blog_page { id => blog.id } +# pagePage | The page for the new page to use +# pageHeaders | The YAML content for the new page +# pageContent | The Markdown content for the new page +# +# This route creates a new page on the blog. +#== +sub do_blog_page ( $c ) { + my $blog = $c->stash->{blog}; + + my $path = $c->param('pagePath'); + my $content = $c->param('pageContent'); + my $headers = $c->param('pageHeaders'); + + my $jekyll = $c->jekyll($blog->domain->name); + + my $page = $jekyll->new_page( "/$path.markdown" ); + + $page->set_headers_from_string( $headers ); + $page->markdown( $content ); + + $jekyll->write_post( $page ); + + $c->sync_blog( $blog ); + + $c->flash( confirmation => "Created Page " . $page->filename . "!" ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); +} + +#== +# GET /dashboard/blog/:id/page/edit | show_dashboard_blog_page_edit { id => blog.id } +# file | This is the name of the file for the page to edit. +# +# This route loads a page for editing. +#== sub blog_page_edit ( $c ) { my $blog = $c->stash->{blog}; @@ -289,25 +457,15 @@ sub blog_page_edit ( $c ) { } -sub do_blog_page_remove ( $c ) { - my $blog = $c->stash->{blog}; - - my $jekyll = $c->jekyll($blog->domain->name); - - my $blog_pages = $c->stash->{blog_pages} = [ map { $_->read } @{$jekyll->list_pages} ]; - - my $rel_path = $c->param('file'); - - my ( $page ) = grep { $_->rel_path eq $rel_path } @{$blog_pages}; - - $jekyll->remove_markdown_file( $page ); - - $c->sync_blog( $blog ); - - $c->flash( confirmation => "That page has been removed." ); - $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); -} - +#== +# POST /dashboard/blog/:id/page/edit | do_dashboard_blog_page_edit { id => blog.id } +# file | The value of rel_path for the file we are editing. +# pageHeaders | The new YAML content for the file. +# pageContent | The new Markdown content for the file. +# +# This route edits a blog page identified by file, and updates it to use the +# pageHeaders and pageContent supplied. +#== sub do_blog_page_edit ( $c ) { my $blog = $c->stash->{blog}; @@ -338,49 +496,56 @@ sub do_blog_page_edit ( $c ) { $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); } -sub do_blog_post_alter ( $c ) { +#== +# POST /dashboard/blog/:id/page/remove | do_dashboard_blog_page_edit { id => blog.id } +# file | The value of rel_path for the file we are removing. +# +# This route deletes a blog page identified by file.. +#== +sub do_blog_page_remove ( $c ) { my $blog = $c->stash->{blog}; - - my $post = $c->stash->{post} = $c->jekyll($blog->domain->name)->get_post( $c->param('mdfile') ); - my $content = $c->param('postContent'); - my $headers = $c->param('postHeaders'); - - $post->set_headers_from_string( $headers ); - $post->markdown( $content ); - - $c->jekyll($blog->domain->name)->write_post( $post ); + my $jekyll = $c->jekyll($blog->domain->name); + + my $blog_pages = $c->stash->{blog_pages} = [ map { $_->read } @{$jekyll->list_pages} ]; + + my $rel_path = $c->param('file'); + + my ( $page ) = grep { $_->rel_path eq $rel_path } @{$blog_pages}; + + $jekyll->remove_markdown_file( $page ); $c->sync_blog( $blog ); - $c->flash( confirmation => "Updated Post " . $post->headers->{title} . "!" ); - $c->redirect_to( $c->url_for( 'show_dashboard_blog_posts', { id => $blog->id } ) ); -} - -sub blog_page ( $c ) { - my $blog = $c->stash->{blog}; + $c->flash( confirmation => "That page has been removed." ); + $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); } -sub do_blog_page ( $c ) { - my $blog = $c->stash->{blog}; - - my $path = $c->param('pagePath'); - my $content = $c->param('pageContent'); - my $headers = $c->param('pageHeaders'); +#== +# Helper Function +# +# Create a slug from a date and title. +# +# The date should capture YYYY-MM-DD from the YAML section. +# +# The title will be transformed to all lowercase alphanumeric. +# Extra characters will be removed if they are in the front or end of the title. +# Extra characters in the middle of the title will be replaced with a single dash(-). +#== +sub _make_slug ( $date, $title ) { + + my $slug; - my $jekyll = $c->jekyll($blog->domain->name); + if ( $date =~ /^(\d{4}-\d{2}-\d{2})/ ) { + $slug = $1; + } - my $page = $jekyll->new_page( "/$path.markdown" ); + s/[^a-zA-Z0-9_-]+/-/g, s/^[^a-zA-Z0-9]+//, s/[^a-zA-Z0-9]+$// for $title; - $page->set_headers_from_string( $headers ); - $page->markdown( $content ); + $slug .= lc("-$title.markdown"); - $jekyll->write_post( $page ); - - $c->sync_blog( $blog ); + return $slug; - $c->flash( confirmation => "Created Page " . $page->filename . "!" ); - $c->redirect_to( $c->url_for( 'show_dashboard_blog_pages', { id => $blog->id } ) ); } 1;