package XXV::OUTPUT::Wml;
use strict;
use vars qw($AUTOLOAD);
use Tools;
use File::Path;
use Pod::Html;
# This module method must exist for XXV
# ------------------
sub module {
# ------------------
my $self = shift || return error('No object defined!');
my $args = {
Name => 'Wml',
Prereq => {
'Template' => 'Front-end module to the Template Toolkit',
},
Description => gettext('This receives and sends WAP messages.')
};
return $args;
}
# ------------------
sub AUTOLOAD {
# ------------------
my $self = shift || return error('No object defined!');
my $data = shift || {};
my $params = shift || 0;
my $name = (split('::', $AUTOLOAD))[-1];
return if($name eq 'DESTROY');
my $output = $self->parseTemplate($name, $data, $params);
$self->out( $output );
$self->{call} = '';
}
# ------------------
sub new {
# ------------------
my($class, %attr) = @_;
my $self = {};
bless($self, $class);
# who am I
$self->{MOD} = $self->module;
# Try to use the Requirments
map {
eval "use $_";
if($@) {
my $m = (split(/ /, $_))[0];
return panic("\nCouldn't load perl module: $m\nPlease install this module on your system:\nperl -MCPAN -e 'install $m'");
}
} keys %{$self->{MOD}->{Prereq}};
$self->{handle} = $attr{'-handle'}
|| return error('No handle defined!');
$self->{paths} = $attr{'-paths'}
|| return error('No Paths defined!');
$self->{dbh} = $attr{'-dbh'}
|| return error('No DBH defined!');
$self->{wmldir} = $attr{'-wmldir'}
|| return error('No wmldir given!');
$self->{cgi} = $attr{'-cgi'}
|| return error('No cgi object given!');
$self->{mime} = $attr{'-mime'}
|| return error('No mime hash given!');
$self->{browser} = $attr{'-browser'}
|| return error('No browser given!');
$self->{charset} = $attr{'-charset'}
|| 'ISO-8859-1';
# $self->{start} = $attr{'-start'}
# || return error('No StartPage given!');
$self->{TYP} = 'WML';
eval "use Template::Stash::XS";
$Template::Config::STASH = 'Template::Stash::XS' unless($@);
# create Template object
$self->{tt} = Template->new(
START_TAG => '\<\?\%', # Tagstyle
END_TAG => '\%\?\>', # Tagstyle
INCLUDE_PATH => $self->{wmldir}, # or list ref
INTERPOLATE => 1, # expand "$var" in plain text
PRE_CHOMP => 1, # cleanup whitespace
EVAL_PERL => 1, # evaluate Perl code blocks
);
return $self;
}
# ------------------
sub parseTemplate {
# ------------------
my $self = shift || return error('No object defined!');
my $name = shift || return error('No name defined!');
my $data = shift || return error('No data defined!');
my $params = shift || {};
my $u = main::getModule('USER');
# you can use two templates, first is a user defined template
# and second the standard template
# i.e. call the htmlhelp command the htmlhelp.tmpl
# SpecialTemplate: ./wmlRoot/usage.tmpl
# StandardTemplate: ./wmlRoot/widgets/menu.tmpl
my $widget_first = sprintf('%s.tmpl', (exists $self->{call}) ? $self->{call} : 'nothing');
my $widget_second = sprintf('widgets/%s.tmpl', $name);
my $widget = (-e sprintf('%s/%s', $self->{wmldir}, $widget_first) ? $widget_first : $widget_second);
my $output;
my $vars = {
cgi => $self->{cgi},
call => $name,
data => $data,
type => ref $data,
info => $self->browser,
param => $params,
pid => $$,
debug => 1,
user => $self->{USER}->{Name},
charset => $self->{charset},
allow => sub{
my($cmdobj, $cmdname, $se, $err) = $u->checkCommand($self, $_[0],"1");
return 1 if($cmdobj);
},
basedir => $self->{wmldir},
entities => sub{ return entities($_[0]) },
# translate string, usage : gettext(foo,truncate) or gettext(foo)
# value for truncate are optional
gettext => sub{
my $t = gettext($_[0]);
$t = substr($t,0,$_[1]) . "..."
if(defined $_[1] && length($t)>$_[1]);
return entities($t);
},
version => sub{ return main::getVersion },
loadfile => sub{ return load_file(@_, 'binary') },
writefile => sub{
my $filename = shift || return error('No Filename to write');
my $data = shift || return error('Nothing data to write');
my $dir = $u->userTmp($self->{USER}->{Name});
# absolut Path to file
my $file = sprintf('%s/%s', $dir, $filename);
# absolut Path to file
if(save_file($file, $data, 'binary')) {
# return the relative Path
my ($relpath) = $file =~ '/(.+?/.+?)$';
return sprintf('tempimages/%s', $filename);
}
},
};
$self->{tt}->process($widget, $vars, \$output)
or return error($self->{tt}->error());
return $output;
}
# ------------------
sub out {
# ------------------
my $self = shift || return error('No object defined!');
my $text = shift || 'no Text for Output';
my $type = shift || 'text/vnd.wap.wml';
my %args = @_;
unless(defined $self->{header}) {
# HTTP Header
my $header = $self->header($type, \%args);
$self->{sendbytes}+= length($header);
$self->{handle}->print($header );
}
$self->{sendbytes}+= length($text)+ 2;
$self->{handle}->print( $text,"\r\n" );
}
# ------------------
sub header {
# ------------------
my $self = shift || return error('No object defined!');
my $typ = shift || return error ('No Type!' );
my $arg = shift || {};
if($self->{USER} && $self->{USER}->{sid}) {
$arg->{'cookie'} = $self->{cgi}->cookie({
"name" => "sid",
"value" => $self->{USER}->{sid},
"expires" => "+4h"});
}
$self->{header} = 200;
return $self->{cgi}->header(
-type => $typ,
-status => "200 OK",
-expires => ($typ =~ 'text/vnd.wap.wml' || (defined $self->{nocache} && $self->{nocache})) ? "now" : "+12h",
-charset => $self->{charset},
%{$arg},
);
}
# ------------------
sub statusmsg {
# ------------------
my $self = shift || return error('No object defined!');
my $state = shift || return error('No state defined!');
my $msg = shift;
my $title = shift;
my $typ = shift || 'text/vnd.wap.wml';
unless(defined $self->{header}) {
$self->{nopack} = 1;
my $s = {
200 => '200 OK',
204 => '204 No Response',
301 => '301 Moved Permanently',
302 => '302 Found',
303 => '303 See Other',
304 => '304 Not Modified',
307 => '307 Temporary Redirect',
400 => '400 Bad Request',
401 => '401 Unauthorized',
403 => '403 Forbidden',
404 => '404 Not Found',
405 => '405 Not Allowed',
408 => '408 Request Timed Out',
500 => '500 Internal Server Error',
503 => '503 Service Unavailable',
504 => '504 Gateway Timed Out',
};
my $status = $s->{200};
$status = $s->{$state}
if(exists $s->{$state});
my $arg = {};
$arg->{'Location'} = $msg
if($state == 301);
$arg->{'WWW-Authenticate'} = "Basic realm=\"xxvd\""
if($state == 401);
$arg->{'expires'} = (($state != 304) || (defined $self->{nocache} && $self->{nocache})) ? "now" : "+7d";
$self->{header} = $state;
my $data = $self->{cgi}->header(
-type => $typ,
-status => $status,
-charset => $self->{charset},
%{$arg},
);
$self->out($data);
}
if($msg && $title) {
$self->start(undef,{ title => $title });
$self->err($msg);
$self->footer();
}
}
# ------------------
# Send HTTP Status 401 (Authorization Required)
sub login {
# ------------------
my $self = shift || return error('No object defined!');
my $msg = shift || '';
$self->statusmsg(401,$msg,gettext("Authorization required"));
}
# ------------------
# Send HTTP Status 403 (Access Forbidden)
sub status403 {
# ------------------
my $self = shift || return error('No object defined!');
my $msg = shift || '';
$self->statusmsg(403,$msg,gettext("Forbidden"));
}
# ------------------
# Send HTTP Status 404 (File not found)
sub status404 {
# ------------------
my $self = shift || return error('No object defined!');
my $file = shift || return error('No file defined!');
my $why = shift || "";
$file =~ s/$self->{wmldir}\///g; # Don't post wml root, avoid spy out
$self->statusmsg(404,sprintf(gettext("Couldn't open file '%s' : %s!"),$file,$why),
gettext("Not found"));
}
# ------------------
sub question {
# ------------------
my $self = shift || return error('No object defined!');
my $titel = shift || 'undef';
my $questions = shift || return error('No data defined!');
my $erg = shift || 0;
my $q = $self->{cgi};
my $quest;
# Check Data
if(ref $erg eq 'HASH' and ref $questions eq 'ARRAY' and exists $erg->{action}) {
my $error;
@$quest = @$questions;
while (my ($name, $data) = splice(@$quest, 0, 2)) {
# Required value ...
$error = $data->{req}
if($data->{req} and not $erg->{$name});
# Check Callback
if(exists $data->{check} and ref $data->{check} eq 'CODE' and not $error) {
($erg->{$name}, $error) = $data->{check}($erg->{$name}, $data);
}
# Check on directory
if($data->{typ} eq 'dir' and $data->{required} and not -d $erg->{$name}) {
($erg->{$name}, $error) = (undef, sprintf(gettext("Directory '%s' does not exist!"), $erg->{$name}));
}
# Check on file
if($data->{typ} eq 'file' and $data->{required} and not -e $erg->{$name}) {
($erg->{$name}, $error) = (undef, sprintf(gettext("File '%s' does not exist!"), $erg->{$name}));
}
if($error) {
$self->err(sprintf(gettext("Error '%s' (%s) : %s!"), $data->{msg}, $name, $error));
last;
}
}
unless($error) {
delete $erg->{action};
return $erg;
}
}
$self->formStart($titel);
if(ref $questions eq 'ARRAY') {
my $q = $self->{cgi};
@$quest = @$questions;
while (my ($name, $data) = splice(@$quest, 0, 2)) {
my $type = delete $data->{typ};
$data->{msg} =~ s/\n/
/sig if($data->{msg});
$data->{NAME} = '__'.$name;
$type ||= 'string';
$self->$type($data);
}
} else {
my $type = delete $questions->{typ};
$questions->{NAME} = '__'.$type;
$type ||= 'string';
$self->$type($questions);
}
$self->formEnd;
return undef;
}
# ------------------
sub image {
# ------------------
my $self = shift || return error('No object defined!');
my $file = shift || return error('No file defined!');
my $typ = shift || $self->{mime}->{lc((split('\.', $file))[-1])}
or return error("No Type in Mimehash or File: $file");
my $data = load_file($file, 'binary')
or return $self->status404($file,$!);
$self->out($data, $typ);
}
# ------------------
sub datei {
# ------------------
my $self = shift || return error('No object defined!');
my $file = shift || return error('No file defined!');
my $data = load_file($file)
or return $self->status404($file,$!);
$self->out($data, 'text/vnd.wap.wml');
}
# ------------------
sub pod {
# ------------------
my $self = shift || return error('No object defined!');
my $modname = shift || return error('No modul name defined!');
$modname = ucfirst($modname) if($modname eq 'GENERAL');
my $podfile = sprintf('%s/%s.pod', $self->{paths}->{PODPATH}, $modname);
my $tmpdir = main::getModule('USER')->userTmp($self->{USER}->{Name});
my $outfile = sprintf('%s/%s_%d.pod', $tmpdir, $modname, time);
pod2html(
"--cachedir=$tmpdir",
"--infile=$podfile",
"--outfile=$outfile",
);
return error('Problem to convert pod2html')
unless(-r $outfile);
my $html = load_file($outfile);
$html = $1 if($html =~ /\