e3a038e521d953180f8b82704b190b4617f1e24a
[privoxy.git] / utils / create-package-feed.pl
1 #!/usr/local/bin/perl
2 #< LICENSE: WTFPL >
3 use warnings;
4 use strict;
5 use Digest::SHA;
6 my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
7 my @days   = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
8
9 my $base_dlurl = 'https://www.privoxy.org/sf-download-mirror/';
10 my $max_advertised_files = 100;
11
12 sub generate_rss_item($$$$) {
13     my ($target, $target_uri, $target_time, $target_sha256) = @_;
14
15     my $rss_item;
16     my $escaped_target_uri = $target_uri;
17     $escaped_target_uri =~ s@ @%20@g;
18
19     # RSS line
20     $rss_item =
21         '<item><title><![CDATA[' . $target_uri . ']]></title>';
22     $rss_item .=
23         '<description><![CDATA['
24         . $target_uri
25         . ' (SHA-256: '
26         . $target_sha256
27         . ')]]></description>';
28     $rss_item .=
29         '<link>'
30         . $base_dlurl
31         . $escaped_target_uri
32         . '</link><guid>'
33         . $base_dlurl
34         . $escaped_target_uri
35         . '</guid>';
36     $rss_item .= '<pubDate>';
37     my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
38         gmtime($target_time);
39     $rss_item .= sprintf("%s, %s %s %d %.2d:%.2d:%.2d GMT",
40                          $days[$wday], $mday, $months[$mon], ($year + 1900),
41                          $hour, $min, $sec);
42     $rss_item .= '</pubDate></item>';
43     $rss_item .= "\n";
44
45     return $rss_item;
46 }
47
48 sub get_sha256_sum($) {
49     my $file = shift;
50
51     open(my $fd, "<", $file)
52         or die "Can't open '$file' to generate checksum $!";
53     my $sha256 = Digest::SHA->new("SHA-256");
54     $sha256->addfile($fd);
55     close($fd);
56
57     return $sha256->hexdigest;
58 }
59
60 sub get_released_files($) {
61     my $scan_dir = shift;
62
63     my @Array = ();
64     my $i     = 0;
65     my $target;
66     my $target_sha256;
67     my $target_uri;
68     my $target_time;
69     my $target_line;
70
71     opendir(my $D1, $scan_dir) or die "Can't open 1st directory! /";
72     while (my $fi1 = readdir($D1)) {
73         next if ($fi1 =~ m/^\./);
74         next if ($fi1 eq 'OldFiles' or $fi1 eq 'pkgsrc');
75
76         opendir(my $D2, $scan_dir . $fi1 . '/')
77             or die "Can't open 2nd directory! /$fi1";
78         while (my $fi2 = readdir($D2)) {
79             next if ($fi2 =~ m/^\./);
80
81             # Start listing /OS/Version/FILE
82             opendir(my $D3, $scan_dir . $fi1 . '/' . $fi2 . '/')
83                 or die "Can't open 3rd directory! /$fi1/$fi2";
84             while (my $fi3 = readdir($D3)) {
85                 next if ($fi3 =~ m/^\./);
86                 $target = $scan_dir . $fi1 . '/' . $fi2 . '/' . $fi3;
87                 next if (!-e $target);    # skip if file is not exist
88
89                 $target_uri  = $fi1 . '/' . $fi2 . '/' . $fi3;
90                 $target_time = (stat $target)[9];
91
92                 $Array[$i] = ([$target_time, $target, $target_uri]);
93
94                 $i++;
95             }
96             closedir($D3);
97         }
98         closedir($D2);
99     }
100     closedir($D1);
101
102     return sort { @$a[0] <=> @$b[0] } @Array;
103 }
104
105 sub generate_feed($) {
106     my $scan_dir = shift;
107
108     # Result = Full XML Codes
109     my $result = '<?xml version="1.0" encoding="utf-8"?>
110  <rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
111   <channel>
112    <title>Privoxy Releases</title>
113    <link>https://www.privoxy.org/announce.txt</link>
114    <description><![CDATA[Privoxy Releases RSS feed]]></description>
115    <pubDate>';
116     my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = gmtime();
117     $result .=
118         "$days[$wday], $mday $months[$mon] "
119         . ($year + 1900)
120         . " $hour:$min:$sec GMT";
121     $result .= '</pubDate>';
122     $result .= "\n";
123
124     my @resArray = get_released_files($scan_dir);
125     my $i = @resArray - 1;
126     while ($max_advertised_files-- > 0 && $i >= 0) {
127         my $target_time =  $resArray[$i][0];
128         my $target = $resArray[$i][1];
129         my $target_uri =  $resArray[$i][2];
130
131         my $target_sha256 = get_sha256_sum($target);
132
133         my $rss_item = generate_rss_item($target, $target_uri, $target_time, $target_sha256);
134
135         $result .= $rss_item;
136         $i--;
137     }
138     $result .= '  </channel>
139    </rss>';
140
141     return $result;
142 }
143
144 sub main() {
145     my $scan_dir = shift(@ARGV)
146         or die "Local package directory not specified (first argument)\n";
147     my $save_rss_file = shift(@ARGV)
148         or die "RSS output file path not specified (second argument)\n";
149
150     my $result = generate_feed($scan_dir);
151
152     open(my $XMLF, ">", $save_rss_file) or die "Failed to write XML file";
153     print $XMLF $result;
154     close($XMLF);
155 }
156
157 main();