2 # Freshmeat.pl: Frontend to www.freshmeat.net
4 # Version: v0.7d (20000923)
12 ### download compressed version instead?
15 'public' => 'http://www.freshmeat.net/backend/appindex.txt',
16 'private' => 'http://feed.freshmeat.net/appindex/appindex.txt',
20 # Usage: &Freshmeat($string);
23 my $refresh = $main::param{'freshmeatRefreshInterval'} * 60 * 60;
25 my $last_refresh = &main::dbGet("freshmeat", "name","_","stable");
28 if (defined $last_refresh) {
29 $renewtable++ if (time() - $last_refresh > $refresh);
33 $renewtable++ if (&main::countKeys("freshmeat") < 10);
35 if ($renewtable and $$ == $main::bot_pid) {
36 &main::Forker("freshmeat", sub {
40 # both parent/fork runs here, in case the following looks weird.
41 return if ($$ == $main::bot_pid);
44 if (!&showPackage($sstr)) { # no exact match.
45 my $start_time = &main::timeget();
48 # search by key/NAME first.
49 foreach (&main::searchTable("freshmeat", "name","name",$sstr)) {
50 $hash{$_} = 1 unless exists $hash{$_};
53 # search by description line.
54 foreach (&main::searchTable("freshmeat", "name","oneliner", $sstr)) {
55 $hash{$_} = 1 unless exists $hash{$_};
56 last if (scalar keys %hash > 15);
59 my @list = keys %hash;
60 # search by value, if we have enough room to do it.
61 if (scalar @list == 1) {
62 &main::status("only one match found; showing full info.");
63 &showPackage($list[0]);
67 # show how long it took.
68 my $delta_time = &main::timedelta($start_time);
69 &main::status(sprintf("freshmeat: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
73 s/([\,\;]+)/\037$1\037/g;
76 &main::performStrictReply( &main::formListReply(1, "Freshmeat ", @list) );
82 my @fm = &main::dbGet("freshmeat", "name",$pkg,"*");
84 if (scalar @fm) { #1: perfect match of name.
86 $retval = "$fm[0] \002(\002$fm[11]\002)\002, ";
87 $retval .= "section $fm[3], ";
88 $retval .= "is $fm[4]. ";
89 $retval .= "Stable: \002$fm[1]\002, ";
90 $retval .= "Development: \002$fm[2]\002. ";
91 $retval .= $fm[5] || $fm[6]; # fallback to 'download'.
92 $retval .= " deb: ".$fm[8] if ($fm[8] ne ""); # 'deb'.
93 &main::performStrictReply($retval);
101 my $start_time = &main::timeget(); # set the start time.
102 my $idx = "$main::param{tempDir}/fm_index.txt";
104 &main::msg($main::who, "Updating freshmeat index... please wait");
106 if (&main::isStale($idx, 1)) {
107 &main::status("Freshmeat: fetching data.");
108 foreach (keys %urls) {
109 my $retval = &main::getURLAsFile($urls{$_}, $idx);
110 next if ($retval =~ /^(403|500)$/);
112 &main::DEBUG("FM: last! retval => '$retval'.");
116 &main::status("Freshmeat: local file hack.");
120 &main::msg($main::who, "the freshmeat butcher is closed.");
124 if ( -s $idx < 100000) {
125 &main::DEBUG("FM: index too small?");
127 &main::msg($main::who, "internal error?");
131 if ($idx =~ /bz2$/) {
132 open(IN, "bzcat $idx |");
133 } elsif ($idx =~ /gz$/) {
134 open(IN, "gzcat $idx |");
139 # delete the table before we redo it.
140 &main::deleteTable("freshmeat");
142 ### lets get on with business.
143 # set the last refresh time. fixes multiple spawn bug.
144 &main::dbSet("freshmeat", "name","_","stable",time());
147 while (my $line = <IN>) {
149 $i++ if ($line eq "%%");
153 &main::dbRaw("LOCK", "LOCK TABLES freshmeat WRITE");
156 while (my $line = <IN>) {
163 if ($i % 200 == 0 and $i != 0) {
164 &main::DEBUG("FM: unlocking and locking.");
165 &main::dbRaw("UNLOCK", "UNLOCK TABLES");
166 ### another lame hack to "prevent" errors.
167 select(undef, undef, undef, 0.2);
168 &main::dbRaw("LOCK", "LOCK TABLES freshmeat WRITE");
171 if (grep /^\Q$data[0]\E$/, @done) {
172 &main::DEBUG("dupe? $data[0]");
181 &main::dbSetRow("freshmeat", @data);
182 push(@done,$data[0]);
186 &main::DEBUG("FM: data ".scalar(@data) );
187 &main::dbRaw("UNLOCK", "UNLOCK TABLES");
189 my $delta_time = &main::timedelta($start_time);
190 &main::status(sprintf("Freshmeat: %.02f sec to complete.", $delta_time)) if ($delta_time > 0);
192 my $count = &main::countKeys("freshmeat");
193 &main::status("Freshmeat: $count entries loaded.");
196 sub freshmeatAnnounce {
197 my $file = "$main::param{tempDir}/fm_recent.txt";
200 ### if file exists, lets read it.
210 my @array = &main::getURL("http://core.freshmeat.net/backend/recentnews.txt");
214 my($what,$date,$url) = splice(@array,0,3);
218 ### if file does not exist, write new.
230 for(my $i=0; $i<scalar(@old); $i++) {
231 last if ($now[$i] eq $old[0]);
232 push(@new, $now[$i]);
236 &main::DEBUG("fA: no new items.");
241 my @chans = split(/[\s\t]+/, lc $main::param{'freshmeatAnnounce'});
242 @chans = keys(%main::channels) unless (scalar @chans);
244 my $line = "Freshmeat update: ".join(" \002::\002 ", @new);
246 next unless (&main::validChan($_));
248 &main::status("sending freshmeat update to $_.");
249 &main::notice($_, $line);