| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 | package Gsg::Html;use strict;use warnings;use Log::Log4perl qw(:easy);use lib "/usr/local/lib";use Shellex::Shellex qw(shellex findBin);use Gsg::Gather qw(get_file_tree get_diff_stat);use Gsg::MdParse qw (render_readme);use Exporter qw(import);our @EXPORT_OK = qw(	write_file append_file write_root_index clean_web_root	write_project_content);# These subs might belong in shellex# Add logger for write opts TODOsub write_file($$) {	my $content = shift;	my $path = shift;	open(my $fh, ">", $path) or die "Couldnt open $path\n";	print $fh "$content";	close $fh;	}sub append_file($$) {	my $content = shift;	my $path = shift;	open(my $fh, ">>", $path) or die "Couldnt open $path\n";	print $fh "$content";	close $fh;}sub write_root_index($$$$) {	my $index = shift;	my $project_dirs_ref = shift;	my $web_projects_dir_path = shift;	my $logger = shift;	write_file("", $index);	append_file("<html><body><b>Git Projects</b><br><head><META NAME=\"ROBOTS\" CONTENT=\"NOINDEX, NOFOLLOW\"></head>\n",$index);	append_file("<small><i>Statically generated web root for browsing this git server</i></small><br><hr/>",$index);		my $mkdirCmd = findBin("mkdir",$logger);	foreach my $project ( @$project_dirs_ref ) {		my $indexPath = $project . "index.html";		append_file("<table><div id=\"cotent\"><table id=\"index\"><tbody>",$index);		append_file("<tr><td><a href=\"projects/$indexPath\">$project</a></td>",$index);		shellex("$mkdirCmd -p $web_projects_dir_path$project",$logger);	}	append_file("</tr></tbody></table></div></body></html>",$index);	$logger->info("Wrote root index at $index");}sub check_for_html($) {	# Expects line from gen_line_nums or gen_diff_colors	# Will change < and > chars to < or >	# This adds tons of overhead, but should work better	# than <xmp> and will solve the rendering problems	my $line = shift;	my $new_line;	open my $fh, '>>', \$new_line or die "Can't open variable: $!";	foreach my $char ( split("",$line) ) {		if ( ! defined $char || $char eq "" ) {			print "Empty char\n";			next;		}		if ( $char eq "<" ) {			print $fh "<";		} elsif ( $char eq ">" ) {			print $fh ">";		} else {			print $fh "$char";		}	}	close $fh;	return $new_line;}sub gen_line_nums($$$) {	my $raw_file = shift;	my $filename = shift;	my $logger = shift;	my $html_file;	# Might be a better way to do this? TODO	open my $fh, '>>', \$html_file or die "Can't open variable: $!";		print $fh "<!DOCTYPE html><html><b>$filename</b><hr/><div id=\"content\"><pre id=\"blob\">";	my $line_counter = 1;	foreach my $line ( split("\n", $raw_file) ) {		if ( $line ne "" ) {			$line = check_for_html($line);		}		print $fh "<a href=\"\#l$line_counter\" class=\"line\" id=\"l$line_counter\">$line_counter</a>\t$line</br>";		$line_counter++;	}	print $fh "</pre></div><html>";	close $fh;	$logger->info("Generated line numbers for $filename");	return $html_file;}sub gen_diff_colors($$$) {	my $raw_diff = shift;	my $id = shift;	my $logger = shift;	my $html_diff;	open my $fh, '>>', \$html_diff or die "Can't open variable: $!";	#print $fh "<!DOCTYPE html><html><div id=\"content\"><pre id=\"blob\">";	print $fh "<!DOCTYPE html><html><b>$id</b><hr/><div id=\"content\"><pre>";	my $line_counter = 1;	foreach my $line ( split("\n", $raw_diff) ) {		if ( $line ne "" ) {			$line = check_for_html($line);		}		if ( $line =~ m/^\+/ ) {			print $fh "<font color=\"green\">$line</font></br>";		} elsif ( $line =~ m/^\-/ ) {			print $fh "<font color=\"red\">$line</font></br>";		} elsif ( $line =~ m/^@@/ ) {			print $fh "<font color=\"blue\">$line</font></br>";		} elsif ( $line =~ m/^diff/ ) {			print $fh "<font color=\"purple\">$line</font></br>";		} elsif ( $line =~ m/^commit/ ) {			print $fh "<font color=\"purple\"><b>$line</b></font></br>";		} else {			print $fh "$line</br>";		}		$line_counter++;	}	print $fh "</pre></div></html>";	close $fh;	$logger->info("Generated colored diff for $id");	return $html_diff;}# Main sub for generating project page# Might make more sense to split into more subs?sub write_project_content($$$$$) {	my $project_dirs_ref = shift;	my $trimmed_project_dirs_ref = shift;	my $web_projects_dir = shift;	my $clone_path = shift;	my $logger = shift;	# Make these array's easier to work with in a hash	# Key is path to actual git dir, val is path to associated web dir	my %projects_map;	@projects_map{@$project_dirs_ref} = @$trimmed_project_dirs_ref;	$logger->info("Assembling data structures of git info");	# Write files part of project index	foreach my $project_path ( keys %projects_map ) {		my $spec_web_dir = $web_projects_dir . $projects_map{$project_path};		my $project_index = $spec_web_dir . "index.html";		write_file("",$project_index);		append_file("<html><a href=\"../../index.html\"><b>Return to index</a></b></br>",$project_index);		my $uniq_clone_path = "Disabled";		if ( $clone_path ne "Disabled" ) {			$uniq_clone_path = $clone_path . $projects_map{$project_path};		}		append_file("<b><pre>Clone:<font color=\"green\"> git clone $uniq_clone_path</font></pre></b><hr/>",$project_index);		# Get all project data structures/info		my ( $file_tree_ref, $file_content_ref, $commits_ref, $commit_ids_ref ) = get_file_tree($project_path,$logger);		# Handle README		if ( grep /^README.md$/, keys %$file_content_ref ) {			$logger->info("$projects_map{$project_path} contains a README");			my $readme_html = render_readme(${$file_content_ref}{'README.md'},$logger);			append_file("$readme_html",$project_index);		}		append_file("<b>Files for $projects_map{$project_path}</b><br>",$project_index);		append_file("<hr/>",$project_index);		## Write files ##		append_file("<table><div id=\"cotent\"><table id=\"index\"><thead><tr><td><b>File</b></td><td><b>Commit</b></td></tr></thead><tbody>",$project_index);		foreach my $filename ( sort keys %$file_content_ref ) {			my $browserCompat = $filename . ".html";			# Rewrite dir paths so we can save on disk without producing actual dir structure			if ( $filename =~ m/\// ) {				my $copy = $filename;				$copy =~ s/\//_/g;				$browserCompat = $copy . ".html";			}			append_file("<tr><td><a href=\"$browserCompat\">$filename</a></td><td>${$file_tree_ref}{$filename}</td>",$project_index);			my $html_file = gen_line_nums(${$file_content_ref}{$filename},$filename,$logger);			write_file("$html_file",$spec_web_dir . $browserCompat);		}	append_file("</tr></tbody></table></div></body>",$project_index);	append_file("<br>", $project_index);	append_file("<html><b>Logs for $projects_map{$project_path}</b><br>",$project_index);	append_file("<table><div id=\"cotent\"><table id=\"index\"><tbody>",$project_index);	append_file("<hr/>",$project_index);	# iterate over array to keep ordering	foreach my $commit_id ( @$commit_ids_ref ) {		my $filename = $commit_id . ".html";		append_file("<tr><td><a href=\"$filename\">$filename</a></td>",$project_index);		my $html_diff = gen_diff_colors(${$commits_ref}{$commit_id},$commit_id,$logger);		write_file($html_diff,$spec_web_dir . $filename);        }        append_file("</tr></tbody></table></div></body>",$project_index);        append_file("</html>",$project_index);	}	$logger->info("Done writing files");}# Not used currently, need to do more trimming/etc# TODO# Work around is rm -rf the webroot manually and then just rerun gsgsub clean_web_root($$$) {	my $web_projects_dir_path = shift;	my $git_projects_ref = shift;	my $logger = shift;	my $lsCmd = findBin("ls",$logger);	my $rmCmd = findBin("rm",$logger);	foreach my $dir ( split("\n", shellex("$lsCmd -d $web_projects_dir_path/*/",$logger)) ) {			if ( ! grep( /^$dir$/, @$git_projects_ref ) ) {			$logger->info("Found $dir in webroot but not in git root, removing...");			my $rmdir = $web_projects_dir_path . $dir;			$logger->info("Would remove $rmdir");			# Does this need to be safer? TODO			#shellex("$rmCmd $rmdir/*",$logger);			#shellex("$rmCmd -d $rmdir",$logger);		}	}}1;
 |