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 $parsed{$key} = $value;
134 }
135 elsif ($_ =~ /^version=(.*)$/)
136 {
137 $parsed{version} = $1;
138 }
139 elsif ($_ =~ /^release=(.*)$/)
140 {
141 $parsed{release} = $1;
142 }
143 }
144 close (FILE);
145 }
146
147 return { %parsed };
148 }
149
150 sub main
151 {
152 my %db;
153
154 parse_args();
155
156 if (!$options{directory})
157 {
158 print_usage();
159 return 0;
160 }
161
162 foreach my $file (recurse_tree($options{directory}))
163 {
164 if ($file =~ q:.*/(.*)/Pkgfile$:)
165 {
166 $db{$1} = parse_pkgfile("$file");
167 }
168 }
169
170 print <<EOH;
171 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
172 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
173
174 <html xmlns="http://www.w3.org/1999/xhtml">
175 <head>
176 EOH
177
178 print " <title>$options{title}</title>\n";
179
180 print <<EOH;
181 <style type="text/css">
182 body
183 {
184 font-family: Verdana, sans-serif;
185 font-size: 85%;
186 padding: 2em;
187 }
188 a
189 {
190 color: black;
191 }
192 table
193 {
194 border: solid #CAD4E9 1px;
195 font-size: 85%;
196 }
197 td
198 {
199 padding: 6px;
200 }
201 tr.header
202 {
203 background-color: #CAD4E9;
204 }
205 tr.odd
206 {
207 background-color: #ECF0F7;
208 }
209 tr.even
210 {
211 background-color: #F7F9FC;
212 }
213 </style>
214 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
215 </head>
216 <body>
217 EOH
218
219 print " <h2>$options{title}</h2>\n";
220
221 if ($options{header})
222 {
223 open(FILE, $options{header}) or die "Couldn't open header file";
224 while (<FILE>)
225 {
226 print " " . $_;
227 }
228 close(FILE);
229 }
230
231 print " <table width=\"100%\" cellspacing=\"0\">\n";
232 print " <tr class=\"header\"><td><b>Port</b></td><td><b>Version</b></td><td><b>Description</b></td>";
233 if ($options{timestamp_accuracy} > 0)
234 {
235 print "<td><b>Last modified</b></td>";
236 }
237 print "</tr>\n";
238 our $odd = "odd";
239 my $count = 0;
240 foreach my $port (sort keys %db)
241 {
242 $count++;
243 print " <tr class=\"$odd\"><td>";
244 $db{$port}{URL} ? print "<a href=\"$db{$port}{URL}\">$port</a>" : print "$port";
245 print "</td><td><a href=\"$options{directory}/$port/\">$db{$port}{version}-$db{$port}{release}</a></td><td>";
246 print $db{$port}{Description} if $db{$port}{Description};
247 print "</td>";
248
249 if ($options{timestamp_accuracy} > 0)
250 {
251 my $date;
252
253 if ($options{date_from_file})
254 {
255 my @files = recurse_tree("$options{directory}/$port");
256 my @dates;
257 foreach my $file (@files)
258 {
259 push (@dates, (stat($file))[9]);
260 }
261 @dates = sort @dates;
262 $date = $dates[$#dates];
263
264 }
265 elsif ($options{date_from_pkgfile})
266 {
267 $date = (stat("$options{directory}/$port/Pkgfile"))[9];
268 }
269 else
270 {
271 $date = (stat("$options{directory}/$port"))[9];
272 }
273
274 print "<td>" . isotime($date, $options{timestamp_accuracy}) . "</td>";
275 }
276
277 print "</tr>\n";
278
279 if ($odd eq "odd") { $odd = "even"; }
280 else { $odd = "odd"; }
281 }
282 print " </table>\n";
283 print " <p><b>$count ports</b></p>\n";
284
285 if ($options{footer})
286 {
287 open(FILE, $options{footer}) or die "Couldn't open footer file";
288 while (<FILE>)
289 {
290 print " " . $_;
291 }
292 close(FILE);
293 }
294
295 print " <p><i>Generated by <a href=\"http://www.karsikkopuu.net/crux/scripts/\">portspage</a> $version on " . isotime() . ".</i></p>\n";
296
297 print <<EOH;
298 </body>
299 </html>
300 EOH
301
302 return 0;
303 }
304
305 sub isotime
306 {
307 my $time = (shift or time);
308 my $accuracy = (shift or 2);
309 my @t = gmtime ($time);
310 my $year = $t[5] + 1900;
311 my $month = sprintf("%02d", $t[4] + 1);
312 my $day = sprintf("%02d", $t[3]);
313
314 if ($accuracy == 1)
315 {
316 return "$year-$month-$day";
317 }
318
319 return "$year-$month-$day " . sprintf("%02d:%02d:%02d UTC", $t[2], $t[1], $t[0]);
320 }
321
322 exit(main());
323
324 # End of file
|