+Comment: FIXME: "head_css" no longer exists in My::Web branch "apache2"
[MyWeb.git] / Project.pm
1 # $Id$
2 # Common functions for HTML/XHTML output generation
3 # Copyright (C) 2003 Jan Kratochvil <project-www.jankratochvil.net@jankratochvil.net>
4
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; exactly version 2 of June 1991 is required
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
19 package My::Project;
20 require 5.6.0;  # at least 'use warnings;' but we need some 5.6.0+ modules anyway
21 our $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; };
22 our $CVS_ID=q$Id$;
23 use strict;
24 use warnings;
25
26 use My::Web;
27 require CGI;
28
29 use Exporter;
30 our @EXPORT=qw();
31 our @ISA=qw(My::Web Exporter);
32
33
34 sub ENTRIES     { return top_dir_disk()."/project/CVS/Entries"; }
35 sub ENTRIES_LOG { return top_dir_disk()."/project/CVS/Entries.Log"; }
36
37
38 sub print_project
39 {
40 my($class,$ListItem,%args)=@_;
41
42         print "<h1>".$W->{"title"}."</h1>\n";
43         do { print $_ if $_; } for ($args{"project_text_after_title"});
44         print $ListItem->{"description"};
45         print "<hr />\n";
46         print $args{"before_project_data"} || "";
47         return if $args{"no_project_data"};
48         my @table=(
49                 {"key"=>"summary","text"=>"Summary"},
50                 {"key"=>"license","text"=>"License","format"=>sub ($) {
51                                 my %known=(
52                                                 "PD"=>"Public Domain",
53                                                 "GPL"=>a_href("http://www.gnu.org/licenses/gpl.html","GNU General Public License"),
54                                                 "LGPL"=>a_href("http://www.gnu.org/licenses/lgpl.html","GNU Lesser General Public License"),
55                                                 "com"=>"Commercial"
56                                                 );
57                                 return $known{$_[0]};
58                                 }},
59                 {"key"=>"maintenance","text"=>"State","format"=>sub ($) {
60                                 my %known=(
61                                                 "active"=>"Ready to use. Project is now actively developed.",
62                                                 "ready"=>"Ready to use. Maintained.",
63                                                 "dead"=>"Dead code, no longer supported.",
64                                                 "merge"=>"Functions belong to existing other project.",
65                                                 "obsolete"=>"Obsoleted.",
66                                                 "update"=>"Package needs updating to recent software.",
67                                                 "accepted"=>"This patch got already integrated by the original package maintainer.",
68                                                 "pending"=>"Patch is ready to be applied to the mainstream.",
69                                                 "ignored"=>"Patch was ignored. It is not applied in the mainstream.",
70                                                 ""=>"",
71                                                 );
72                                 my @r;
73                                 for ($known{($_[0]=~/^([^-]*)-?/)[0] || ""}) {
74                                         push @r,$_ if $_;
75                                         push @r," $'" if $';
76                                         }
77                                 return join(" ",@r);
78                                 }},
79                 {"key"=>"aminet","text"=>a_href('http://www.aminet.net/','Aminet'),"format"=>sub ($) {
80                                 return join(" ",
81                                                 a_href('http://www.aminet.net/'.$_[0].".lha",$_[0].".lha"),
82                                                 "(".a_href('http://www.aminet.net/'.$_[0].".readme","readme").")");
83                                 }},
84                 {"key"=>qr(^download\b),"text"=>sub ($) {
85                                                 $_[0]=~s/^download//;
86                                                 $_[0]=~s/^-/ /;
87                                                 return "Download".$_[0];
88                                                 },
89                                 "format"=>sub ($) {
90                                                 return a_href($_[0],CGI::escapeHTML(File::Basename::basename($_[0])),"size"=>2);
91                                                 }},
92                 {"key"=>qr(^link\b),"text"=>sub ($) {
93                                                 $_[0]=~s/^link-//;
94                                                 return $_[0];
95                                                 },
96                                 "format"=>sub ($) {
97                                                 return($_[0]=~/^<a\b/ ? $_[0] : a_href($_[0],CGI::escapeHTML($_[0])));
98                                                 }},
99                 {"key"=>qr(^cvs\b),"text"=>sub ($) {
100                                                 $_[0]=~s/^cvs//;
101                                                 $_[0]=~s/^-/ /;
102                                                 return "CVS".$_[0];
103                                                 },
104                                 "format"=>sub ($$) {
105                                                 my($val,$key)=@_;
106                                                 $key=~s/^cvs//;
107                                                 $key=~s/^-/ /;
108                                                 my $branch="";
109                                                 $branch=$1 if $val=~s/:(.*)//;
110                                                 return join("<br />\n\t\t",
111                                                                 CGI::escapeHTML("cvs -d ".$W->{"pserver"}.":".$W->{"pserver_path"}." -z3"
112                                                                                 ." checkout".(!$branch ? "" : " -r $branch -kk")
113                                                                                 .($val!~m#/# ? "" : " -d ".File::Basename::basename($val))
114                                                                                 ." $val"),
115                                                                 join(" | \n\t\t",
116                                                                                 map({ a_href($_->[1],$_->[0]); }
117                                                                                                 ["ViewCVS CVS repository",$W->{"project_viewcvs"}.$val."/".(!$branch ? "" : '?only_with_tag='.$branch)],
118                                                                                                 ["Download CVS snapshot" ,
119                                                                                                                 $W->{"project_viewcvs"}.$val."/".File::Basename::basename($val).".tar.gz?tarball=1"
120                                                                                                                                 .(!$branch ? "" : '&only_with_tag='.$branch)],
121                                                                                                 ["CVS ChangeLog"         ,"/project/ChangeLog.txt.pl?cvs=$val"])));
122                                                 }},
123                 {"key"=>"ownership","text"=>"Ownership"},
124                 {"key"=>"sponsorship","text"=>"Sponsorship"},
125                 {"key"=>"language","text"=>"Programming language","format"=>sub ($) {
126                                 return a_href("http://java.sun.com/",CGI::escapeHTML($_[0]))
127                                                 if $_[0]=~/^Java\b/;
128                                 return a_href("http://www.php.net/",CGI::escapeHTML($_[0]))
129                                                 if $_[0]=~/^PHP\b/;
130                                 return undef();
131                                 }},
132                 );
133
134 sub tableit_func
135 {
136 my($tableit,$val,$key,$ListItem)=@_;
137
138         delete $ListItem->{$key};
139         my $r="";
140         $r.="<tr>";
141                 if ($tableit->{"text"}) {
142                         $r.="<td>";
143                                 $r.=(!ref $_ ? $_ : &{$_}($key)) for ($tableit->{"text"});
144                         $r.="</td>";
145                         }
146                 if ($tableit->{"format"}) {
147                         do { $val=$_ if defined $_; } for (&{$tableit->{"format"}}($val,$key));
148                         }
149                 return join("",map("<tr><td>".$_->[0]."</td><td>".$_->[1]."</td></tr>\n",@$val))
150                                 if ref $val;
151                 $r.="<td>$val</td>";
152         $r.="</tr>\n";
153 }
154
155         print '<table border="0" class="print_project">'."\n";
156                 for my $tableit (@table) {
157                         if (!ref $tableit->{"key"}) {
158                                 print tableit_func($tableit,$ListItem->{$tableit->{"key"}},$tableit->{"key"},$ListItem)
159                                                 if $ListItem->{$tableit->{"key"}};
160                                 }
161                         else {
162                                 for my $key (@{$ListItem->{"keys_array"}}) {
163                                         my $keyregex=$tableit->{"key"};
164                                         next if $key!~/$keyregex/;
165                                         print tableit_func($tableit,$ListItem->{$key},$key,$ListItem);
166                                         }
167                                 }
168                         }
169         print "</table>\n";
170         print vskip;
171 }
172
173 sub project_arr_to_hash (@)
174 {
175 my(@arr)=@_;
176
177         return (
178                         @arr,
179                         "keys_array"=>[ My::Web::arr_keys(@arr) ],
180                         );
181 }
182
183 sub title ($$)
184 {
185 my($class,$hashref)=@_;
186
187         return $hashref->{"name"}.": ".$hashref->{"summary"},
188 }
189
190 # $args{"ListItem"}=\%...;
191 sub init_project ($%)
192 {
193 my($class,%args)=@_;
194
195         my $ListItem={ project_arr_to_hash(@{$args{"ListItem"}}) };
196         my $W=$class->init(
197                         "title"=>$class->title($ListItem),
198                         map(("rel_$_"=>top_dir('/project/Rel.pl?rel='.$_.'&project='.($args{"__PACKAGE__"}=~/^.*::([^:]+)::[^:]+$/)[0])),
199                                         qw(prev next)),
200                         "rel_up"=>top_dir('/project/'),
201 #                       "rel_start"=>top_dir(), # TODO:homepage
202                         %args,
203                         # FIXME: "head_css" no longer exists in My::Web branch "apache2"
204                         "head_css"=>($args{"head_css"} || "")."
205 table.print_project td { vertical-align: top; }
206 ",
207                         "WebConfig::heading_novskip"=>1,
208                         );
209         $class->heading();
210         print $class->platforms($ListItem->{"platform"});
211         $class->print_project({ %$ListItem },%args);
212         return $W;
213 }
214
215 sub one_item_list_read($$)
216 {
217 my($class,$name)=@_;
218
219         Wrequire "project::${name}::ListItem";
220         my $item=eval('\@project::'.$name.'::ListItem::ListItem');
221         do { warn "Broken project/$name/ListItem.pm"; next; } if !defined $item;
222         return @$item;
223 }
224
225 sub item_hash_read ()
226 {
227 # FIXME: $class
228         my %dirs;
229         for my $ENTRIES (ENTRIES(),ENTRIES_LOG()) {
230                 local *E;
231                 next if !open E,$ENTRIES;
232                 while (<E>) {
233                         chomp;
234                         do { $dirs{$1}=1; next; } if m#^(?:A )?D/([^/]*)/#;
235                         next if m#^/([^/]*)/# ;
236                         next if /^D$/;
237                         warn "File $ENTRIES contains invalid line \"$_\": $!";
238                         }
239                 close E;
240                 }
241
242         my %item;
243         for my $dir (keys(%dirs)) {
244                 Wrequire "project::${dir}::ListItem";
245                 my $item=eval('\@project::'.$dir.'::ListItem::ListItem');
246                 do { warn "Broken project/$dir/ListItem.pm"; next; } if !defined $item;
247                 $item{$dir}={ My::Project::project_arr_to_hash(My::Project->one_item_list_read($dir)) };
248                 }
249         return %item;
250 }
251
252 our @platforms=(
253                 "unixuser"=>"UNIX",
254                 "unixdevel"=>"UNIX-devel",
255                 "web"=>"Web",
256                 "amiga"=>"Amiga",
257                 "w32"=>"MS-Windows",
258                 "dos"=>"MS-DOS",
259                 "patch"=>"Patches",
260                 );
261
262 sub views ($$)
263 {
264 my($class,$view_selected)=@_;
265
266         my $view=sub ($$)
267                 {
268                 my($current,$href,$content)=@_;
269
270                         return a_href($href,$content) if $current ne $view_selected;
271                         return "<b>".$content."</b> (current)";
272                 };
273
274         return <<"HERE";
275 <h1>Project List of @{[ a_href 'http://www.jankratochvil.net/','Jan Kratochvil' ]}</h1>
276
277 <ul>
278         <li>@{[ &{$view}('Detailed'     ,'/project/','Detailed project listing per platform') ]}</li>
279         <li>@{[ &{$view}('BriefPlatform','/project/List.html.pl?platform=platform',
280                         'Brief project listing per platform') ]}</li>
281         <li>@{[ &{$view}('BriefUnified' ,'/project/List.html.pl',
282                         'Unified brief project listing') ]}</li>
283 </ul>
284 @{[ vskip "1ex" ]}
285 HERE
286 }
287
288 sub platforms ($;$%)
289 {
290 my($class,$platform_selected,%args)=@_;
291
292         my $r="";
293         $r.='<table border="0" align="center"><tr>'."\n";
294                 $r.='<td>';
295                         $r.='<table border="1" align="center"'  # align="left"
296                                         .' style="border-collapse: collapse; border-style: solid; border-width: 1px;">'."\n";
297                                 $r.='<tr>'."\n";
298                                         $r.='<td style="padding: 5px; font-weight: bold;">'."\n";
299                                                 $r.='Projects';
300                                         $r.='</td>'."\n";
301                                 $r.='</tr>'."\n";
302                         $r.='</table>';
303                 $r.='</td>';
304                 $r.='<td>';
305                         $r.='<table border="1" align="center" style="border-collapse: collapse; border-style: solid;">'."\n";
306                                 $r.='<tr>'."\n";
307                                         my @platforms=@platforms;
308                                         while (@platforms) {
309                                                 my $platform_sym =shift @platforms;
310                                                 my $platform_name=shift @platforms;
311                                                 my $chosen=($platform_selected && $platform_selected eq $platform_sym);
312                                                 $r.='<td style="padding: 5px;">';
313                                                         $r.=a_href((!$platform_selected ? "" : "/project/").'#'.$platform_sym,$platform_name,
314                                                                         "attr"=>($chosen
315                                                                                         ? 'style="text-decoration: underline; font-weight: bold;"'
316                                                                                         : 'style="text-decoration: inherit; /* revoke underline */"'));
317                                                 $r.="</td>\n";
318                                                 }
319                                 $r.='</tr>'."\n";
320                         $r.='</table>'."\n";
321                 $r.='</td>'."\n";
322         $r.='</tr></table>'."\n";
323         if (!$args{"novskip"}) {
324                 $r.="<hr />\n";
325                 $r.=My::Web::vskip "6ex";
326                 }
327         $r;
328 }
329
330 sub section ($$)
331 {
332 my($class,$name)=@_;
333
334         my %item=( $class->one_item_list_read($name) );
335         my $title=$class->title(\%item);
336         my $r="";
337
338         print $class->platforms($item{"platform"},"novskip"=>1);
339
340         $r.='<table border="0" align="center"><tr>'."\n";
341                 $r.='<td>';
342                         $r.='<table border="1" align="center" style="border-collapse: collapse; border-style: solid;">'."\n";
343                                 $r.='<tr><td style="font-size: larger;">'."\n";
344                                         $r.=a_href "/project/$name/",$title;
345                                 $r.='</td></tr>'."\n";
346                         $r.='</table>'."\n";
347                 $r.='</td>'."\n";
348         $r.='</tr></table>'."\n";
349         $r.=vskip "1ex";
350         $r;
351 }
352
353 1;