NAME Bot::CPAN - provides CPAN services via IRC SYNOPSIS use Bot::CPAN; my $bot = Bot::CPAN->new( channels => ['#cpan'], servers => ['irc.perl.org', 'irc.freenode.net'], port => 6667, nick => 'cpantest', alt_nicks => ['cpantest2', 'cpantest3'], username => 'cpantest', name => 'cpantest', nickserv_password => 'top_secret_password', ignore_list => [qw(purl)], news_server => 'nntp.perl.org', group => 'perl.cpan.testers', reload_indices_interval => 300, inform_channel_of_new_uploads => 60, inform_channel_of_new_ratings => 60, debug => 0, search_max_results => 30, adminhost => qr/Fox!afoxson\@pool-141-158-116-119\.pitt\.east\.verizon\.net/, policy => { # See 'POLICY CONTROL MECHANISM', in the POD, below '#cpan' => { # allow channel 'cpan upload' informs, allow => qr/^POE-/i, # for #cpan, only if it matches ^POE-, deny => qr/.+/, # and deny everything else }, }, ); $bot->run(); # OR, see the 'cpanbot' script for an alternative DESCRIPTION Bot::CPAN is a POE based distribution that allows individuals on IRC to query the CPAN and other perl resources in a great number of different ways. Bot::CPAN will also automatically inform the channels of new uploads to the CPAN, and new ratings of CPAN distributions. IRC EXAMPLES cpan: recent cpan: top10 cpan: id_name for FOX cpan: mod_desc for Test::Reporter cpan: dist_version for Bot-CPAN METHODS * new This constructor returns a Bot::CPAN object, and is inherited from Bot::CPAN::BasicBot. It will accept named parameters for: channels, servers, port, nick, alt_nicks, username, name, ignore_list, store, and log. Bot::CPAN extends the Bot::CPAN::BasicBot constructor to accept the following named parameters: news_server, group, reload_indices_interval, inform_channel_of_new_uploads, inform_channel_of_new_ratings, debug, search_max_results, nickserv_password, policy and adminhost. * run Fires up the bot. CONSTRUCTOR OPTIONS * adminhost Specifies a regular expression that will be matched against userhosts for commands that require administrative access. * alt_nicks Alternate nicks that this bot will be known by. These are not nicks that the bot will try if its main nick is taken, but rather other nicks that the bot will recognize if it is addressed in a public channel as the nick. This is useful for bots that are replacements for other bots...e.g, your bot can answer to the name "infobot: " even though it isn't really. * channels The channels we're going to connect to. * ignore_list The list of irc nicks to ignore public messages from (normally other bots.) Useful for stopping bot cascades. * debug Enable or disable bugging. 1 or 0. * group NNTP group to retrieve articles from. This group should be where the cpan upload emails are sent. * inform_channel_of_new_uploads Number of seconds between checks for new CPAN uploads. * inform_channel_of_new_ratings Number of seconds between checks for new CPAN ratings. * name The name that the bot will identify itself as. * nickserv_password Password for IRC networks that use NICKSERV. * news_server The NNTP server to retrieve articles from. * nick The nick we're going to use. * policy Defines the policy control mechanism. * port The port we're going to use. * reload_indices_interval Number of seconds between reloading of CPAN indices. * search_max_results Maximum numer of results to return via the 'search' command. (semi-deprecated) * servers The servers that the bot should attempt to connect to. One will be chosen at random for every connect, or reconnect. * username The username we'll claim to have at our ip/domain. COMMANDS * botsnack gives the bot a snack * config Shows the bot's configuration (admin only) * help provides instruction on how to use this bot * proxy proxies an emote (admin only) * recent shows last ten distributions uploaded to the CPAN * status retrieves the status of the bot * top10 top 10 contributors to CPAN * id_dists shows all distributions of an author * id_email retrieves an email from a PAUSE ID * id_name retrieves a name from a PAUSE ID * mod_chapter retrieves the chapter of a module * mod_desc retrieves the description of a module * mod_dist retrieves the distribution of a module * mod_docurl retrieves the documentation URL of a module * mod_dslip retrieves the DSLIP of a module * mod_id retrieves the PAUSE ID of a module * mod_language retrieves the language of a module * mod_license retrieves the license of a module * mod_rturl retrieves the RT URL of a module * mod_stage retrieves the stage of a module * mod_search search for a module * mod_support retrieves the support level of a module * mod_style retrieves the style of a module * mod_version retrieves the version of a module * dist_chapter lists the chapter of a distribution * dist_date retrieves the release date of a distribution * dist_desc retrieves description of a distribution * dist_dlurl retrieves the download URL of a distribution * dist_filename retrieves the filename of a distribution * dist_id retrieves PAUSE ID of a distribution * dist_mods lists all modules in a distribution * dist_path retrieves the path to a distribution * dist_ratings retrives ratings of a distribution * dist_search earch for a distribution * dist_size retrieves the size of a distribution * dist_tests shows tests results for a distribution * dist_url retrieves URL of a distribution * dist_version retrieves the version of a distribution ATTRIBUTES * :Admin Indicates that this command is an admin command. A user will not be able to execute commands marked with this attribute unless their usermask matches the adminhost regex specified in the constructor. * :Args Indicates the nature of the arguments sent to this command. This attribute takes an argument of either 'required', 'optional', or 'refuse'. The user will then get an error message if they attempt to use a command in a manner inconsistent with its intended use. * :Fork Indicates that this command should be forked off. This should be used only for commands that take a long time to execute (like 'tests'). Essentially, forking off a long running command will prevent the execution from blocking the bot. * :Help Defines the help message for this command, which will be available via: /msg bot help . * :LowPrio Indicates that this command's data should be returned to the user with a low priority. This should be used only for commands that return a lot of discrete chunks of data back to the user (like 'tests'). This will prevent the returning of a lot of data from blocking the bot. * :Private Indicates that this command can be executed via a /msg. This attribute takes an argument of either 'notice', or 'privmsg', indicating that manner in which the data should be returned to the user. * :Public Indicates that this command can be executed publically from within a channel. This attribute takes an argument of either 'notice', or 'privmsg', indicating that manner in which the data should be returned to the user. HOW TO WRITE A NEW COMMAND Simple really. Define a subroutine, in CPAN.pm, and add whatever attributes you'd like to it's signature (see above). You will be passed three arguments, the referrent object, the event hashref, and the command's actual argument. To get data back to the user, simply use $self->print(). Its first argument should be the event hashref and the other argument is whatever you want to return to the user. POLICY CONTROL MECHANISM The policy control mechanism consults the policy hashref specified in the constructor. The policy hashref should contain channel hashrefs. The channel hashref may contain both 'allow', and 'deny' key/value pairs. The values of the keys are regex's which specify which channel 'cpan upload' informs are to be allowed or denied. The search stops at the first match. This is a simplistic and minimal policy control mechanism that is directly based on HOSTS_ACCESS(5) (/etc/hosts.(allow|deny)). A channel 'cpan upload' inform will be allowed when the text of an inform matches the allow regex. Otherwise, a channel 'cpan upload' inform will be denied when the text of an inform matches the deny regex. Otherwise, a channel 'cpan upload' inform will be allowed. If a channel doesn't have a specified policy, all channel 'cpan upload' informs will be allowed. You will be matching against strings that look like the below. Bear this firmly in mind when you create regex's to match them (see 'RATINGS'): Test-Reporter-1.19 (+++++) by AFOXSON POE-0.25 (+++++) by RCAPUTO Games-Cryptoquote-1.30 (++++ ) by BOBO RATINGS An upload inform will look something like: Test-Reporter-1.19 (+++++) by AFOXSON What is up with all of the +'s? The plus signs within the parens represent the distributions average rounded rating from cpanratings.perl.org (aka karma). Possible ratings are 1 through 5. The area between the parens is fixed-width which means if a distribution has an average rounded ratinging of '2' if will be padded with 3 spaces. It used to be that (unknown) would be displayed if the bot cannot connect to the data source, (unrated) would be displayed if the module has yet to receieve any ratings, and (error) would be displayed if something went wrong. However, after some discussion on #perl@MagNET, the karma representation will be omitted unless there is an actual karma rating to display. There were competing "karma represetations" floated on #perl@MagNET, such as "letter-grades", and "descriptive words" but in the end, the incremement style got the popular vote. CAVEATS If you expect the bot to have very recent CPAN data, be sure that reindexing is set to get indexes directly from ftp.funet.fi. Even then, those indices are only updated on the funet end about once an hour or so. Bot::CPAN::BasicBot's alt_nicks doesn't do what you think. It's NOT for specifying alternate nicks to use for connecting to IRC if the one you chose is taken. It's used for specifying nicks that you'd like the bot to also respond for, as if the real nick was addressed. This is a relic from the bundling of Bot::BasicBot. BUGS If you happen to find one please email me at afoxson@pobox.com. Thank you. Or, better yet, report it on RT. TODO - Add support for "throttling" (suggested by Spoon) i.e., if several uploads occur at the same time, pace the reporting of such to a pre-determined number of upload notification per minute - Consider re-adding 'modulelist' - Consider re-adding 'details' - Consider re-supporting search_max_results - Improve 'recent' so it has a full recent list on connect - Improve memory profile - Investigate forking reindexing and checking for new uploads/ratings COPYRIGHT Copyright (c) 2003 Adam J. Foxson. All rights reserved. Copyright (c) 2003 Casey West. All rights reserved. LICENSE This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. SEE ALSO * perl * HTTP::Request * XML::Parser * URI * LWP::UserAgent * Mail::Internet * Math::Round * Net::NNTP * POE * Statistics::Descriptive * XML::RSS::Parser * POE::Component::IRC * Text::Wrap * Error * Class::Phrasebook * Attribute::Handlers * Storable * CPAN::DistnameInfo * Compress::Zlib * File::Listing * Sort::Versions * Encode * Config::Auto * Getopt::Long AUTHORS Adam J. Foxson , with patches from Casey West to support the latest POE versions, Randal Schwartz to support NNTP retrieval of CPAN uploads (as opposed to the old way of doing it via mailbox polling), and Rocco Caputo that solved early-on blocking issues, and got the prioritized events patch into the P::C::I core. Special thanks goes out to Iain Truskett for diligent testing and the suggestion of many spiffy features.