273 lines
7.2 KiB
Perl
Executable File
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 = "⛰";
|
|
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 ? " - ".$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">☰</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]));
|