]> git.imager.perl.org - bse.git/blame - site/cgi-bin/modules/BSE/UI.pm
more metadata generalization and modification
[bse.git] / site / cgi-bin / modules / BSE / UI.pm
CommitLineData
d980b7fa
TC
1package BSE::UI;
2use strict;
3use BSE::Cfg;
4
e5bceed5
TC
5our $VERSION = "1.004";
6
bef1f08f
TC
7my $time = sub { time };
8
9if (eval { require Time::HiRes; 1 }) {
10 $time = \&Time::HiRes::time;
11}
12
d980b7fa
TC
13sub confess;
14
15sub run {
16 my ($class, $ui_class, %opts) = @_;
17
18 local $SIG{__DIE__} = sub { confess @_ };
19 (my $file = $ui_class . ".pm") =~ s(::)(/)g;
20
21 my $cfg = $opts{cfg} || BSE::Cfg->new;
22
bef1f08f
TC
23 my $start = $time->();
24
d980b7fa
TC
25 my $req;
26 eval {
27 require BSE::Request;
28 $req = BSE::Request->new
29 (
30 cfg => $cfg,
31 %{$opts{req_params} || {}},
32 );
33 1;
34 } or fail("Loading request class: $@", "req", $cfg);
35
36 eval {
37 require $file;
38 1;
39 } or fail("Loading module $file: $@", "load", $cfg);
40
41 eval {
42 my $ui = $ui_class->new;
43 my $result = $ui->dispatch($req);
44
45 if (!$result && !$opts{silent_exit}) {
46 confess "No content returned by dispatch()";
47 }
48
49 my $cfg = $req->cfg;
50 undef $req; # release any locks
51 if ($result) {
bef1f08f
TC
52 $cfg->entry("basic", "times", 0)
53 and _show_times($start, $result);
d980b7fa
TC
54 require BSE::Template;
55 BSE::Template->output_resultc($cfg, $result);
56 }
57
58 1;
59 } or fail("Running dispatcher: $@", "run", $cfg);
60}
61
62sub run_fcgi {
63 my ($class, $ui_class, %opts) = @_;
64
65 local $SIG{__DIE__} = sub { confess @_ };
66 (my $file = $ui_class . ".pm") =~ s(::)(/)g;
67
68 my $cfg = $opts{cfg} || BSE::Cfg->new;
69
70 eval {
71 require $file;
72 1;
73 } or fail("Loading module $file: $@", "load", $cfg);
74
29050477 75 require CGI::Fast;
d980b7fa 76 while (my $cgi = CGI::Fast->new) {
bef1f08f 77 my $start = $time->();
d980b7fa
TC
78 my $req;
79 eval {
80 require BSE::Request;
81 $req = BSE::Request->new
82 (
83 cfg => $cfg,
84 cgi => $cgi,
8329ce1b 85 fastcgi => scalar $FCGI::global_request->IsFastCGI,
d980b7fa
TC
86 %{$opts{req_params} || {}},
87 );
88 1;
89 } or fail("Loading request class: $@", "req", $cfg);
90
91 eval {
92 my $ui = $ui_class->new;
93 my $result = $ui->dispatch($req);
94
95 if (!$result && !$opts{silent_exit}) {
96 confess "No content returned by dispatch()";
97 }
98
99 my $cfg = $req->cfg;
100 undef $req; # release any locks
101 if ($result) {
bef1f08f
TC
102 $cfg->entry("basic", "times", 0)
103 and _show_times($start, $result);
104
d980b7fa
TC
105 require BSE::Template;
106 BSE::Template->output_resultc($cfg, $result);
107 }
108
109 1;
110 } or fail("Running dispatcher: $@", "run", $cfg);
111 }
112}
113
114sub confess {
115 require Carp;
116
117 goto &Carp::confess;
118}
119
bef1f08f
TC
120sub _show_times {
121 my ($start, $result) = @_;
122
e5bceed5
TC
123 if ($result->{type}
124 && $result->{type} =~ m(^text/html)
125 && $result->{content}) {
bef1f08f
TC
126 my %mem = qw(VmPeak unknown VmSize unknown);
127
128 $mem{time} = sprintf("%.1f", 1000 * ($time->() - $start));
129 if (open my $meminfo, "<", "/proc/$$/status") {
130 while (my $line = <$meminfo>) {
131 chomp $line;
132 $line =~ /(\w+):\s+(.*)/ and $mem{$1} = $2;
133 }
134 close $meminfo;
135 }
136 $result->{content} =~ s/<!--pagegen:(\w+)-->/$mem{$1} || "unknown"/ge;
137 if ($result->{headers}) {
138 my $length = length $result->{content};
139 for my $header (@{$result->{headers}}) {
140 $header =~ s/(Content-Length: ).*/$1$length/
141 and last;
142 }
143 }
144 }
145}
146
d980b7fa
TC
147sub fail {
148 my ($msg, $func, $cfg) = @_;
149
150 print STDERR "run failure: $msg\n";
151 eval {
152 # try to log it
153 require BSE::TB::AuditLog;
154 my ($script) = $ENV{SCRIPT_NAME} =~ /(\w+)\.\w+$/;
155 $script ||= "unknown";
156 BSE::TB::AuditLog->log
157 (
158 component => "$script:run",
159 function => $func,
160 level => "crit",
161 actor => "S",
162 msg => $msg,
163 dump => <<DUMP,
164Error: $msg
165
166\@INC: @INC
167DUMP
168 );
169 1;
170 } or print STDERR "Could not log: $@\n";
171
172 print <<EOS;
173Status: 500
174Content-Type: text/plain
175
176There was an error producing your content.
177EOS
178 exit 1;
179}
180
1811;