changelog-to-rss 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #! /usr/bin/perl
  2. # Copyright (C) 2005 Alex Schroeder <alex@emacswiki.org>
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 3 of the License, or
  7. # (at your option) any later version.
  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, see <http://www.gnu.org/licenses/>.
  16. use CGI;
  17. use CGI::Carp qw(fatalsToBrowser);
  18. use LWP::UserAgent;
  19. use encoding 'utf8';
  20. use POSIX;
  21. my $q = new CGI;
  22. my $url = $q->param('url');
  23. my $pattern = $q->param('pattern');
  24. if (not $url) {
  25. print $q->header(),
  26. $q->start_html('ChangeLog to RSS'),
  27. $q->h1('ChangeLog to RSS'),
  28. $q->p('Translates ChangeLog output to RSS 2.0.'),
  29. $q->p(q{$Id: changelog-to-rss,v 1.17 2005/01/07 13:09:27 as Exp $}),
  30. $q->start_form(-method=>'GET'),
  31. $q->p('ChangeLog URL: ',
  32. $q->textfield('url', '', 70)),
  33. $q->p('Link pattern if available, use %s for the filename: ',
  34. $q->textfield('pattern', '', 70)),
  35. $q->p('Limit number of entries returned: ',
  36. $q->textfield('limit', '15', 5)),
  37. $q->p($q->submit()),
  38. $q->end_form(),
  39. $q->end_html();
  40. exit;
  41. }
  42. print $q->header(-type=>'application/rss+xml; charset=UTF-8');
  43. my $rss = qq{<?xml version="1.0" encoding="UTF-8"?>
  44. <rss version="2.0">
  45. <channel>
  46. <title>ChangeLog</title>
  47. <description>RSS feed automatically extracted from a ChangeLog file.</description>
  48. <link>$url</link>
  49. };
  50. my $ua = new LWP::UserAgent;
  51. my $response = $ua->get($url);
  52. die $response->status_line unless $response->is_success;
  53. my $data = $response->content;
  54. my $limit = $q->param('limit') || 15;
  55. my ($date, $author, $file, $log, $count);
  56. foreach my $line (split(/\n/, $data)) {
  57. # print "----\n$line\n----\n";
  58. if ($line =~ m/^(\d\d\d\d-\d\d-\d\d)\s*(.*)/) {
  59. output($date, $author, $file, $log);
  60. $date = $1;
  61. $author = $2;
  62. $file = '';
  63. $log = '';
  64. } elsif ($line =~ m|^\t\* ([a-zA-Z0-9./-]+)(.*)|) {
  65. last if ++$count > $limit;
  66. output($date, $author, $file, $log);
  67. $file = $1;
  68. $log = $2;
  69. } else {
  70. $log .= "\n" . $line;
  71. }
  72. }
  73. output($date, $author, $file, $log) if $file or $log;
  74. $rss .= q{
  75. </channel>
  76. </rss>
  77. };
  78. print $rss;
  79. sub output {
  80. my ($date, $author, $file, $log) = @_;
  81. return unless $file;
  82. $date = to_date($date);
  83. $author = quote_html($author);
  84. $log =~ s|^\t||mg; # strip leading tabs on every line
  85. $log =~ s|\)\n\(|, |g; # fix weird continuation groups
  86. # add linebreaks and highlighting for parentheses
  87. $log =~ s|\((.*?)\):|</span><span class="chunk"><br />(<strong>$1</strong>):|g;
  88. $log =~ s|^ *<br />||; # strip first linebreak, if there is one
  89. $log = quote_html($q->span({-class=>"chunk"}, $log));
  90. my $link = $pattern;
  91. $link =~ s/\%s/$file/g or $link .= $file;
  92. $rss .= "<item>\n";
  93. $rss .= "<author>$author</author>\n" if $author;
  94. $rss .= "<pubDate>$date</pubDate>\n" if $date;
  95. $rss .= "<title>$file</title>\n" if $file;
  96. $rss .= "<link>$link</link>\n" if $link;
  97. $rss .= "<description>$log</description>\n" if $log;
  98. $rss .= "</item>\n\n";
  99. }
  100. sub to_date {
  101. $_ = shift;
  102. my ($year, $month, $day) = split(/-/);
  103. # Wed, 02 Oct 2002 00:00:00 GMT
  104. return strftime("%a, %d %b %Y 00:00:00 GMT",
  105. 0, 0, 0, $day, $month - 1, $year - 1900);
  106. }
  107. sub quote_html {
  108. $_ = shift;
  109. s/&/&amp;/g;
  110. s/</&lt;/g;
  111. s/>/&gt;/g;
  112. s/&amp;([#a-zA-Z0-9]+);/&$1;/g; # Allow character references
  113. return $_;
  114. }