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