2 # Freshmeat.pl: Frontend to www.freshmeat.net
4 # Version: v0.7c (20000606)
12 ### download compressed version instead?
15 'public' => 'http://core.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::infobot_pid) {
36 &main::Forker("freshmeat", sub {
40 return if ($$ == $main::infobot_pid);
43 if (!&showPackage($sstr)) { # no exact match.
44 my $start_time = &main::gettimeofday();
47 # search by key first.
48 foreach (&main::searchTable("freshmeat", "name","name",$sstr)) {
49 $hash{$_} = 1 unless exists $hash{$_};
52 foreach (&main::searchTable("freshmeat", "name","oneliner", $sstr)) {
53 $hash{$_} = 1 unless exists $hash{$_};
54 last if (scalar keys %hash > 15);
57 my @list = keys %hash;
58 # search by value, if we have enough room to do it.
59 if (scalar @list == 1) {
60 &main::DEBUG("only one partial match found; showing full info.");
61 &showPackage($list[0]);
65 # show how long it took.
66 my $delta_time = &main::gettimeofday() - $start_time;
67 &main::status(sprintf("freshmeat: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0);
71 s/([\,\;]+)/\037$1\037/g;
74 &main::performStrictReply( &main::formListReply(1, "Freshmeat ", @list) );
80 my @fm = &main::dbGet("freshmeat", "name",$pkg,"*");
82 if (scalar @fm) { #1: perfect match of name.
84 $retval = "$fm[0] \002(\002$fm[11]\002)\002, ";
85 $retval .= "section $fm[3], ";
86 $retval .= "is $fm[4]. ";
87 $retval .= "Stable: \002$fm[1]\002, ";
88 $retval .= "Development: \002$fm[2]\002. ";
89 $retval .= $fm[5] || $fm[6]; # fallback to 'download'.
90 $retval .= " deb: ".$fm[8] if ($fm[8] ne ""); # 'deb'.
91 &main::performStrictReply($retval);
99 my $start_time = &main::gettimeofday(); # set the start time.
100 my $idx = "$main::infobot_base_dir/Temp/fm_index.txt";
102 &main::msg($main::who, "Updating freshmeat index... please wait");
104 if (&main::isStale($idx, 1)) {
105 &main::status("Freshmeat: fetching data.");
106 foreach (keys %urls) {
107 &main::DEBUG("FM: urls{$_} => '$urls{$_}'.");
108 my $retval = &main::getURLAsFile($urls{$_}, $idx);
109 next if ($retval eq "403");
110 &main::DEBUG("FM: last! retval => '$retval'.");
114 &main::status("Freshmeat: local file hack.");
118 &main::msg($main::who, "the freshmeat butcher is closed.");
122 if ( -s $idx < 100000) {
123 &main::DEBUG("FM: index too small?");
125 &main::msg($main::who, "internal error?");
129 ### TODO: do not dump full contents to an array.
130 ### => process on the fly instead but how?
133 # delete the table before we redo it.
134 &main::deleteTable("freshmeat");
136 ### lets get on with business.
137 # set the last refresh time. fixes multiple spawn bug.
138 &main::dbSet("freshmeat", "name","_","stable",time());
141 while (my $line = <IN>) {
143 $i++ if ($line eq "%%");
147 &main::dbRaw("LOCK", "LOCK TABLES freshmeat WRITE");
149 while (my $line = <IN>) {
156 if ($i % 100 == 0 and $i != 0) {
157 &main::DEBUG("FM: unlocking and locking.");
158 &main::dbRaw("UNLOCK", "UNLOCK TABLES");
159 sleep 1; # another lame hack to "prevent" errors.
160 &main::dbRaw("LOCK", "LOCK TABLES freshmeat WRITE");
167 &main::dbSetRow("freshmeat", @data);
171 &main::DEBUG("FM: data ".scalar(@data) );
172 &main::dbRaw("UNLOCK", "UNLOCK TABLES");
174 my $delta_time = &main::gettimeofday() - $start_time;
175 &main::status(sprintf("Freshmeat: %.02f sec to complete.", $delta_time)) if ($delta_time > 0);
177 my $count = &main::countKeys("freshmeat");
178 &main::status("Freshmeat: $count entries loaded.");
181 sub freshmeatAnnounce {
182 my $file = "$main::infobot_base_dir/Temp/fm_recent.txt";
194 my @array = &main::getURL("http://core.freshmeat.net/backend/recentnews.txt");
198 my($what,$date,$url) = splice(@array,0,3);
215 for(my $i=0; $i<scalar(@old); $i++) {
216 last if ($now[$i] eq $old[0]);
217 push(@new, $now[$i]);
221 &main::DEBUG("fA: no new items.");
226 my @chans = split(/[\s\t]+/, lc $main::param{'freshmeatAnnounce'});
227 @chans = keys(%main::channels) unless (scalar @chans);
229 my $line = "Freshmeat update: ".join(" \002::\002 ", @new);
231 next unless (&main::validChan($_));
233 &main::status("sending freshmeat update to $_.");
234 &main::notice($_, $line);