/[suikacvs]/webroot/commitfeed/mkcommitfeed.pl
Suika

Contents of /webroot/commitfeed/mkcommitfeed.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations) (download)
Mon Nov 24 06:31:25 2008 UTC (15 years, 5 months ago) by wakaba
Branch: MAIN
Changes since 1.3: +23 -2 lines
File MIME type: text/plain
++ ChangeLog	24 Nov 2008 06:31:19 -0000
	* .htaccess: AddLangauge was missing.

	* Makefile: Add <link rel=feed> to |readme.html|.

	* mkcommitfeed.pl: Added availability sections to the document.

2008-11-24  Wakaba  <wakaba@suika.fam.cx>

1 #!/usr/bin/perl
2 use strict;
3
4 use Getopt::Long;
5 use Pod::Usage;
6 use Time::Local;
7
8 my $file_name;
9 my $feed_url;
10 my $feed_title = 'ChangeLog';
11 my $feed_author_name;
12 my $feed_author_mail;
13 my $feed_author_url;
14 my $feed_lang = 'i-default';
15 my $feed_related_url;
16 my $feed_license_url;
17 my $feed_rights;
18 my $entry_content;
19 my $entry_author_name;
20 my $entry_author_mail;
21 my $entry_date;
22 my $entry_title;
23
24 GetOptions (
25 'entry-author-mail=s' => \$entry_author_mail,
26 'entry-author-name=s' => \$entry_author_name,
27 'entry-content=s' => \$entry_content,
28 'entry-title=s' => \$entry_title,
29 'feed-author-mail=s' => \$feed_author_mail,
30 'feed-author-name=s' => \$feed_author_name,
31 'feed-author-url=s' => \$feed_author_url,
32 'feed-lang=s' => \$feed_lang,
33 'feed-license-url=s' => \$feed_license_url,
34 'feed-related-url=s' => \$feed_related_url,
35 'feed-rights=s' => \$feed_rights,
36 'feed-title=s' => \$feed_title,
37 'feed-url=s' => \$feed_url,
38 'file-name=s' => \$file_name,
39 'help' => sub {
40 pod2usage (-exitval => 0, -verbose => 2);
41 },
42 ) or pod2usage (-exitval => 1, -verbose => 1);
43 pod2usage (-exitval => 1, -verbose => 1,
44 -msg => "Required argument --file-name is not specified.\n")
45 unless defined $file_name;
46 pod2usage (-exitval => 1, -verbose => 1,
47 -msg => "Required argument --feed-url is not specified.\n")
48 unless defined $feed_url;
49
50 unless (defined $entry_content) {
51 $entry_content = '';
52 $entry_content .= $_ while <>;
53 }
54
55 if ($entry_content =~ /^(\d+)-(\d+)-(\d+)\s+(.+)<([^<>]+)>/m) {
56 # $entry_date //= timegm (0, 0, 0, $3, $2-1, $1);
57 $entry_author_name //= $4;
58 $entry_author_mail //= $5;
59 $entry_author_name =~ s/\s+$//;
60 }
61 $entry_date //= time;
62
63 pod2usage (-exitval => 1, -verbose => 1,
64 -msg => "Required argument --entry-author-name is not specified.\n")
65 unless defined $entry_author_name;
66
67 unless (defined $entry_title) {
68 my $time = [gmtime $entry_date];
69 $entry_title = sprintf '%04d-%02d-%02d %s', 1900+$time->[5], 1+$time->[4],
70 $time->[3], $entry_author_name;
71 }
72
73 require Message::DOM::DOMImplementation;
74 my $dom = Message::DOM::DOMImplementation->new;
75 my $doc;
76
77 {
78 if (-f $file_name) {
79 open my $file, '<:encoding(utf8)', $file_name or die "$0: $file_name: $!";
80 local $/ = undef;
81 $doc = $dom->create_document;
82 $doc->inner_html (<$file>);
83 } else {
84 $doc = $dom->create_atom_feed_document
85 ($feed_url, $feed_title, $feed_lang);
86 }
87 }
88
89 $doc->dom_config
90 ->{q<http://suika.fam.cx/www/2006/dom-config/create-child-element>} = 1;
91 my $feed = $doc->document_element;
92 unless ($feed) {
93 $feed = $doc->create_element_ns ('http://www.w3.org/2005/Atom', 'feed');
94 $doc->append_child ($feed);
95 }
96 $feed->set_attribute_ns ('http://www.w3.org/2000/xmlns/',
97 'xmlns', $feed->namespace_uri);
98
99 unless (@{$feed->author_elements}) {
100 if (defined $feed_author_name) {
101 my $author = $doc->create_element_ns ($feed->namespace_uri, 'author');
102 $author->name ($feed_author_name);
103 $author->email ($feed_author_mail) if defined $feed_author_mail;
104 $author->uri ($feed_author_url) if defined $feed_author_url;
105 $feed->append_child ($author);
106 }
107 }
108 unless (@{$feed->link_elements}) {
109 my $link_self = $doc->create_element_ns ($feed->namespace_uri, 'link');
110 $link_self->rel ('self');
111 $link_self->type ('application/atom+xml');
112 $link_self->hreflang ($feed_lang);
113 $link_self->href ($feed_url);
114 $feed->append_child ($link_self);
115
116 if (defined $feed_related_url) {
117 my $link = $doc->create_element_ns ($feed->namespace_uri, 'link');
118 $link->rel ('related');
119 $link->href ($feed_related_url);
120 $feed->append_child ($link);
121 }
122
123 if (defined $feed_license_url) {
124 my $link = $doc->create_element_ns ($feed->namespace_uri, 'link');
125 $link->rel ('license');
126 $link->href ($feed_license_url);
127 $feed->append_child ($link);
128 }
129 }
130
131 if (defined $feed_rights) {
132 $feed->rights_element->text_content ($feed_rights);
133 }
134
135 my $entry_id = 'entry-' . time;
136 my $entry = $feed->add_new_entry ($feed_url . '#' . $entry_id,
137 $entry_title);
138 $entry->set_attribute_ns ('http://www.w3.org/XML/1998/namespace',
139 'xml:id' => $entry_id);
140 if (defined $entry_author_name) {
141 my $author = $doc->create_element_ns ($feed->namespace_uri, 'author');
142 $author->name ($entry_author_name);
143 $author->email ($entry_author_mail) if defined $entry_author_mail;
144 $entry->append_child ($author);
145 }
146 $entry->updated_element->value ($entry_date);
147 my $content = $entry->content_element;
148 $content->type ('text');
149 $content->text_content ($entry_content);
150
151 {
152 open my $file, '>:utf8', $file_name or die "$0: $file_name: $!";
153 print $file $doc->inner_html;
154 }
155
156 ## $Date: 2008/11/24 06:18:00 $
157
158 __END__
159
160 =head1 NAME
161
162 mkcommitfeed.pl - Commit Log Feed Generator
163
164 =head1 SYNOPSIS
165
166 mkcommitfeed.pl \
167 --file-name filename.atom \
168 --feed-url http://example.com/myproject/filename.atom \
169 --feed-title "MyProject Commit Log" \
170 --feed-lang langtag \
171 --feed-related-url "http://example.com/myproject/" \
172 --feed-license-url "http://example.com/myproject/license" \
173 --feed-rights "Copyright or copyleft statement" \
174 < changes-in-this-revision.txt
175
176 =head1 DESCRIPTION
177
178 The C<mkcommitfeed.pl> script provides a command-line interface to
179 update an Atom Feed that is intended for providing commit logs for a
180 software developmenet project.
181
182 The script, when invoked, adds an Atom Entry that describes a change
183 made to the project's repository.
184
185 =head1 STANDARD INPUT
186
187 A description for the change must be specified to the standard input.
188 It is used as the plain text content of the atom:content element of
189 the Entry for the change to add.
190
191 Non-ASCII characters are not supported in this version of this script.
192 Maybe a future version of this script would support UTF-8.
193
194 =head1 ARGUMENTS
195
196 There are command-line options for the script. Some of them are
197 required, while the others are optional. As a general rule, an option
198 whose name begins with C<--entry> specifies a property for the Entry
199 to add, while an option whose name begins with C<--feed> specifies a
200 property for the entire Feed. Option values for Feed properties might
201 not be used when updating an existing Feed document.
202
203 =over 4
204
205 =item C<--entry-author-mail I<foo@domain.example>> (optional)
206
207 Specifies the mail address of the person who made a change. It is
208 used as the content of the C<atom:email> element of the C<atom:author>
209 element of the Entry.
210
211 If this option is not specified, but the standard input includes a
212 ChangeLog entry in the standard GNU format, then the mail address is
213 taken from the ChangeLog entry. Otherwise, C<atom:email> element is
214 not specified.
215
216 The option value must be an RFC 2822 C<addr-spec> that does not match
217 C<obs-addr-spec> (i.e. standard email address format). Otherwise the
218 generated Feed would be non-conforming.
219
220 =item C<--entry-author-name I<author-name>> (conditionally required)
221
222 Specifies the human readable name of the person who made a change. It
223 is used as the content of the C<atom:name> element of the
224 C<atom:author> element of the Entry.
225
226 If this option is not specified, but the standard input includes a
227 ChangeLog entry in the standard GNU format, then the name is taken
228 from the ChangeLog entry. If the standard input does not include a
229 GNU format ChangeLog entry, then the C<--entry-author-name> option
230 must be specified.
231
232 Non-ASCII characters are not supported in this version of this script.
233
234 =item C<--entry-content I<description>> (optional)
235
236 Specifies the description of the change. It is used as the content of
237 the C<atom:content> element of the Entry, with C<type=text>.
238
239 If this option is specified, its value is used as if it were from the
240 standard input and the actual standard input, if any, is ignored. If
241 neither this option nor the standard input is specified, then the
242 description is assumed as the empty string.
243
244 Non-ASCII characters are not supported in this version of this script.
245
246 =item C<--entry-title I<title>> (optional)
247
248 Specifies the title of the change. It is used as the content of the
249 C<atom:title> element of the Entry, with C<type=text>.
250
251 If this option is not specified, then the date of the change, as well
252 as the name of the author, is used as title.
253
254 Non-ASCII characters are not supported in this version of this script.
255
256 =item C<--feed-author-mail I<foo@domain.example>> (optional)
257
258 Specifies the mail address of the author of the Feed. It is used as
259 the content of the C<atom:email> element of the C<atom:author> element
260 of the Feed.
261
262 This option is ignored if the C<--feed-author-name> option is not
263 specified.
264
265 If this option is not specified, C<atom:email> element is not
266 specified.
267
268 The option value must be an RFC 2822 C<addr-spec> that does not match
269 C<obs-addr-spec> (i.e. standard email address format). Otherwise the
270 generated Feed would be non-conforming.
271
272 This option is ignored if the Feed already has an C<atom:author>
273 element.
274
275 =item C<--feed-author-name I<author-name>> (optional)
276
277 Specifies the human readable name of the author of the Feed. It is
278 used as the content of the C<atom:name> element of the C<atom:author>
279 element of the Feed.
280
281 If this option is not specified, the C<atom:author> element is not
282 specified in the Feed.
283
284 Non-ASCII characters are not supported in this version of this script.
285
286 This option is ignored if the Feed already has an C<atom:author>
287 element.
288
289 =item C<--feed-author-url I<url>> (optional)
290
291 Specifies the URI for the author (e.g. URL of the Web page for the
292 author). It is used as the content of the C<atom:uri> element of the
293 C<atom:author> element of the Feed.
294
295 If the C<--feed-author-name> option is not specified, this option is
296 ignored.
297
298 If this option is not specified, the C<atom:uri> element is not
299 specified.
300
301 The option value must be a URI reference conforming to RFC 3986. It
302 should be an absolute reference unless you understand what is the base
303 URL that is used to resolve a relative reference. Non-ASCII
304 characters (i.e. IRI references) are not supported in this version of
305 this script.
306
307 This option is ignored if the Feed already has an C<atom:author>
308 element.
309
310 =item C<--feed-lang I<langtag>> (optional)
311
312 Specifies the natural language used in textual parts of the Feed. It
313 is used as the value of C<xml:lang> attribute of the root element of
314 the Feed.
315
316 If this option is not specified, the default value I<i-default> is used.
317
318 This option is ignored if the Feed already exists and has a
319 C<atom:link> element.
320
321 =item C<--feed-license-url I<url>> (optional)
322
323 Specifies the URL that describes the license of the Feed. It is used
324 as the C<href> attribute value of an C<atom:link> element whose C<rel>
325 is C<license>.
326
327 If this option is not specified, the C<atom:link> element whose C<rel>
328 is C<license> is not specified.
329
330 The option value must be a URI reference conforming to RFC 3986. It
331 should be an absolute reference unless you understand what is the base
332 URL that is used to resolve a relative reference. Non-ASCII
333 characters (i.e. IRI references) are not supported in this version of
334 this script.
335
336 This option is ignored if the Feed already has a C<atom:link>
337 element.
338
339 =item C<--feed-related-url I<url>> (optional)
340
341 Specifies a related URL for the Feed. Usually the URL for the project
342 Web page should be specified. It is used as the C<href> attribute
343 value of an C<atom:link> element whose C<rel> is C<related>.
344
345 If this option is not specified, the C<atom:link> element whose C<rel>
346 is C<related> is not specified.
347
348 The option value must be a URI reference conforming to RFC 3986. It
349 should be an absolute reference unless you understand what is the base
350 URL that is used to resolve a relative reference. Non-ASCII
351 characters (i.e. IRI references) are not supported in this version of
352 this script.
353
354 This option is ignored if the Feed already has a C<atom:link>
355 element.
356
357 =item C<--feed-rights C<license-terms>> (optional)
358
359 Specifies the license terms for the Feed. It is used as the content
360 of the C<atom:rights> element of the Feed.
361
362 If there is the C<atom:rights> element exists, its value is replaced
363 by the value of this option.
364
365 If this option is not specified, the C<atom:rights> element is not
366 added. If there are already the C<atom:rights> element specified,
367 however, it is not removed from the Feed.
368
369 Non-ASCII characters are not supported in this version of this script.
370
371 =item C<--feed-title C<title>> (optional)
372
373 Specifies the title of the Feed. It is used as the content of the
374 C<atom:title> of the Feed.
375
376 If this option is not specified, the default value "ChangeLog" is used.
377
378 If there is Feed exists, then this option is ignored.
379
380 Non-ASCII characters are not supported in this version of this script.
381
382 =item C<--feed-url C<url>> (required)
383
384 Specifies the URL of the Feed itself. It is used in various places,
385 such as in the C<href> attribute of the C<atom:link> element whose
386 C<rel> is C<self>.
387
388 The option value must be a URI reference conforming to RFC 3986. It
389 should be an absolute reference unless you understand what is the base
390 URL that is used to resolve a relative reference. Non-ASCII
391 characters (i.e. IRI references) are not supported in this version of
392 this script.
393
394 =item C<--file-name C<path-to-atom-file>> (required)
395
396 Specifies the path to the file that contains the Atom Feed.
397
398 If the specified file is not found, then a new file is created.
399 Otherwise, the existing file is loaded as an Atom Feed and then it is
400 updated.
401
402 The file, if exists, must be encoded in UTF-8. The new content of the
403 file generated by this script is encoded in UTF-8.
404
405 =item C<--help>
406
407 Shows a help message and aborts.
408
409 =back
410
411 =head1 DEPENDENCY
412
413 For the execution of C<mkcommitfeed.pl>, the libiraries below are
414 required, as well as Perl 5.10.0 or later:
415
416 manakai-core L<http://suika.fam.cx/www/manakai-core/doc/web/>
417
418 Whatpm L<http://suika.fam.cx/www/markup/html/whatpm/readme>
419
420 =head1 DOWNLOAD
421
422 The latest version of this script is available from the CVS
423 repository: L<http://suika.fam.cx/gate/cvs/webroot/commitfeed/>.
424
425 A gzipped tarball for the files is also available:
426 L<http://suika.fam.cx/gate/cvs/webroot/commitfeed/commitfeed.tar.gz?tarball=1>.
427
428 =head1 SEE ALSO
429
430 The C<mkcommitfeed.pl> Web site
431 L<http://suika.fam.cx/commitfeed/readme>.
432
433 =head1 AUTHOR
434
435 Wakaba <w@suika.fam.cx>.
436
437 =head1 HISTORY
438
439 This module was originally developed as part of Whatpm
440 L<http://suika.fam.cx/www/markup/html/whatpm/readme>.
441
442 An Atom Feed for updates for this script, which is itself generated by
443 this script, is available at
444 L<http://suika.fam.cx/commitfeed/commitfeed-commit>.
445
446 =head1 LICENSE
447
448 Copyright 2008 Wakaba <w@suika.fam.cx>
449
450 This program is free software; you can redistribute it and/or
451 modify it under the same terms as Perl itself.
452
453 =cut
454
455 ## $Date: 2008/11/24 06:18:00 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24