pcms/index.pl
bluesaxman d82ededc4f Bug fix
Actual fix for undefined passed to menu
2019-09-05 09:21:18 -06:00

273 lines
7.2 KiB
Perl
Executable File

#!/usr/bin/perl -w
use strict;
use warnings;
# Where are my things?
my $img_dir = "/img/"; #must be based on web root
my $css_dir = "/css/"; #must be based on web root
my $js_dir = "/js/"; #must be based on web root
my $pages_dir = "./pages/";
my $scripts_dir = "./scripts/";
my $data_dir = "./dynamic/";
# What are my configurations?
my $system_base = `pwd`; #where am I on the system
chomp($system_base);
my $site_base = "/";
my $site_name = "Murkfall Mountain";
my $site_symbol = "&#9968";
my $site500 = "There was an oopsy";
my $site404 = "There is nothing here...";
# What files should we include in our header
my @header_includes = (
{"file" => $img_dir."favicon.gif", "type" => "image/gif", "rel" => "icon", "tag" => "link"},
{"file" => $css_dir."css.css", "type" => "text/css", "rel" => "stylesheet", "tag" => "link"},
);
my @footer_includes = (
{"file" => $js_dir."bluecore.js", "type" => "text/javascript", "rel" => "", "tag" => "script"},
{"file" => $js_dir."base.js", "type" => "text/javascript", "rel" => "", "tag" => "script"}
);
# Make some tools
sub clean_input {
my $input = shift;
# I think I need to address what this line is actually doing.
if ($input =~ m!%2F!) { print "Location: /hax\r\n\r\n"; exit; }
$input =~ s!%(..)!chr hex $1!ge;
$input =~ s!\+! !g;
return $input;
}
sub get_info {
my $clientIP = ($ENV{"REMOTE_ADDR"} or "0.0.0.0");
my $proto = ($ENV{"REQUEST_SCHEME"} or "http");
my $query = (split(/\?/,($ENV{"QUERY_STRING"} or "")))[0];
my $referrer = ($ENV{"HTTP_REFERER"} or "");
my $PageURL = ($ENV{"REQUEST_URI"} or "home");
#We might need to look at more of these.
return ($proto,$clientIP,$query,$referrer,$PageURL);
}
our @request = get_info();
sub http_status {
my ($status,$content,$target) = @_;
my $header = "";
$header .= "status: ".$status."\r\n";
$header .= "Location: ".$target."\r\n" if $target;
$header .= "Content-Type: ".$content."\r\n" if $content;
$header .= "\r\n";
return $header;
}
sub html_tag {
my $tag = shift;
my $content = shift;
my @attrib_array = @_;
my $string = "\n<".$tag;
my $end = " />";
if (@attrib_array) {
foreach(@attrib_array) {
unless (defined($_)) { next; }
$string .= ' '.$_->{attribute}.'="'.$_->{value}.'"';
}
}
if ($content) {
$string =~ s/^\s//g;
$string .= ">".$content;
$end = "</".$tag.">";
}
return $string.$end;
}
sub soft_die {
print http_status(500,"text/html; charset=utf-8");
print "<!DOCTYPE html>\n";
print html_tag("html",html_tag("body",$site500.shift));
exit;
}
sub page404 {
print http_status(404,"text/html; charset=utf-8");
print "<!DOCTYPE html>\n";
$site_name .= " - 404";
print html_tag("html",
html_tag("head",header()).
html_tag("body",
render_logo($site_symbol).
page_template($site404)));
exit;
}
sub normalize_string {
return join(" ",(map { ucfirst($_) } split("_",shift)));
}
# lets build a website
sub include {
my @includes = @_;
my $buffer = "";
for (@includes) {
if (-e $system_base.$_->{"file"}) {
my $rel = $_->{"rel"} ne "" ? 1 : 0;
$buffer .= html_tag(
$_->{"tag"},
$_->{"tag"} eq "script" ? " " : undef,
$rel ? {attribute=>'rel', value=>$_->{"rel"}} : undef,
{attribute=>'type', value=>$_->{"type"}},
{attribute=>$rel?'href':'src', value=>$_->{"file"}});
}
}
return $buffer;
}
sub header {
my $header = "";
$header .= html_tag(
"meta",
undef,
{attribute=>'http-equiv', value=>'Content-Type'},
{attribute=>'content', value=>'text/html; charset=utf-8'});
my $page = (split("/",$request[4]))[-1];
$header .= html_tag('title',$site_name . $page ne "" ? " - ".$page : "");
$header .= include(@header_includes);
$header .= html_tag(
'meta',
undef,
{attribute=>'name', value=>"viewport"},
{attribute=>'content', value=>"user-scalable=no"});
return $header;
}
sub render_logo {
my $symbol = shift;
return html_tag(
'div',
html_tag(
'span',
$symbol,
{attribute=>'id',value=>"SiteSymbol"}).
html_tag(
'span',
$site_name,
{attribute=>'id',value=>'SiteName'}),
{attribute=>'id',value=>'logo'});
}
sub get_page {
my $pageURL = shift;
$pageURL =~ s/^$site_base//g;
$pageURL =~ s/%20/ /g;
my @URLvars = split(/\//,$pageURL);
my $page_name = $URLvars[0];
unless ($page_name) { $page_name = "home";}
if (-e $scripts_dir.$page_name.".pl") {
return qx($scripts_dir$page_name.pl @URLvars);
} else {
my $sub_page_name = $page_name;
if ($page_name =~ m/_dir$/) {
$sub_page_name .= "/".$URLvars[1];
$page_name =~ s/_dir$//g;
}
open(PAGE, "<", $pages_dir.$sub_page_name) or return page404($pageURL." we looked here:".$pages_dir.$sub_page_name);
my @content = <PAGE>;
close(PAGE);
return @content;
}
}
sub menu_item {
my $name = $_[0];
if ($_[0] =~ m/\//){$name = (split("/",$_[0]))[1]}
$name =~ s/_/ /g;
my $item_content = '<li><a href="'.$site_base.(map {lc} $_[0])[0].'"> ';
$item_content .= ucfirst $name;
$item_content .= ' </a></li>';
return $item_content;
}
sub render_menu {
my $id = shift(@_);
my $menu_content = '<input type="checkbox" id="'.$id.'-trigger" /><label for="'.$id.'-trigger">&#9776;</label>';
$menu_content .= '<ul id="'.$id.'">';
my @list = sort {$a cmp $b} @_;
foreach (@list) {
$menu_content .= menu_item($_) if(-e $pages_dir.$_);
}
$menu_content .= '</ul>';
$menu_content .= "\n";
return $menu_content;
}
sub menu {
my $filthy_page = (split("/",(shift or "")))[1];
my $current_page = $filthy_page ? $filthy_page : "";
$current_page =~ s/_dir$//g;
my %menus = ();
# Handle main menu
if (-e $data_dir."menucont") {
open(MENUFILE, "<", $data_dir."menucont") or return "Problem accessing menu file:".$!;
while(my $item = <MENUFILE>) {
push(@{$menus{"menu"}},$item);
}
close(MENUFILE);
chomp @{$menus{"menu"}};
} else {
opendir(my $dir,$pages_dir) or return "Problem parsing the pages directory:".$!;
while (my $file = readdir($dir)) {
next if ($file =~ m/^\./);
next if ($file =~ m/_dir$/);
push (@{$menus{"menu"}}, $file);
}
close($dir);
}
# Get any additional menus. currently supports 1 sub menu, eventually recursive
if (-d $pages_dir.$current_page."_dir") {
$menus{$current_page} = ();
opendir(my $dir,$pages_dir.$current_page."_dir") or return "Problem parsing the ".$current_page."_dir directory:".$!;
while (my $file = readdir($dir)) {
next if ($file =~ m/^\./);
next if ($file =~ m/_dir$/);
push (@{$menus{$current_page}}, $current_page."_dir/".$file);
}
close($dir);
}
my $buffer = "";
for my $menu_name (sort keys %menus) {
$buffer .= render_menu($menu_name,@{$menus{$menu_name}});
}
return $buffer;
}
sub page_template {
my $content = join("\n",@_);
my $page_content = html_tag(
'div',
$content
,{attribute=>'id', value=>'screen'});
$page_content .= menu(clean_input($request[4]));
$page_content .= html_tag('div',"Murkfall.net",{attribute=>'id',value=>"footer"});
return $page_content;
}
sub build_page {
my @content = get_page(shift); #should 404 if page doesn't exsist
print http_status(200,"text/html; charset=utf-8");
print "<!DOCTYPE html>\n";
print html_tag("html",
html_tag("head",header()).
html_tag("body",
render_logo($site_symbol).
page_template(@content).
include(@footer_includes),
)
);
}
build_page(clean_input($request[4]));