+ my $del; # delimiter between date and time
+
+ if ( $ret->{rows}->[0]->[0] =~ m/(\d{4}-\d{2}-\d{2})(.)?(\d{2}:\d{2}:\d{2})?/ ) {
+
+ my ( $date,$time );
+ ( $date, $del, $time ) = ( $1,$2,$3 );
+
+ my $fmt = '%Y-%m-%d';
+ $fmt .= 'T' if $del;
+ $fmt .= '%H:%M:%S' if $time;
+
+ my $format_x = $time ? '%d %H:%M' : '%Y-%m-%d';
+ $gnuplot .= qq|
+
+set xdata time
+set timefmt "$fmt"
+
+set format x "$format_x"
+set xtics nomirror rotate by -90
+
+|;
+
+ } else {
+ warn "first column not timestamp";
+ }
+
+ my $plot = 'plot ';
+ my $with = $self->param('with') || 'dots';
+ foreach my $i ( 1 .. $#{ $ret->{rows}->[0] } ) {
+ $gnuplot .= $plot; $plot = ',';
+ $gnuplot .= qq| '-' using 1:2 with $with title "$c[$i]" |;
+ }
+ $gnuplot .= "\n";
+
+ foreach my $i ( 1 .. $#{ $ret->{rows}->[0] } ) {
+
+ foreach my $row ( @{ $ret->{rows} } ) {
+ my $date = $row->[0];
+ $date =~ s/\Q$del\E/T/g if $del;
+ $date =~ s/\.\d+//;
+ $gnuplot .= join(" ", $date, $row->[$i])."\n";
+ }
+ $gnuplot .= "e\n";
+ }
+
+ open(my $fd, '|-', 'gnuplot') || die "gnuplot: $!";
+ print $fd $gnuplot;
+ close($fd);
+
+ $gnuplot = '' unless $self->param('include_gnuplot');
+
+ $self->render('gnuplot', sql => $sql, img => "/gnuplot/$name", gnuplot => $gnuplot);
+};
+
+get '/_redis' => sub {
+ my $self = shift;
+
+ _render_jsonp( $self, Mojo::JSON->new->encode({ status => APKPM::Model->redis_status }) );
+};
+
+get '/user' => sub {
+ my $self = shift;
+
+ $self->render('user');
+};
+
+get '/psql/:command' => sub {
+ my $self = shift;
+ my $command = $self->param('command');
+ $command =~ s/^_/\\/ && warn "internal psql command $command";
+ $command = sprintf "psql -c '%s' apkpm", $command;
+ my $output = `$command`; # FIXME unsecure
+ $self->render_text( "\$ <b><tt>$command</tt></b>\n\n<pre>$output</pre>" );
+};
+
+# create pid file
+open(my $pid, '>', '/tmp/apkpm.web_ui.pid');
+print $pid "$$\n";
+close $pid;
+
+app->start;