summaryrefslogtreecommitdiff
path: root/portspage
blob: 9a79f2fa8275a69384b651f309c158ef22734b31 (plain)
    1 #!/usr/bin/perl -w
    2 
    3 our $version = "1.0.5";
    4 
    5 ########################################################################
    6 #
    7 # portspage
    8 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    9 # This is a script for generating CRUX port listings.
   10 # Distributed under the terms of the GPL license.
   11 # Report bugs and suggestions to jmcquah at disroot dot org.
   12 #
   13 # Changelog:
   14 # 1.0.5
   15 #   - Added a table row containing the signify public key
   16 # 1.0.4
   17 #   - Added --date-from-pkgfile (patch from Mikhail Kolesnik)
   18 # 1.0.3
   19 #   - Fixed a problem with tabs in Pkgfile
   20 # 1.0.2
   21 #   - Might as well make it XHTML 1.1
   22 # 1.0.1
   23 #   - Output is now valid XHTML 1.0 Strict
   24 #
   25 ########################################################################
   26 
   27 use strict;
   28 use Cwd qw(cwd getcwd);
   29 
   30 our %options =
   31 (
   32 	title => "CRUX ports",
   33 	timestamp_accuracy => 1,
   34 	date_from_file => 0,
   35 );
   36 
   37 sub print_usage
   38 {
   39 	print <<EOT;
   40 Usage: portspage [OPTION]... [DIRECTORY]
   41 
   42   --title=TITLE               set the page title
   43   --header=FILE               name of file to insert before port listing
   44   --footer=FILE               name of file to insert after port listing
   45   --timestamp-accuracy=LEVEL  0 = no timestamp, 1 = date only, 2 = date and time
   46                               default is 1
   47   --date-from-file            take date from newest file instead of directory
   48   --date-from-pkgfile         take date from Pkgfile instead of directory
   49   --version                   output version information and exit
   50 
   51 Report bugs to <jukka\@karsikkopuu.net>.
   52 EOT
   53 }
   54 
   55 sub parse_args
   56 {
   57 	foreach my $arg (@ARGV)
   58 	{
   59 		if ($arg =~ /^--header=(.*)$/)
   60 		{
   61 			$options{header} = $1;
   62 		}
   63 		elsif ($arg =~ /^--footer=(.*)$/)
   64 		{
   65 			$options{footer} = $1;
   66 		}
   67 		elsif ($arg =~ /^--title=(.*)$/)
   68 		{
   69 			$options{title} = $1;
   70 		}
   71 		elsif ($arg =~ /^--timestamp-accuracy=(0|1|2)$/)
   72 		{
   73 			$options{timestamp_accuracy} = $1;
   74 		}
   75 		elsif ($arg =~ /^--date-from-file$/)
   76 		{
   77 			$options{date_from_file} = 1;
   78 		}
   79 		elsif ($arg =~ /^--date-from-pkgfile$/)
   80 		{
   81 			$options{date_from_pkgfile} = 1;
   82 		}
   83 		elsif ($arg =~ /^--version$/)
   84 		{
   85 			print "$version\n";
   86 			exit 0;
   87 		}
   88 		elsif ($arg =~ /^--help$/)
   89 		{
   90 			print_usage();
   91 			exit 0;
   92 		}
   93 		else
   94 		{
   95 			$options{directory} = $arg;
   96 		}
   97 	}
   98 }
   99 
  100 sub recurse_tree
  101 {
  102 	my $path = shift;
  103 	my @list;
  104 
  105 	while ($path =~ s/\/\//\//g) {}
  106 	$path =~ s/\/$//;
  107 
  108 	opendir(DIR, $path) or return;
  109 	ENTRY:
  110 	foreach my $entry(sort(readdir(DIR)))
  111 	{
  112 		next ENTRY if $entry eq ".";
  113 		next ENTRY if $entry eq "..";
  114 		push (@list, "$path/$entry") if -f "$path/$entry";
  115 		push (@list, recurse_tree("$path/$entry")) if -d "$path/$entry";
  116 	}
  117 
  118 	return @list;
  119 }
  120 
  121 sub parse_pkgfile
  122 {
  123 	my %parsed;
  124 	my $pkgfile = shift;
  125 
  126 	if (open (FILE, $pkgfile))
  127 	{
  128 		while (<FILE>)
  129 		{
  130 			if ($_ =~ /^#\s*(.*?):\s*(.*)$/)
  131 			{
  132 				my $key = $1;
  133 				my $value = $2;
  134 				$value =~ s/</&lt;/g;
  135 				$value =~ s/>/&gt;/g;
  136 				$value =~ s/&/&amp;/g;
  137 				$parsed{$key} = $value;
  138 			}
  139 			elsif ($_ =~ /^version=(.*)$/)
  140 			{
  141 				$parsed{version} = $1;
  142 			}
  143 			elsif ($_ =~ /^release=(.*)$/)
  144 			{
  145 				$parsed{release} = $1;
  146 			}
  147 		}
  148 		close (FILE);
  149 	}
  150 
  151 	return { %parsed };
  152 }
  153 
  154 sub main
  155 {
  156 	my %db;
  157 
  158 	parse_args();
  159 
  160 	if (!$options{directory})
  161 	{
  162 		print_usage();
  163 		return 0;
  164 	}
  165 
  166 	foreach my $file (recurse_tree($options{directory}))
  167 	{
  168 		if ($file =~ q:.*/(.*)/Pkgfile$:)
  169 		{
  170 			$db{$1} = parse_pkgfile("$file");
  171 		}
  172 	}
  173 
  174 	print <<EOH;
  175 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  176     "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  177 
  178 <html xmlns="http://www.w3.org/1999/xhtml">
  179  <head>
  180 EOH
  181 
  182 	print "  <title>$options{title}</title>\n";
  183 
  184 	print <<EOH;
  185   <style type="text/css">
  186    body
  187    {
  188     font-family: Verdana, sans-serif;
  189     font-size: 85%;
  190     padding: 2em;
  191    }
  192    a
  193    {
  194     color: black;
  195    }
  196    table
  197    {
  198     border: solid #CAD4E9 1px;
  199     font-size: 85%;
  200    }
  201    td
  202    {
  203     padding: 6px;
  204    }
  205    tr.header
  206    {
  207     background-color: #CAD4E9;
  208    }
  209    tr.odd
  210    {
  211     background-color: #ECF0F7;
  212    }
  213    tr.even
  214    {
  215     background-color: #F7F9FC;
  216    }
  217   </style>
  218   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  219  </head>
  220  <body>
  221 EOH
  222 
  223 	print "  <h2>$options{title}</h2>\n";
  224 
  225 	if ($options{header})
  226 	{
  227 		open(FILE, $options{header}) or die "Couldn't open header file";
  228 		while (<FILE>)
  229 		{
  230 			print "  " . $_;
  231 		}
  232 		close(FILE);
  233 	}
  234 
  235 	
  236 
  237 
  238 	print "  <table width=\"100%\" cellspacing=\"0\">\n";
  239 	my $CWD = getcwd;
  240 	my @repopath = split /\//, $CWD;
  241 	my $repo = $repopath[$#repopath];
  242 	my $pubkey = "/etc/ports/".$repo.".pub";
  243 	if (-e $pubkey) {
  244 		open(KH, $pubkey) or die "Couldn't read from public key!";
  245 		while (my $line = <KH>) {
  246 		    chomp $line;
  247 		    if ($line =~ "untrusted comment") {
  248 		    }
  249 		    else {
  250 			print "  <tr class=\"header\"><td colspan=\"4\">\n";
  251 			print "  <strong>Signify public key:</strong> $line\n";
  252 			print "  </td></tr>\n";
  253 		    }
  254 		}
  255 		close(KH);
  256 	}
  257 	print "   <tr class=\"header\"><td><b>Port</b></td><td><b>Version</b></td><td><b>Description</b></td>";
  258 	if ($options{timestamp_accuracy} > 0)
  259 	{
  260 		print "<td><b>Last modified</b></td>";
  261 	}
  262 	print "</tr>\n";
  263 	our $odd = "odd";
  264 	my $count = 0;
  265 	foreach my $port (sort keys %db)
  266 	{
  267 		$count++;
  268 		print "   <tr class=\"$odd\"><td>";
  269 		$db{$port}{URL} ? print "<a href=\"$db{$port}{URL}\">$port</a>" : print "$port";
  270 		print "</td><td><a href=\"$options{directory}/$port/\">$db{$port}{version}-$db{$port}{release}</a></td><td>";
  271 		print $db{$port}{Description} if $db{$port}{Description};
  272 		print "</td>";
  273 
  274 		if ($options{timestamp_accuracy} > 0)
  275 		{
  276 			my $date;
  277 
  278 			if ($options{date_from_file})
  279 			{
  280 				my @files = recurse_tree("$options{directory}/$port");
  281 				my @dates;
  282 				foreach my $file (@files)
  283 				{
  284 					push (@dates, (stat($file))[9]);
  285 				}
  286 				@dates = sort @dates;
  287 				$date = $dates[$#dates];
  288 
  289 			}
  290 			elsif ($options{date_from_pkgfile})
  291 			{
  292 				$date = (stat("$options{directory}/$port/Pkgfile"))[9];
  293 			}
  294 			else
  295 			{
  296 				$date = (stat("$options{directory}/$port"))[9];
  297 			}
  298 
  299 			print "<td>" . isotime($date, $options{timestamp_accuracy}) . "</td>";
  300 		}
  301 
  302 		print "</tr>\n";
  303 
  304 		if ($odd eq "odd") { $odd = "even"; }
  305 		else { $odd = "odd"; }
  306 	}
  307 	print "  </table>\n";
  308 	print "  <p><b>$count ports</b></p>\n";
  309 
  310 	if ($options{footer})
  311 	{
  312 		open(FILE, $options{footer}) or die "Couldn't open footer file";
  313 		while (<FILE>)
  314 		{
  315 			print "  " . $_;
  316 		}
  317 		close(FILE);
  318 	}
  319 
  320 	print "  <p><i>Generated by portspage $version on " . isotime() . ".</i></p>\n";
  321 
  322 	print <<EOH;
  323  </body>
  324 </html>
  325 EOH
  326 
  327 	return 0;
  328 }
  329 
  330 sub isotime
  331 {
  332 	my $time = (shift or time);
  333 	my $accuracy = (shift or 2);
  334 	my @t = gmtime ($time);
  335 	my $year = $t[5] + 1900;
  336 	my $month = sprintf("%02d", $t[4] + 1);
  337 	my $day = sprintf("%02d", $t[3]);
  338 
  339 	if ($accuracy == 1)
  340 	{
  341 		return "$year-$month-$day";
  342 	}
  343 
  344 	return "$year-$month-$day " . sprintf("%02d:%02d:%02d UTC", $t[2], $t[1], $t[0]);
  345 }
  346 
  347 exit(main());
  348 
  349 # End of file

Generated by cgit