CVS: blootbot/old Freshmeat_I.pl,NONE,1.1 Freshmeat_II.pl,NONE,1.1 News.pl,NONE,1.1 dbm.pl,NONE,1.1
Brought to you by:
timriker
From: David <dm...@us...> - 2002-11-28 12:28:21
|
Update of /cvsroot/blootbot/blootbot/old In directory sc8-pr-cvs1:/tmp/cvs-serv27181/old Added Files: Freshmeat_I.pl Freshmeat_II.pl News.pl dbm.pl Log Message: - move unuseable files to old/ - Freshmeat is gone because fm ][ is lacking in info - Freshmeat I is kept for historical value. - dbm.pl is kept for historical value. --- NEW FILE: Freshmeat_I.pl --- # # Freshmeat.pl: Frontend to www.freshmeat.net # Author: dms # Version: v0.7d (20000923) # Created: 19990930 # package Freshmeat; use strict; ### download compressed version instead? my %urls = ( 'public' => 'http://www.freshmeat.net/backend/appindex.txt', 'private' => 'http://feed.freshmeat.net/appindex/appindex.txt', ); #### # Usage: &Freshmeat($string); sub Freshmeat { my $sstr = lc($_[0]); my $refresh = &::getChanConfDefault("freshmeatRefreshInterval", "", 24) * 60 * 60; my $last_refresh = &::dbGet("freshmeat", "name","_","stable"); my $renewtable = 0; if (defined $last_refresh) { $renewtable++ if (time() - $last_refresh > $refresh); } else { $renewtable++; } $renewtable++ if (&::countKeys("freshmeat") < 10); if ($renewtable and $$ == $::bot_pid) { &::Forker("freshmeat", sub { &downloadIndex(); &Freshmeat($sstr); } ); # both parent/fork runs here, in case the following looks weird. return if ($$ == $::bot_pid); } if (!&showPackage($sstr)) { # no exact match. my $start_time = &::timeget(); my %hash; # search by key/NAME first. foreach (&::searchTable("freshmeat", "name","name",$sstr)) { $hash{$_} = 1 unless exists $hash{$_}; } # search by description line. foreach (&::searchTable("freshmeat", "name","oneliner", $sstr)) { $hash{$_} = 1 unless exists $hash{$_}; last if (scalar keys %hash > 15); } my @list = keys %hash; # search by value, if we have enough room to do it. if (scalar @list == 1) { &::status("only one match found; showing full info."); &showPackage($list[0]); return; } # show how long it took. my $delta_time = &::timedelta($start_time); &::status(sprintf("freshmeat: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0); for (@list) { tr/A-Z/a-z/; s/([\,\;]+)/\037$1\037/g; } &::performStrictReply( &::formListReply(1, "Freshmeat ", @list) ); } } sub showPackage { my ($pkg) = @_; my @fm = &::dbGet("freshmeat", "name",$pkg,"*"); if (scalar @fm) { #1: perfect match of name. my $retval; $retval = "$fm[0] \002(\002$fm[11]\002)\002, "; $retval .= "section $fm[3], "; $retval .= "is $fm[4]. "; $retval .= "Stable: \002$fm[1]\002, "; $retval .= "Development: \002$fm[2]\002. "; $retval .= $fm[5] || $fm[6]; # fallback to 'download'. $retval .= " deb: ".$fm[8] if ($fm[8] ne ""); # 'deb'. &::performStrictReply($retval); return 1; } else { return 0; } } sub randPackage { my @fm = &::randKey("freshmeat","*"); if (scalar @fm) { #1: perfect match of name. my $retval; $retval = "$fm[0] \002(\002$fm[11]\002)\002, "; $retval .= "section $fm[3], "; $retval .= "is $fm[4]. "; $retval .= "Stable: \002$fm[1]\002, "; $retval .= "Development: \002$fm[2]\002. "; $retval .= $fm[5] || $fm[6]; # fallback to 'download'. $retval .= " deb: ".$fm[8] if ($fm[8] ne ""); # 'deb'. return $retval; } else { return; } } sub downloadIndex { my $start_time = &::timeget(); # set the start time. my $idx = "$::param{tempDir}/fm_index.txt"; &::msg($::who, "Updating freshmeat index... please wait"); if (&::isStale($idx, 1)) { &::status("Freshmeat: fetching data."); foreach (keys %urls) { my $retval = &::getURLAsFile($urls{$_}, $idx); next if ($retval =~ /^(403|500)$/); &::DEBUG("FM: last! retval => '$retval'."); last; } } else { &::status("Freshmeat: local file hack."); } if (! -e $idx) { &::msg($::who, "the freshmeat butcher is closed."); return; } if ( -s $idx < 100000) { &::DEBUG("FM: index too small?"); unlink $idx; &::msg($::who, "internal error?"); return; } if ($idx =~ /bz2$/) { open(IN, "bzcat $idx |"); } elsif ($idx =~ /gz$/) { open(IN, "gzcat $idx |"); } else { open(IN, $idx); } # delete the table before we redo it. &::deleteTable("freshmeat"); ### lets get on with business. # set the last refresh time. fixes multiple spawn bug. &::dbSet("freshmeat", "name","_","stable",time()); my $i = 0; while (my $line = <IN>) { chop $line; $i++ if ($line eq "%%"); last if ($i == 2); } &::dbRaw("LOCK", "LOCK TABLES freshmeat WRITE"); my @data; my @done; while (my $line = <IN>) { chop $line; if ($line ne "%%") { push(@data,$line); next; } if ($i % 200 == 0 and $i != 0) { &::DEBUG("FM: unlocking and locking."); &::dbRaw("UNLOCK", "UNLOCK TABLES"); ### another lame hack to "prevent" errors. select(undef, undef, undef, 0.2); &::dbRaw("LOCK", "LOCK TABLES freshmeat WRITE"); } if (grep /^\Q$data[0]\E$/, @done) { &::DEBUG("dupe? $data[0]"); @data = (); next; } $i++; pop @data; $data[1] ||= "none"; $data[2] ||= "none"; &::dbSetRow("freshmeat", @data); push(@done,$data[0]); @data = (); } close IN; &::DEBUG("FM: data ".scalar(@data) ); &::dbRaw("UNLOCK", "UNLOCK TABLES"); my $delta_time = &::timedelta($start_time); &::status(sprintf("Freshmeat: %.02f sec to complete.", $delta_time)) if ($delta_time > 0); my $count = &::countKeys("freshmeat"); &::status("Freshmeat: $count entries loaded."); } sub freshmeatAnnounce { my $file = "$::param{tempDir}/fm_recent.txt"; my @old; ### if file exists, lets read it. if ( -f $file) { open(IN, $file); while (<IN>) { chop; push(@old,$_); } close IN; } my @array = &::getURL("http://core.freshmeat.net/backend/recentnews.txt"); my @now; while (@array) { my($what,$date,$url) = splice(@array,0,3); push(@now, $what); } ### if file does not exist, write new. if (! -f $file) { open(OUT, ">$file"); foreach (@now) { print OUT "$_\n"; } close OUT; return; } my @new; for(my $i=0; $i<scalar(@old); $i++) { last if ($now[$i] eq $old[0]); push(@new, $now[$i]); } if (!scalar @new) { &::DEBUG("fA: no new items."); return; } ### output new file. open(OUT, ">$file"); foreach (@now) { print OUT "$_\n"; } close OUT; return "Freshmeat update: ".join(" \002::\002 ", @new); } 1; --- NEW FILE: Freshmeat_II.pl --- # # Freshmeat.pl: Frontend to www.freshmeat.net # Author: dms # Version: v0.7d (20000923) # Created: 19990930 # package Freshmeat; use strict; use vars qw(@cols @data $string %pkg $i $locktime); my %urls = ( 'public' => 'http://www.freshmeat.net/backend/fm-projects.rdf.bz2', # 'private' => 'http://feed.freshmeat.net/appindex/appindex.txt', ); #### # Usage: &Freshmeat($string); sub Freshmeat { my $sstr = lc($_[0]); my $refresh = &::getChanConfDefault("freshmeatRefreshInterval", "", 24) * 60 * 60 * 7; my $last_refresh = &::dbGet("freshmeat", "latest_version", "projectname_short=".&::dbQuote('_')); my $renewtable = 0; if (defined $last_refresh and $last_refresh =~ /^\d+$/) { $renewtable++ if (time() - $last_refresh > $refresh); } else { $renewtable++; } $renewtable++ if (&::countKeys("freshmeat") < 1000); if ($renewtable) { if ($$ == $::bot_pid) { &::Forker("freshmeat", sub { &Freshmeat($sstr) if &downloadIndex(); } ); # both parent/fork runs here, in case the following looks weird. } else { &downloadIndex(); } return if ($$ == $::bot_pid); } if (!&showPackage($sstr)) { # no exact match. my $start_time = &::timeget(); my %hash; # search by key/NAME first. foreach (&::searchTable("freshmeat", "projectname_short", "projectname_short",$sstr)) { $hash{$_} = 1 unless exists $hash{$_}; } # search by description line. foreach (&::searchTable("freshmeat", "projectname_short", "desc_short", $sstr)) { $hash{$_} = 1 unless exists $hash{$_}; last if (scalar keys %hash > 15); } my @list = keys %hash; # search by value, if we have enough room to do it. if (scalar @list == 1) { &::status("only one match found; showing full info."); &showPackage($list[0]); return; } # show how long it took. my $delta_time = &::timedelta($start_time); &::status(sprintf("freshmeat: %.02f sec to complete query.", $delta_time)) if ($delta_time > 0); for (@list) { tr/A-Z/a-z/; s/([\,\;]+)/\037$1\037/g; } &::performStrictReply( &::formListReply(1, "Freshmeat ", @list) ); } } sub packageText { my ($pkg) = @_; my %fm = &::dbGetColNiceHash("freshmeat", "*", "projectname_short=".&::dbQuote($pkg)); if (scalar keys %fm) { #1: perfect match of name. my $retval; $retval = "$fm{'projectname_short'} \002(\002$fm{'desc_short'}\002)\002, "; $retval .= "is $fm{'license'}. "; $retval .= "Version: \002$fm{'latest_version'}\002, $fm{'url_homepage'}"; return $retval; } else { return; } } sub showPackage { my ($pkg) = @_; my ($retval); if ($retval = packageText($pkg)) { &::performStrictReply($retval); return 1; } else { return 0; } } sub randPackage { my @fm = &::randKey("freshmeat","*"); return &packageText($fm[0]); } sub downloadIndex { my $start_time = &::timeget(); # set the start time. my $idx = "$::param{tempDir}/fm-projects.rdf.bz2"; if (!&::loadPerlModule("XML::Parser")) { &::WARN("don't have xml::parser..."); return 0; } my $p = new XML::Parser(Style => 'Objects'); my %pkg; my $string; $p->setHandlers( Char => \&xml_text, End => \&xml_end, ); &::msg($::who, "Updating freshmeat index... please wait"); if (&::isStale($idx, 1)) { &::status("Freshmeat: fetching data."); foreach (keys %urls) { $urls{$_} =~ /^.*\/(.*)$/; $idx = "$::param{tempDir}/$1"; my $retval = &::getURLAsFile($urls{$_}, $idx); next if ($retval =~ /^(403|500)$/); &::DEBUG("FM: last! retval => '$retval'."); last; } } else { &::status("Freshmeat: local file hack."); } if (! -e $idx) { &::msg($::who, "the freshmeat butcher is closed."); return 0; } if ( -s $idx < 100000) { &::DEBUG("FM: index too small?"); unlink $idx; &::msg($::who, "internal error?"); return 0; } if ($idx =~ /bz2$/) { open(IN, "bzcat $idx |"); } elsif ($idx =~ /gz$/) { open(IN, "gzcat $idx |"); } else { open(IN, $idx); } # delete the table before we redo it. &::deleteTable("freshmeat"); ### lets get on with business. # set the last refresh time. fixes multiple spawn bug. &::dbSet("freshmeat", { "projectname_short" => "_" }, { "latest_version" => time(), "desc_short" => "dummy project to track date" } ); # &::dbRaw("LOCK", "LOCK TABLES freshmeat WRITE"); @cols = &::dbGetColInfo("freshmeat"); $locktime = time(); # this mess is to not dump IN to memory. $_ = <IN>; $_ = <IN>; $_ = <IN>; my $str; while (<IN>) { chop; $str .= $_; next unless (/<\/project>/); # XML::Parser's parse() doesn't like the following. # but parsefile() does... why! for ($str) { s/®/_/g; s/ô//g; s/"//g; s/é/e/g; s/à/a/g; s/í/i/g; s/­/_/g; # ??? s/´/a/g; s/»/_/g; # ??? s/«/_/g; # ??? s/©/[C]/g; s/°/deg/g; s/Æ/A/g; s/\cN//g; # fucking openbsd morons. s/ /-/g; s/ö/o/g; s/¶//g; # ??? s/ã//g; s/\cM/ /g; # stupid windows morons s/²/square/g; s/ü/?/g; s/µ/u/g; s/æ/a/g; s/ø/o/g; s/ð/e/g; s/ß//g; s/·//g; } if (0 and $str =~ s/\&(\S+?);//g) { &::DEBUG("fm: sarred $1 to ''."); } $p->parse($str, ProtocolEncoding => 'ISO-8859-1'); $str = ""; } close IN; # &::dbRaw("UNLOCK", "UNLOCK TABLES"); my $delta_time = &::timedelta($start_time); &::status(sprintf("Freshmeat: %.02f sec to complete.", $delta_time)) if ($delta_time > 0); my $count = &::countKeys("freshmeat"); &::status("Freshmeat: $count entries loaded."); return 1; } sub freshmeatAnnounce { my $file = "$::param{tempDir}/fm_recent.txt"; my @old; ### if file exists, lets read it. if ( -f $file) { open(IN, $file); while (<IN>) { chop; push(@old,$_); } close IN; } my @array = &::getURL("http://core.freshmeat.net/backend/recentnews.txt"); my @now; while (@array) { my($what,$date,$url) = splice(@array,0,3); push(@now, $what); } ### if file does not exist, write new. if (! -f $file) { open(OUT, ">$file"); foreach (@now) { print OUT "$_\n"; } close OUT; return; } my @new; for(my $i=0; $i<scalar(@old); $i++) { last if ($now[$i] eq $old[0]); push(@new, $now[$i]); } if (!scalar @new) { &::DEBUG("fA: no new items."); return; } ### output new file. open(OUT, ">$file"); foreach (@now) { print OUT "$_\n"; } close OUT; return "Freshmeat update: ".join(" \002::\002 ", @new); } sub xml_text { my ($e,$t) = @_; return if ($t =~ /^\s*$/); $string = $t; } sub xml_end { my($expat,$text) = @_; $pkg{$text} = $string; if ($expat->depth == 0) { # old code. if (0) { for (my $j=0; $j<scalar @cols; $j++) { $data[$j] = $pkg{ $cols[$j] }; } $i++; &::dbSetRow("freshmeat", [@data], "DELAY"); undef @data; } # new code. $i++; my %data; foreach(@cols) { $data{$_} = $pkg{$_} if ($pkg{$_}); } &::dbReplace("freshmeat", "projectname_short", %data); undef %data; # end of new code. undef %pkg; if ($i % 200 == 0 and $i != 0) { &::showProc(); &::status("FM: unlocking and locking ($i): ". &::Time2String( time() - $locktime ) ); $locktime = time(); # I think the following leaks 120k of memory each time it's # called... the wonders of libmysql-perl leaking! # &::dbRaw("UNLOCK", "UNLOCK TABLES"); ### another lame hack to "prevent" errors. # select(undef, undef, undef, 0.2); # &::dbRaw("LOCK", "LOCK TABLES freshmeat WRITE"); } } } 1; --- NEW FILE: News.pl --- # # News.pl: Advanced news management # Author: dms # Version: v0.3 (20010412) # Created: 20010326 # Notes: Testing done by greycat, kudos! # ### structure: # news{ channel }{ string } { item } # newsuser{ channel }{ user } = time() ### where item is: # Time - when it was added (used for sorting) # Author - Who by. # Expire - Time to expire. # Text - Actual text. ### package News; [...992 lines suppressed...] } &::DEBUG("news: stats: total user cache => $i"); $i = 0; # average latest time read. my $t = time(); foreach $chan (keys %::newsuser) { $i += $t - $::newsuser{$chan}{$_}; &::DEBUG(" i = $i"); $j++; } &::DEBUG("news: stats: average latest time read: total time: $i"); &::DEBUG("news: ... count: $j"); &::DEBUG("news: average: ".sprintf("%.02f", $i/($j||1))." sec/user"); $i = $j = 0; } sub AUTOLOAD { &::AUTOLOAD(@_); } 1; --- NEW FILE: dbm.pl --- # # dbm.pl: Extension on the factoid database. # OrigAuthor: Kevin Lenzo (c) 1997 # CurrAuthor: dms <dm...@us...> # Version: v0.6 (20000707) # FModified: 19991020 # use strict; package main; use vars qw(%factoids %param); { my %formats = ( 'factoids', [ 'factoid_key', 'factoid_value', 'created_by', 'created_time', 'modified_by', 'modified_time', 'requested_by', 'requested_time', 'requested_count', 'locked_by', 'locked_time' ], 'freshmeat', [ 'projectname_short', 'latest_version', 'license', 'url_homepage', 'desc_short' ], 'rootwarn', [ 'nick', 'attempt', 'time', 'host', 'channel' ], 'seen', [ 'nick', 'time', 'channel', 'host', 'messagecount', 'hehcount', 'karma', 'message' ], 'stats', [ 'nick', 'type', 'counter', 'time' ] ); sub openDB { use DB_File; foreach (keys %formats) { next unless (&IsParam($_)); my $file = "$param{'DBName'}-$_"; if (dbmopen(%{ $_ }, $file, 0666)) { &status("Opened DBM $_ ($file)."); } else { &ERROR("Failed open to DBM $_ ($file)."); &shutdown(); exit 1; } } } sub closeDB { foreach (keys %formats) { next unless (&IsParam($_)); if (dbmclose(%{ $_ })) { &status("Closed DBM $_ successfully."); next; } &ERROR("Failed closing DBM $_."); } } ##### # Usage: &dbGetColInfo($table); sub dbGetColInfo { my ($table) = @_; if (scalar @{$formats{$table}}) { return @{$formats{$table}}; } else { &ERROR("dbGCI: no format for table ($table)."); return; } } } ##### # Usage: &dbQuote($str); sub dbQuote { return $_[0]; } ##### # Usage: &dbGet($table, $select, $where); sub dbGet { my ($table, $select, $where) = @_; my ($key, $val) = split('=',$where) if $where =~ /=/; my $found = 0; my @retval; my $i; &DEBUG("dbGet($table, $select, $where);"); return unless $key; my @format = &dbGetColInfo($table); if (!scalar @format) { return; } if (!defined ${ "$table" }{lc $val}) { # dbm hash exception. &DEBUG("dbGet: '$val' does not exist in $table."); return; } # return the whole row. if ($select eq "*") { @retval = split $;, ${"$table"}{lc $val}; unshift(@retval,$key); return(@retval); } &DEBUG("dbGet: select=>'$select'."); my @array = split "$;", ${"$table"}{lc $val}; unshift(@array,$val); for (0 .. $#format) { my $str = $format[$_]; next unless (grep /^$str$/, split(/\,/, $select)); $array[$_] ||= ''; &DEBUG("dG: '$format[$_]'=>'$array[$_]'."); push(@retval, $array[$_]); } if (scalar @retval > 1) { return @retval; } elsif (scalar @retval == 1) { return $retval[0]; } else { return; } } ##### # Usage: &dbGetCol(); # Usage: &dbGetCol($table, $select, $where, [$type]); sub dbGetCol { my ($table, $select, $where, $type) = @_; &FIXME("STUB: &dbGetCol($table, $select, $where, $type);"); } ##### # Usage: &dbGetColNiceHash($table, $select, $where); sub dbGetColNiceHash { my ($table, $select, $where) = @_; &DEBUG("dbGetColNiceHash($table, $select, $where);"); my ($key, $val) = split('=',$where) if $where =~ /=/; return unless ${$table}{lc $val}; my (%hash) = (); $hash{lc $key} = $val; my (@format) = &dbGetColInfo($table); shift @format; @hash{@format} = split $;, ${$table}{lc $val}; return %hash; } ##### # Usage: &dbInsert($table, $primkey, %hash); # Note: dbInsert should do dbQuote. sub dbInsert { my ($table, $primkey, %hash) = @_; my $found = 0; &DEBUG("dbInsert($table, $primkey, ...)"); my $info = ${$table}{lc $primkey} || ''; # primkey or primval? my @format = &dbGetColInfo($table); if (!scalar @format) { return 0; } my $i; my @array = split $;, $info; delete $hash{$format[0]}; for $i (1 .. $#format) { my $col = $format[$i]; $array[$i - 1]=$hash{$col}; $array[$i - 1]='' unless $array[$i - 1]; delete $hash{$col}; &DEBUG("dbI: '$col'=>'$array[$i - 1]'"); } if (scalar keys %hash) { &ERROR("dbI: not added..."); foreach (keys %hash) { &ERROR("dbI: '$_'=>'$hash{$_}'"); } return 0; } ${$table}{lc $primkey} = join $;, @array; return 1; } sub dbUpdate { &FIXME("STUB: &dbUpdate(@_);=>somehow use dbInsert!"); } ##### # Usage: &dbSetRow($table, @values); sub dbSetRow { my ($table, @values) = @_; &DEBUG("dbSetRow(@_);"); my $key = lc $values[0]; my @format = &dbGetColInfo($table); if (!scalar @format) { return 0; } if (defined ${$table}{$key}) { &WARN("dbSetRow: $table {$key} already exists?"); } if (scalar @values != scalar @format) { &WARN("dbSetRow: scalar values != scalar ${table} format."); } for (0 .. $#format) { # @array? this is not defined anywhere. please fix, timriker!!! if (defined $array[$_] and $array[$_] ne "") { &DEBUG("dbSetRow: array[$_] != NULL($array[$_])."); } $array[$_] = $values[$_]; } ${$table}{$key} = join $;, @array; } ##### # Usage: &dbDel($table, $primkey, $primval, [$key]); sub dbDel { my ($table, $primkey, $primval, $key) = @_; &DEBUG("dbDel($table, $primkey, $primval);"); if (!defined ${$table}{lc $primval}) { &DEBUG("dbDel: lc $primval does not exist in $table."); } else { delete ${$table}{lc $primval}; } return ''; } ##### # Usage: &dbReplace($table, $key, %hash); # Note: dbReplace does optional dbQuote. sub dbReplace { my ($table, $key, %hash) = @_; &DEBUG("dbReplace($table, $key, %hash);"); &dbDel($table, $key, $hash{$key}, %hash); &dbInsert($table, $hash{$key}, %hash); return 1; } ##### # Usage: &dbSet($table, $primhash_ref, $hash_ref); sub dbSet { my ($table, $phref, $href) = @_; &DEBUG("dbSet(@_)"); my ($key) = keys %{$phref}; my $where = $key . "=" . $phref->{$key}; my %hash = &dbGetColNiceHash($table, "*", $where); $hash{$key}=$phref->{$key}; foreach (keys %{$href}) { &DEBUG("dbSet: setting $_=${$href}{$_}"); $hash{$_} = ${$href}{$_}; } &dbReplace($table, $key, %hash); return 1; } sub dbRaw { &FIXME("STUB: &dbRaw(@_);"); } sub dbRawReturn { &FIXME("STUB: &dbRawReturn(@_);"); } #################################################################### ##### Factoid related stuff... ##### sub countKeys { return scalar keys %{$_[0]}; } sub getKeys { &FIXME("STUB: &getKeys(@_); -- REDUNDANT"); } sub randKey { &DEBUG("STUB: &randKey(@_);"); my ($table, $select) = @_; my @format = &dbGetColInfo($table); if (!scalar @format) { return; } my $rand = int(rand(&countKeys($table) - 1)); my @keys = keys %{$table}; &dbGet($table, '$select', "$format[0]=$keys[$rand]"); } ##### # Usage: &deleteTable($table); sub deleteTable { my ($table) = @_; &FIXME("STUB: deleteTable($table)"); } ##### $select is misleading??? # Usage: &searchTable($table, $returnkey, $primkey, $str); sub searchTable { my ($table, $primkey, $key, $str) = @_; &FIXME("STUB: searchTable($table, $primkey, $key, $str)"); return; &DEBUG("searchTable($table, $primkey, $key, $str)"); if (!scalar &dbGetColInfo($table)) { return; } my @results; foreach (keys %{$table}) { my $val = &dbGet($table, "NULL", $_, $key) || ''; next unless ($val =~ /\Q$str\E/); push(@results, $_); } &DEBUG("sT: ".scalar(@results) ); @results; } ##### # Usage: &getFactInfo($faqtoid, $type); sub getFactInfo { my ($faqtoid, $type) = @_; my @format = &dbGetColInfo("factoids"); if (!scalar @format) { return; } if (!defined $factoids{$faqtoid}) { # dbm hash exception. return; } if ($type eq "*") { # all. return split /$;/, $factoids{$faqtoid}; } # specific. if (!grep /^$type$/, @format) { &ERROR("gFI: type '$type' not valid for factoids."); return; } my @array = split /$;/, $factoids{$faqtoid}; for (0 .. $#format) { next unless ($type eq $format[$_]); return $array[$_]; } &ERROR("gFI: should never happen."); } ##### # Usage: &getFactoid($faqtoid); sub getFactoid { my ($faqtoid) = @_; if (!defined $faqtoid or $faqtoid =~ /^\s*$/) { &WARN("getF: faqtoid == NULL."); return; } if (defined $factoids{$faqtoid}) { # dbm hash exception. # we assume 1 unfortunately. ### TODO: use &getFactInfo() instead? my $retval = (split $;, $factoids{$faqtoid})[1]; if (defined $retval) { &DEBUG("getF: returning '$retval' for '$faqtoid'."); } else { &DEBUG("getF: returning NULL for '$faqtoid'."); } return $retval; } else { return; } } ##### # Usage: &delFactoid($faqtoid); sub delFactoid { my ($faqtoid) = @_; if (!defined $faqtoid or $faqtoid =~ /^\s*$/) { &WARN("delF: faqtoid == NULL."); return; } if (defined $factoids{$faqtoid}) { # dbm hash exception. delete $factoids{$faqtoid}; &status("DELETED $faqtoid"); } else { &WARN("delF: nothing to deleted? ($faqtoid)"); return; } } sub checkTables { # nothing - DB_FIle will create them on openDB() } 1; |