Bot::CPAN - provides CPAN services via IRC


     use Bot::CPAN;
     my $bot = Bot::CPAN->new(
         channels => ['#cpan'],
         servers => ['', ''],
         port => 6667,
         nick => 'cpantest',
         alt_nicks => ['cpantest2', 'cpantest3'],
         username => 'cpantest',
         name => 'cpantest',
         nickserv_password => 'top_secret_password',
         ignore_list => [qw(purl)],
         news_server => '',
         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 =>
         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
     # OR, see the 'cpanbot' script for an alternative


   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.


     cpan: recent
     cpan: top10
     cpan: id_name for FOX
     cpan: mod_desc for Test::Reporter
     cpan: dist_version for Bot-CPAN


   * 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.


   * 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.
   * 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.


   * 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


   * :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 <command>.
   * :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
   * :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.


   Simple really. Define a subroutine, in, 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.


   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


   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 (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.


   If you expect the bot to have very recent CPAN data, be sure that
   reindexing is set to get indexes directly from Even then,
   those indices are only updated on the funet end about once an hour or
   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.


   If you happen to find one please email me at Thank
   you. Or, better yet, report it on RT.


     - 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 (c) 2003 Adam J. Foxson. All rights reserved.
     Copyright (c) 2003 Casey West. All rights reserved.


   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
   Public License for more details.


   * 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


   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.