From 8885cb614e364f1ad53c5548a94d340faf1e1011 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Fri, 9 Mar 2018 20:58:34 -0500 Subject: [PATCH] Sketch rudimentary web app --- .gitignore | 12 +++++ app.pl | 73 ++++++++++++++++++++++++++++++ assets/logo.png | Bin 0 -> 14485 bytes lib/RakudoOrg/Posts.pm | 43 ++++++++++++++++++ morbo | 3 ++ templates/feed.xml.ep | 35 ++++++++++++++ templates/home.html.ep | 12 +++++ templates/layouts/default.html.ep | 49 ++++++++++++++++++++ 8 files changed, 227 insertions(+) create mode 100644 .gitignore create mode 100644 app.pl create mode 100644 assets/logo.png create mode 100644 lib/RakudoOrg/Posts.pm create mode 100755 morbo create mode 100644 templates/feed.xml.ep create mode 100644 templates/home.html.ep create mode 100644 templates/layouts/default.html.ep diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ce15f91 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +*~ +.sass-cache +.precomp +*.map +assets/sass/main.css +hypnotoad.pid +assets/assetpack.db +assets/cache/ +pull-password +.precomp +/test.p6 +/out.html \ No newline at end of file diff --git a/app.pl b/app.pl new file mode 100644 index 0000000..f9f38cb --- /dev/null +++ b/app.pl @@ -0,0 +1,73 @@ +#!/usr/bin/env perl + +use lib qw; +use Mojolicious::Lite; +use Mojo::UserAgent; +use Mojo::File qw/path/; +use Mojo::Util qw/trim/; +use Time::Moment; +use RakudoOrg::Posts; + +my $posts = RakudoOrg::Posts->new; +my $ua = Mojo::UserAgent->new; + +app->config({ hypnotoad => { listen => ['http://*:4242'], proxy => 1 } }); + +# plugin 'AssetPack' => { pipes => [qw/Sass JavaScript Combine/] }; +# app->asset->process('app.css' => 'sass/main.scss'); +# app->asset->process('app.js' => qw{ +# js/ie10-viewport-bug-workaround.js +# js/codemirror/codemirror.min.js +# js/codemirror/perl6-mode.js +# js/main.js +# }); + +### Routes +get '/' => sub { + my $c = shift; + $c->stash(posts => $posts->all); +} => 'home'; + +get '/post/#post' => sub { + my $c = shift; + my ($meta, $markdown, $html) = $posts->load($c->param('post')); + $html or return $c->reply->not_found; + + $c->stash(%$meta, post => $html, title => $meta->{title}); +} => 'post'; + +any $_ => sub { + my $c = shift; + my $posts = [ map +{ %$_ }, @{ $posts->all } ]; + $_->{date} = blog_date_to_feed_date($_->{date}) for @$posts; + + my $blog_last_updated_date = $posts->[0]{date}; + $c->stash( + posts => $posts, + last_update => $blog_last_updated_date, + template => 'feed', + format => 'xml', + ); +}, ($_ eq '/feed' ? 'feed' : ()) + for '/feed', '/feed/', '/feed/index', '/atom', '/atom/', '/atom/index'; + +get '/pull/*password' => sub { + my $c = shift; + + return $c->reply->not_found + unless $c->param('password') eq trim path('pull-password')->slurp; + + $c->render( + text => "Pulled!\n" . `git pull`, + format => 'txt', + ); +}; + +app->start; + +sub blog_date_to_feed_date { + my $date = shift; + return Time::Moment->from_string("${date}T00:00:00Z") + ->strftime("%a, %d %b %Y %H:%M:%S %z"); +} + diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ed738d2e7225469ce20d043c6482b58fc6e2c215 GIT binary patch literal 14485 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 + next if $meta->{draft}; + push @return, { + date => $meta->{date}, + title => $meta->{title}, + desc => $meta->{desc}, + post => (substr $_, length 'post/'), + }; + } + return [ sort { $b->{date} cmp $a->{date} } @return ]; +} + +sub load { + my ($self, $post) = @_; + my $post_file = "post/$post.md"; + return unless -f $post_file and -r _; + my ($meta, $content) = process(decode 'UTF-8', path($post_file)->slurp); + return $meta, markdown $content; +} + +sub process { + my $post = shift; + my %meta; + $meta{$1} = $2 while $post =~ s/^%%\s*(\w+)\s*:\s*([^\n]+)\n//; + $post =~ s/^```$//gm; + return \%meta, $post; +} + +1; diff --git a/morbo b/morbo new file mode 100755 index 0000000..9e7921f --- /dev/null +++ b/morbo @@ -0,0 +1,3 @@ +#!/bin/sh +morbo -l 'http://*:4242' -w assets -w templates -w lib app.pl + diff --git a/templates/feed.xml.ep b/templates/feed.xml.ep new file mode 100644 index 0000000..48eccf5 --- /dev/null +++ b/templates/feed.xml.ep @@ -0,0 +1,35 @@ + + + Rakudo Perl 6 Compiler + + <%= url_for('home')->to_abs %> + Rakudo Perl 6 Compiler + <%= $last_update %> + en + + <%= url_for('/assets/logo.png')->to_abs %> + Perl 6 Compiler + <%= url_for('home')->to_abs %> + + + % for my $post (@$posts) { + + <%= $post->{title} %> + <%= url_for(post => $post->{post})->to_abs %> + <%= $post->{date} %> + <%= + url_for(post => $post->{post})->to_abs %> + {desc} %>]]> + + % } + + diff --git a/templates/home.html.ep b/templates/home.html.ep new file mode 100644 index 0000000..a6b7823 --- /dev/null +++ b/templates/home.html.ep @@ -0,0 +1,12 @@ +% layout 'default'; +% title 'Rakudo Perl 6 Compiler'; + +% for my $p ( @$posts ) { +
+

<%= $p->{title} %>

+ +

<%= $p->{desc} =%>

+
+% } + diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep new file mode 100644 index 0000000..0c48cf7 --- /dev/null +++ b/templates/layouts/default.html.ep @@ -0,0 +1,49 @@ + + + + + + + + + <%= $title %> + - Rakudo Compiler for Perl 6 Programming Language + + +
+
+ +
+
+ +
+
+
+

<%= $title + // 'Rakudo Compiler for Perl 6 Programming Language' %>

+
+
+
+ <%= content %> +
+
+
+
+ + + + +