Move display mangling to templates, add read API
[gruntmaster-page.git] / lib / Plack / App / Gruntmaster.pm
1 package Plack::App::Gruntmaster;
2
3 use 5.014000;
4 use strict;
5 use warnings;
6 use parent qw/Plack::Component/;
7 no if $] >= 5.017011, warnings => 'experimental::smartmatch';
8 our $VERSION = '5999.000_001';
9
10 use File::Slurp qw/read_file/;
11 use HTTP::Negotiate qw/choose/;
12 use Plack::Request;
13 use Gruntmaster::Page::Log;
14 use Gruntmaster::Page::Pb::Entry;
15 use Gruntmaster::Page::Generic;
16
17 my %handlers;
18
19 sub call {
20 my $env = $_[1];
21 my $r = Plack::Request->new($env);
22 my @handlers = @{ $handlers{$r->method} // [] };
23 for my $handler (@handlers) {
24 my ($re, $obj) = @$handler;
25 my @args;
26 next unless @args = $r->path =~ m/^$re$/a;
27 my $format = choose $obj->variants, $r->headers;
28 return $obj->generate($format, $env, map { $_ // '' } @args);
29 }
30
31 if ($r->method eq 'GET' || $r->method eq 'HEAD') {
32 my $article = $r->path eq '/' ? '/index' : $r->path;
33 $article = substr $article, 1;
34 $article =~ tr,/,_,;
35 my @variants = grep { !/\.title$/ } <a/$article.*>;
36 if (@variants) {
37 my $lang = choose [ map { [$_, 1, 'text/html', undef, undef, $_, undef] } map { /\.(.+)$/ } @variants ], $r->headers;
38 my $content = read_file "a/$article.$lang";
39 my $title = read_file "a/$article.$lang.title";
40 my $html = Gruntmaster::Page::Base::header($lang, $title) . $content . Gruntmaster::Page::Base::footer($lang);
41 return [200, ['Content-Type' => 'text/html', 'Content-Language' => $lang, 'Vary' => 'Accept-Language', 'X-Forever' => 1, 'Cache-Control' => 'max-age=300'], [$html] ]
42 }
43 }
44
45 [404, ['Content-Type' => 'text/plain'], ['Not found']]
46 }
47
48 sub get {
49 my ($re, $obj) = @_;
50 eval "require Gruntmaster::Page::$obj" or die $@;
51 push @{$handlers{GET }}, [ $re, "Gruntmaster::Page::$obj" ]
52 }
53
54 sub post {
55 my ($re, $obj) = @_;
56 eval "require Gruntmaster::Page::$obj" or die $@;
57 push @{$handlers{POST}}, [ $re, "Gruntmaster::Page::$obj" ]
58 }
59
60 BEGIN{
61 my $word = qr,(\w+),a;
62 my $ct = qr,(?:\/ct/$word)?,a;
63
64 sub generic {
65 my ($thing, $ct, $fs) = @_;
66 $ct //= '', $fs //= '';
67 my $pkg = ucfirst $thing;
68 get qr,$ct/$thing/, => $pkg;
69 get qr,$ct/$thing/$word$fs, => "${pkg}::Entry";
70
71 get qr,$ct/$thing/read, => "${pkg}::Read";
72 # post qr,$ct/$thing/$word/create, => "${pkg}::Entry::Create";
73 get qr,$ct/$thing/$word/read, => "${pkg}::Entry::Read";
74 # post qr,$ct/$thing/$word/update, => "${pkg}::Entry::Update";
75 # post qr,$ct/$thing/$word/delete, => "${pkg}::Entry::Delete";
76 }
77
78 get qr,/css/$word\.css, => 'CSS';
79 get qr,/js\.js, => 'JS';
80
81 generic 'us';
82 generic ct => '', '/';
83 generic pb => $ct;
84 #generic log => $ct;
85
86 get qr,$ct/log/(\d+)?, => 'Log';
87 get qr,$ct/log/st, => 'St';
88 get qr,$ct/log/job/$word, => 'Log::Entry';
89 get qr,$ct/log/job/$word/read, => 'Log::Entry::Read';
90 get qr,$ct/log/src/$word\.$word, => 'Src';
91 post qr,$ct/pb/$word/submit, => 'Submit';
92
93 post qr,/action/register, => 'Register';
94 post qr,/action/passwd, => 'Passwd';
95 }
96
97 1;
98 __END__
This page took 0.029307 seconds and 4 git commands to generate.