From a589ec7ed941f3d0c972267c42bd3c2d30b75408 Mon Sep 17 00:00:00 2001 From: Matthew Connelly Date: Mon, 28 Dec 2015 20:09:51 +0000 Subject: [PATCH] a number of changes too great to list here, but basically it's a ton of (currently incomplete) refactoring --- bin/app.psgi | 9 ++ config.yml | 21 ++-- environments/dev.yml | 5 + environments/prod.yml | 5 + layout/base.html | 13 --- lib/App/BlogAlba.pm | 163 +++++++++-------------------- lib/App/BlogAlba/Article.pm | 0 {layout => views/layouts}/foot.inc | 0 {layout => views/layouts}/head.inc | 0 views/layouts/main.tt | 98 +++++++++++++++++ {layout => views/layouts}/post.inc | 0 11 files changed, 180 insertions(+), 134 deletions(-) create mode 100644 bin/app.psgi create mode 100644 environments/dev.yml create mode 100644 environments/prod.yml delete mode 100644 layout/base.html create mode 100644 lib/App/BlogAlba/Article.pm rename {layout => views/layouts}/foot.inc (100%) rename {layout => views/layouts}/head.inc (100%) create mode 100644 views/layouts/main.tt rename {layout => views/layouts}/post.inc (100%) diff --git a/bin/app.psgi b/bin/app.psgi new file mode 100644 index 0000000..d12ba1d --- /dev/null +++ b/bin/app.psgi @@ -0,0 +1,9 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use FindBin; +use lib "$FindBin::Bin/../lib"; + +use App::BlogAlba; +App::BlogAlba->to_app; diff --git a/config.yml b/config.yml index 0d02948..316d4dc 100644 --- a/config.yml +++ b/config.yml @@ -1,22 +1,27 @@ -appname: "BlogAlba" +appname: "App::BlogAlba" +layout: "main" charset: "UTF-8" tz: "Europe/London" locale: "en_GB" -logger: "console" -log: "debug" +template: "template_toolkit" +engines: + template: + template_toolkit: + encoding: 'utf8' + start_tag: '[%' + end_tag: '%]' -# Uncomment for debugging -#show_errors: 1 -#Blog configuration -url: https://maff.scot/ +#Site configuration + +#url: https://maff.scot/ name: colourful words and phrases tagline: techy tangents and general life chatter from a tired sysadmin. author: Maff about: A dorky dude who spends too much time with perl. keywords: "sysadmin,unix,bsd,freebsd,linux,software,web,developer,perl,bash,shell,gentoo,maff,matthew,connelly,dundee,scotland,furry,blog" -posturlprepend: wrote/ +blog_prepend: wrote conf: indexable: 1 per_page: 6 diff --git a/environments/dev.yml b/environments/dev.yml new file mode 100644 index 0000000..84c6e60 --- /dev/null +++ b/environments/dev.yml @@ -0,0 +1,5 @@ +logger: "console" +log: "core" +warnings: 1 +show_errors: 1 +startup_info: 1 diff --git a/environments/prod.yml b/environments/prod.yml new file mode 100644 index 0000000..a63a0e1 --- /dev/null +++ b/environments/prod.yml @@ -0,0 +1,5 @@ +log: "warning" +logger: "file" +warnings: 0 +show_errors: 0 +no_server_tokens: 1 \ No newline at end of file diff --git a/layout/base.html b/layout/base.html deleted file mode 100644 index 44c9704..0000000 --- a/layout/base.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/lib/App/BlogAlba.pm b/lib/App/BlogAlba.pm index 82716ea..14384b1 100644 --- a/lib/App/BlogAlba.pm +++ b/lib/App/BlogAlba.pm @@ -3,86 +3,20 @@ package App::BlogAlba; use strict; use warnings; -use Cwd; -# TODO: maybe swap this out for templating stuff through dancer, would be cleaner. -use HTML::Template; -use Text::Markdown::Hoedown; +use App::BlogAlba::Article; +use Data::Paginated; -use POSIX qw/strftime/; -use Date::Parse qw/str2time/; #Required for converting the date field in posts to something strftime can work with use Time::HiRes qw/gettimeofday tv_interval/; -use XML::RSS; -use Unicode::Normalize; -use YAML; #Required for loading post-specific information from posts + +use Sys::Hostname; +my $HOST = hostname; $HOST =~ s/\..*$//; use Dancer2; +use Dancer2::Plugin::Feed; -my $HOST = `hostname -s`; chomp $HOST; +#Sanitise our base URL +config->{url} =~ /\/$/ or config->{url} .= '/'; -my $basedir=$ENV{BASE}."/".$ENV{APP} || cwd(); -config->{url} .= '/' unless config->{url} =~ /\/$/; - -my ($page,@posts,@pages,%defparams); -my $nposts=0;my $npages=1;my $lastcache=0; - -sub readpost { - my $file = shift;my $psh = shift || 1; - my %post; - my $postb = ""; my $postmm = ""; - open POST, $file or warn "Couldn't open $file!" and return 0; - my $status = 0; - while () { - $postb .= $_ if $status==2; - /^-{3,}$/ and not $status==2 and $status = $status==1? 2 : 1; - $postmm .= $_ if $status==1; - } - close POST; undef $status; - %post = %{YAML::Load($postmm)}; undef $postmm; - $post{filename} = $1 if $file =~ /(?:^|\/)([a-zA-Z0-9\-]*)\.md$/; - $post{body} = markdown( - $postb, - extensions => HOEDOWN_EXT_TABLES - | HOEDOWN_EXT_FENCED_CODE - | HOEDOWN_EXT_FOOTNOTES - | HOEDOWN_EXT_AUTOLINK - | HOEDOWN_EXT_STRIKETHROUGH - | HOEDOWN_EXT_UNDERLINE - | HOEDOWN_EXT_HIGHLIGHT - | HOEDOWN_EXT_SUPERSCRIPT - | HOEDOWN_EXT_NO_INTRA_EMPHASIS); - $post{mdsource} = $postb; - undef $postb; - if (defined $post{date}) { - $post{slug} = slugify($post{title}) unless $post{slug}; #we allow custom slugs to be defined - $post{hastags} = 1 unless not defined $post{tags}; - $post{excerpt} = $1 if $post{body} =~ /(

.*?<\/p>)/s; - $post{time} = str2time($post{date}); - $post{fancy} = timefmt($post{time},'fancydate'); - $post{datetime} = timefmt($post{date},'datetime'); - $post{permaurl} = config->{url}.config->{posturlprepend}.timefmt($post{time},'permalink').$post{slug}; - } - push @posts,{%post} if $psh==1; push @pages,{%post} if $psh==2;return %post; -} -sub slugify { - my $t = shift; - $t = lc NFKD($t); #Unicode::Normalize - $t =~ tr/\000-\177//cd; #Strip non-ascii - $t =~ s/[^\w\s-]//g; #Strip non-words - chomp $t; - $t =~ s/[-\s]+/-/g; #Prevent multiple hyphens or any spaces - return $t; -} -sub timefmt { - my ($epoch,$context)=@_; - $epoch=str2time $epoch if $epoch !~ /^[0-9]{10}$/; - my $dsuffix = 'th'; $dsuffix = 'st' if strftime("%d",localtime $epoch) =~ /1$/; $dsuffix = 'nd' if strftime("%d",localtime $epoch) =~ /2$/; - return strftime "%A, %e$dsuffix %b. %Y", localtime $epoch if $context eq 'fancydate'; - return strftime "%Y-%m-%dT%H:%M%z",localtime $epoch if $context eq 'datetime'; - return strftime "%Y-%m",localtime $epoch if $context eq 'writepost'; - return strftime "%Y/%m/",localtime $epoch if $context eq 'permalink'; - return strftime $context, localtime $epoch if $context; - return strftime config->{conf}->{date_format},localtime $epoch; -} sub pagination_calc { my $rem=$nposts % config->{conf}->{per_page}; $npages=($nposts-$rem)/config->{conf}->{per_page}; @@ -99,10 +33,6 @@ sub paginate { $page->param(PAGINATED => 1, prevlink => ($pagenum>1? 1 : 0), prevpage => $pagenum-1, nextlink => ($pagenum<$npages? 1 : 0), nextpage => $pagenum+1); return get_index @posts[$offset..(($offset+config->{conf}->{per_page})>$#posts? $#posts : ($offset+(config->{conf}->{per_page}-1)))]; } -sub page_init { - $page = HTML::Template->new(filename => "$basedir/layout/base.html",die_on_bad_params => 0,utf8 => 1,global_vars => 1); - $page->param(%defparams); -} sub get_post { my ($y,$m,$slug) = @_; for my $r (@posts) { @@ -123,31 +53,6 @@ sub get_page { } return undef; } -sub generate_feed { - return unless config->{conf}->{rss_publish}; - my $feed = new XML::RSS(version => '2.0'); - $feed->channel ( - title => config->{name}, - link => config->{url}, - description => config->{tagline}, - dc => { - creator => config->{author}, - language => config->{locale}, - }, - syn => { - updatePeriod => "daily", - updateFrequency => "1", - updateBase => "1970-01-01T00:00+00:00", - }, - ); - $feed->add_item ( - title => $_->{title}, - link => $_->{permaurl}, - description => (config->{conf}->{rss_excerpt}? $_->{excerpt} : $_->{body}), - dc => { creator => config->{author}, }, - ) for @posts[0 .. ($#posts > (config->{conf}->{recent_posts}-1)? (config->{conf}->{recent_posts}-1) : $#posts)]; - $feed->save("$basedir/public/feed-rss2.xml"); -} sub do_cache { return if $lastcache > (time - 3600); $lastcache = time;my $st=[gettimeofday]; @@ -181,37 +86,69 @@ sub do_cache { pagination_calc; } +sub GetPost { + my $params = shift or return undef; + return undef unless + $params->{year} =~ /^[0-9]{4}$/ and + $params->{month} =~ /^(0[1-9]|1[0-2])$/ and + $params->{slug}; + + for my $article (@articles) { + next unless + $article->{slug} eq lc $params->{slug} and + $article->{yyyymm} eq $params->{year}.$params->{month}; + return $article; + } + return undef; +} + hook 'before' => sub { do_cache; page_init; }; +#Indexes get '/' => sub { return get_index @posts if $npages==1; return paginate 1; }; -get '/page/:id' => sub { +get '/page/:num' => sub { pass unless params->{id} =~ /^[0-9]+$/ and params->{id} <= $npages; return redirect '/' unless $npages > 1 and params->{id} > 1; return paginate params->{id}; }; -get '/wrote/:yyyy/:mm/:slug' => sub { - pass unless params->{yyyy} =~ /^[0-9]{4}$/ and params->{mm} =~ /^(?:0[1-9]|1[0-2])$/ and params->{slug} =~ /^[a-z0-9\-]+(?:\.md)?$/i; - if (params->{slug} =~ s/\.md$//) { $page->param(SOURCEVIEW => 1); header('Content-Type' => 'text/plain'); } - $page->param(ISPOST => 1); - get_post params->{yyyy}, params->{mm}, params->{slug} or pass; - return $page->output; -}; -get '/:extpage' => sub { + +#Published articles +get '/:page' => sub { pass unless params->{extpage} =~ /^[a-z0-9\-]+(?:\.md)?$/i; if (params->{extpage} =~ s/\.md$//) { $page->param(SOURCEVIEW => 1); header('Content-Type' => 'text/plain'); } $page->param(ISPOST => 0); get_page params->{extpage} or pass; return $page->output; }; +get '/wrote/:yyyy/:mm/:slug' => sub { + my $article = GetPost scalar params 'route'; + pass unless $article; + content_tyle 'text/plain' and return $article->{raw} + if params->{slug} =~ /\.md$/; + + return template 'post', { page => $article }; +}; + +#Feeds +get '/feed/:type' => sub { + pass unless params->{type} =~ /^(rss|atom)$/i; + create_feed + format => lc params->{type}, + title => config->{blogtitle}, + link => request->base, + entries => \@articles; +} +get qr{/feed-(atom|rss2).xml} => sub { redirect '/feed/'.splat; } + # 404 any qr/.*/ => sub { - return redirect '/' if request->path =~ /index(?:\.(?:html?|pl)?)?$/; + redirect '/' if request->path =~ /index\.(html?|pl)$/; return send_error('The page you seek cannot be found.', 404); }; diff --git a/lib/App/BlogAlba/Article.pm b/lib/App/BlogAlba/Article.pm new file mode 100644 index 0000000..e69de29 diff --git a/layout/foot.inc b/views/layouts/foot.inc similarity index 100% rename from layout/foot.inc rename to views/layouts/foot.inc diff --git a/layout/head.inc b/views/layouts/head.inc similarity index 100% rename from layout/head.inc rename to views/layouts/head.inc diff --git a/views/layouts/main.tt b/views/layouts/main.tt new file mode 100644 index 0000000..9b12bdc --- /dev/null +++ b/views/layouts/main.tt @@ -0,0 +1,98 @@ + + + + + + " /> + " /> + " /> + " /> + " /> + " /> + <TMPL_VAR NAME="pagetitle"> + + + + + (RSS 2.0)" href="/feed-rss2.xml" /> + + + + + + +

+ +
+
+
+
+

" title=""> +

+
+
+
+
+
+
+
+ +
+ + + + +
+
+ + + + + + + + + \ No newline at end of file diff --git a/layout/post.inc b/views/layouts/post.inc similarity index 100% rename from layout/post.inc rename to views/layouts/post.inc