This is Info file pm.info, produced by Makeinfo version 1.68 from the input file bigpm.texi.  File: pm.info, Node: Perlbug/Base, Next: Perlbug/Cmd, Prev: Perlbug, Up: Module List Module for bringing together Config, Log, Format, Do, TM, Mysql etc. ******************************************************************** NAME ==== Perlbug::Base - Module for bringing together Config, Log, Format, Do, TM, Mysql etc. DESCRIPTION =========== Methods for perlbug database access, all_flags, check_user, get_list, get_data, clean_up, etc. SYNOPSIS ======== my $o_base = Perlbug::Base->new; my %user = $o_base->user_data('richard'); print "User is: ".$user{'username'}; METHODS ======= new Create new Perlbug object, (see also `Description' in this node above): my $pb = Perlbug->new(); url Store and return the given url. do Wrap a Perlbug::Do command my $i_ok = $pb->do('b', 'bugid'); debug Wrap o_log->debug calls dodgy_addresses Returns quoted, OR-d dodgy addresses prepared for a pattern match ...|...|... my $regex = $o_obj->dodgy_addresses('from'); # $rex = 'perlbug\@perl\.com|perl5\-porters\@perl\.org|...' link Wrap o_log->link calls AUTOLOAD Wrapper for debug functions, translates this: $o_obj->debug3($data); # to $o_obj->{'o_log'}->debug(3, $data); # this dump Wrap Data::Dumper catering for www also. can_update Check if current user is allowed to update given item/s. print 'yes' if $o_perlbug->can_update([$user||$bid||$mid||$bid|$pid]); fatal Wrap o_log->fatal calls start finish format Wrap o_format->format calls format_overview Wrap o_format->overview calls format_schema Wrap o_format->schema calls copy Wrap Log::copy flags Returns array of options for given type. my @list = $pb->flags('category'); all_flags Return all flags available in db keyed by type. my %flags = $pb->all_flags; %flags = ( # now looks like this: 'category' => ['core', 'docs', 'install'], # ... 'status' => ['open', 'onhold', 'onhold'], # ... # ... ); date_hash active_admins Returns active admins from db. my @active = $pb->active_admins; active_admin_addresses Returns active admin addresses from db. my @addrs = $pb->active_admin_addresses; user_data Return (cached) data on given user my %data = $pb->user_data('richard'); help Returns help message for perlbug database. my $help = $pb->help; spec Returns spec message for perlbug database. my $spec = $pb->spec(); flow Details how the mail / web mechanism flows administration_failure Deal with a failed administration attempt my $i_ok = $self->administration_failure($bid, $user, $commands); check_user Checks given user is registered in the database as an admin. Sets userid in `admin' in this node and thereby `status' in this node for later reference. $pb->check_user($user_name); isadmin Stores and returns current admin userid (post check_user), checks whether system is restricted or not. next unless $pb->isadmin; status Returns 'A' or 'U' depending on whether user is an admin or a 'mere' user. my $thing = ($self->status eq 'A') ? 'key' : 'lock'; ok Checks bugid is in valid format (looks like a bugid) (uses get_id): &do_this($id) if $pb->ok($id); get_id Determine if the string contains a valid bug ID _switches Stores and returns ref to list of switches given by calling script. Only these will be parsed within the command hash in `process_commands' in this node. my $switches = $pb->_switches(qw(e t T s S h l)); #sample result Storage area (file) for results from queries, returns the FH. my $res = $pb->result('store this stuff'); #store fh Wrapper for Log fh set_site Set the site directory for text files, headers, todos etc. read append Wrapper for Log append get_results Return the results of the queries from this session. my $a_data = $pb->get_results; get_list Returns a simple list of items (column values?), from a sql query. my @list = $pb->get_data('SELECT bugid FROM tm_bug'); get_data Returns a list of hash references, from a sql query. my @hash_refs = $pb->get_data('SELECT * FROM tm_bug'); exec Returns statement handle from sql query. my $sth = $pb->exec("INSERT @data INTO table"); exists Does this bugid exist in the db? tm_parent_child Assign to given bugid, given list of parent and child bugids current_status Get's current status of bug for reference. tm_bug_patch Assign to given bugid, given list of patchids, return valid, @pids tm_bug_note Assign to given bugid, given list of note ids, return valid, @nids tm_bug_test Assign to given bugid, given list of testids, return valid, @tids notify_cc Notify tm_cc addresses of changes, current status of bug. track Track some function or modification to the db. $i_tracked = $self->track($type, $id, $entry); ck822 Email address checker (RFC822) courtesy Tom Christiansen/Jeffrey Friedl. print (($o_email->ck822($addr)) ? "yup($addr)\n" : "nope($addr)\n"); htpasswd Modify, add, delete, comment out entries in .htpasswd $i_ok = $o_web->htpasswd($userid, $pass); # entry ok? @entries = $o_web->htpasswd; # returns list of entries ('userid:passwd', 'user2:pass2'...) clean_up Clean up previous (logs and results) activity whenever run. Exits when done. insert_bug Insert a bug into the database my ($i_ok, $bid, $mid) = $o_obj->insert_bug(@args); parse_flags Return the 'AND ...' or 'SET ...' condition for a tm_bug query given the flags from the status, category and severity columns WITHOUT the leading 'AND' or a leading ', ' separator. my $stuff = $pb->parse_flags([('o', 'build')], 'AND'); # $stuff is now "status = 'open' AND category = 'build'" my $sql = "SELECT * FROM some_table WHERE $stuff"; # or my $stuff = $pb->parse_flags([('o', 'build')], 'SET'); # $stuff is now "status = 'open', category = 'build'" my $sql = "UPDATE tm_bug SET $stuff WHERE bugid = 'xyz'"; =cut sub parse_flags { my $self = shift; my ($str, $type) = @_; $str = (ref($str) eq 'ARRAY') ? join(' ', @{$str}) : $str; my $this = ($type eq 'AND') ? 'AND ' : ', '; # AND|SET $self->debug(2, "Parsing str ($str), type ($type) ... this ($this)"); my @tm_flags = $self->get_list('SELECT DISTINCT type FROM tm_flags'); my $sql = undef; my %seen = (); FLAG: foreach my $f (@tm_flags) { $self->debug(3, "Parsing flag ($f)"); my @opts = $self->get_list("SELECT DISTINCT LOWER(flag) FROM tm_flags WHERE type = '$f'"); OPT: foreach my $opt (@opts) { $self->debug(4, "Comparing str ($str) and opt ($opt)"); STR: foreach my $bit (split ' ', lc($str)) { next unless $bit =~ /\w/; if ($opt =~ /\b$bit/i) { my $line = " $this $f = '$opt' "; $seen{$opt}++; $self->debug(4, "Flag ($f) matched, line ($line) made."); $sql .= $line; next FLAG; } else { $self->debug(4, "Flag ($f) not matched: opt($opt) bit($bit)"); } } } $self->debug(3, "Flag ($f) set sql ($sql)"); } $sql =~ s/^(.+)?$type\s*$/$1/; $sql =~ s/^[\,\s]+(\w.+)$/ $1/; if (!(scalar(keys %seen) >= 1)) { $sql .= " AND bugid = 'non-plaus_ible bug id!' AND bugid = 'no flag found protector :-)' "; $self->debug(0, "Setting duff flag to protect against all bugs being returned: '$sql': ".Dumper(\%seen)); } # $sql = (length($sql) > 4) ? substr($sql, 4) : $sql; # start $self->debug(2, "Parse ($str, $type) result: sql($sql)"); return $sql; } parse_str my %cmds = $o_obj->parse_str('patch__etc' | (qw(patchid bugid etc));  File: pm.info, Node: Perlbug/Cmd, Next: Perlbug/Config, Prev: Perlbug/Base, Up: Module List Command line interface to perlbug database. ******************************************* NAME ==== Perlbug::Cmd - Command line interface to perlbug database. DESCRIPTION =========== Command line interface to perlbug database. SYNOPSIS ======== use Perlbug::Cmd; my $o_perlbug = Perlbug::Cmd->new; my $result = $o_perlbug->cmd; print $result; # == 1 (hopefully :-) METHODS ======= new Create new Perlbug::Cmd object: my $pb = Perlbug::Cmd->new(); cmd Call the command line interface: $o_perlbug->cmd; process Processes the command given, gets and truncates the results, calls scroll scroll Scroll the available data if necessary. history History mechanism accessor doh Wraps help message doH History of commands parse_commands Parses the subject and body of the email message into a command hash, hash is placed in $pb->result, returns ref to said hash: my $h_ref = $pb->parse_commands($sbj, $bdy); process_commands Steps through hash created by `parse_commands' in this node, and executes each outstanding command, so long as the command has been allowed via `switches' in this node. Returns valid == 1 or error message. my $outcome = $pb->process_commands($ref_to_hashed_commands); AUTHOR ====== Richard Foley perlbug@rfi.net 2000  File: pm.info, Node: Perlbug/Config, Next: Perlbug/Do, Prev: Perlbug/Cmd, Up: Module List Perlbug Configuration data handler ********************************** NAME ==== Perlbug::Config - Perlbug Configuration data handler DESCRIPTION =========== Configuration data for the Perlbug bug tracking system. Be sure to set the 'Perlbug_SiteConfig' environment variable to the correct site configuration file, and/or fix the line above. Set methods are provided only for `current()' in this node parameters, the rest are all gettable only, and settable from the configuration file. SYNOPSIS ======== my $o_conf = Perlbug::Config->new; my $debug = $o_conf->current('debug'); # 0 or as set in Configuration file my $new_debug = $o_conf->current('debug', 2); # 2 ! my @current_data = $o_conf->get_keys('current'); # have a look METHODS ======= new Create new Config object with all prefs set. my $conf = Perlbug::Config->new; get_config_data Retrieve data from site configuration file my ($ok, $h_data) = get_config_data($config_file_location); update_data Update config data structure for current/local environment my ($ok, $h_data) = &update_data(\%data); check_data Check config data structure my ($ok, $h_data) = check_data(\%data); get_date Returns common date for use throughout Perlbug. my $date = get_date; # -> 19980815 get_keys Return list of keys of given key, ignoring comment fields. get_vals Return list of values of given key, ignoring comment fields. dump Returns prefs, via Data::Dumper for debugging, all if no argument given. Be sure to call it in a list context: print $Conf->dump('system'); current Current modifiable environment. Get my $debuglevel = $o_obj->current('debug'); Set my $incremented = $o_obj->current('debug', $self->current('debug') + 1); methods Access methods to data, non are directly modifiable, see the Configuration file. my $target_address = $o_obj->target('generic'); AUTHOR ====== Richard Foley perlbug@rfi.net 21.Oct.1999  File: pm.info, Node: Perlbug/Do, Next: Perlbug/Email, Prev: Perlbug/Config, Up: Module List Commands (switches) for generic interface to perlbug database. ************************************************************** NAME ==== Perlbug::Do - Commands (switches) for generic interface to perlbug database. DESCRIPTION =========== Methods for various functions against the perlbug database. SYNOPSIS ======== Use like this: $o_obj->dod(2); # set debug level to '2' =head1 METHODS new Create new Perlbug::Do object: my $do = Perlbug::Do->new(); get_switches Returns array of current switches, rather than string my @switches = $o_mail->get_switches('user'); doh Returns help message built from a hash_ref, commands may be overwritten by sending in a hash. Syntax for the hash is 'key => description (sample args)': $o_obj->doh({ 'e' => 'email me a copy too (email@address.com)', # add 'H' => 'Help - more detailed info ()', # replace 'z' => '', # unrequired }); dod Switches debugging on (1). doD Dumps database for backup and recovery. dom Return the given message(id), places the `format', *Note Perlbug: Perlbug,ed result in to the results array. my $res = $do->dom([@messageids]); doM Create new message my $i_ok = $do->doM($bugid, 'message', 'etc'); # rjsf -> ($xstr, $content, $hdr, $to, $from, $subject) # reverse order dop Return the given patch(id), places the `format', *Note Perlbug: Perlbug,ed result in to the results array. my $res = $do->dop([@patchids]); doP Assign to given bugid, given patch, return i_ok $i_ok = $o_obj->doP('tid_chid_versid', 'patch...here', 'hdr', 'sbj', 'frm', 'to); dot Return the given test(id), places the `format', *Note Perlbug: Perlbug,ed result in to the results array. my $res = $do->dot([@testids]); doT Assign to given bugid, given test, return i_ok $i_ok = $o_obj->doT('tid_chid_versid', 'test...here', 'hdr', 'sbj', 'frm', 'to); dob Return the given bug(id), places the `format', *Note Perlbug: Perlbug,ed result in to the result array. my $i_bugs = $do->dob([@bugids]); # $i_bugs = num of bugs succesfully processed doB Return the given bug(id), with all the messages assigned to it, calls dob() my $i_bugs = $do->doB([@bugids]); # $i_bugs = num of bugs succesfully processed dou Get the given user, checks if active print $o_do->dou($userid); doc Retrieve bug based on the existing category, severity or status flags. my $res = $do->doc('open build'); doC Retrieve messages, as per doB() where category, severity or status fulfills the following optional flags: o (open), c (closed), b (build), p (patch), u (utilities) ... Wrapper for l. dos Retrieve data based on the subject line of a bug my $res = $do->dos('open build'); dor Retrieve data based on contents of the Body of a message my $res = $do->dor('open build'); don Get the note for this noteid doN Assign to given bugid, given notes, return $i_nid or 0 Accepts ($bugid, $note, $header) or ([($bugid, $note, $header)]) doq Gets the sql _q_ query statement given in the body of the message, executes it, and returns the result in the result array. doQ Returns the database schema, for use with SQL statements. doL Returns the current (or given later) logfile. =cut sub doL { # Log (all) my $self = shift; $self->debug('IN', @_); my ($input) = @_; my ($given) = (ref($input) eq 'ARRAY') ? @{$input} : $input; ($given == 1) && ($given = 'today'); $self->start("L $given"); my $fh = $self->fh('log'); # , pb_log_\d{8} my $LOG = "; if (defined $fh) { $fh->seek(0,0); while (<$fh>) { $LOG .= $_; } $fh->seek(0, 2); my $length = length($LOG); $self->debug(2, "log ($fh) length ($length) read"); } else { $self->debug(0, "Can't read LOG from undefined fh ($fh)"); } $self->result($LOG, 3); $self->finish; my $i_ok = (length($LOG) >= 1) ? 1 : 0; $self->debug('OUT', $i_ok); return $i_ok; } dol Just the stored log results from this process. dof Sets the appropriate format for use by `Format' in this node methods, overrides default 'a' set earlier. $o_obj->dof('h'); stats Get stats from db for overview usage. my $h_data = $self->stats; doo Returns a summary overview of the bugs, bugs, messages etc. in the database. $i_ok = $o_do->doo(); # data in result via formatting... doO Returns a similar overview of the bugs, in GUI format using GIFgraph and/or AA-lib? Still to do doa ONLY do this if registered as admin of bug. in which case dok could still dok(\@bids) these bugids... or should it automatically add id as admin? admin_of_bug Checks given bugid and administrator against tm_bug_user. Returns 1 if administrator listed against bug, 0 otherwise. doA dok Klaim the bug(id) given doK UnKlaim the bug(id) given dox Delete bug from tm_bug table. Use doX for messages associated with bugs. doX Delete given bugid messages from tm_message. doi Initiate new admin entry, including htpasswd entry, (currently rf only) userid=test_user: password=p*ss33*t: address=perlbugtest@rfi.net: match_address=.*\@rfi\.net: name=Richard Foley: or userid=test_user:password=p*ss33*t:address=perlbugtest@rfi.net:match_address=.*\@rfi\.net:name=Richard Foley doI Disable a user entry _doz Update: only to be used by perlbug@rfi.net (disabled) $ok = $o_obj->_doz($filename, $data); doy Password renewal $i_ok = $o_obj->doy($user, $pass); AUTHOR ====== Richard Foley perlbug@rfi.net Oct 1999  File: pm.info, Node: Perlbug/Email, Next: Perlbug/Fix, Prev: Perlbug/Do, Up: Module List Email interface to perlbug database. ************************************ NAME ==== Perlbug::Email - Email interface to perlbug database. DESCRIPTION =========== Email interface to perlbug database. SYNOPSIS ======== use Perlbug::Email; use Mail::Internet; my $o_mail = Mail::Internet->new(*STDIN); my $o_perlbug = Perlbug::Email->new($o_mail); my $call = $o_perlbug->switch; my $result = $o_perlbug->$call($o_mail); print $result; # =1 (hopefully :-) METHODS ======= new Create new Perlbug::Email object: my $pb = Perlbug::Email->new($o_mail); # Mail::Internet _original_mail Maintain original original Returns original field/s from header mailing Switch mailing on/off, also sets email->mailer to 'test' if off splice Returns the original mail spliced up into useful bits, set from `parse_mail' in this node or `switch' in this node, or given as arg. my ($o_hdr, $header, $body) = $self->splice; # or splice($o_mail); parse_mail Given a mail (Mail::Internet) object, parses it into command hash, also checks the header for X-Perlbug loop and the address of the sender via `check_user' in this node. my $h_commands = $pb->parse_mail($mail); from Sort out the wheat from the chaff, use the first valid ck822 address: my $from = $self->from($replyto, $from, @alternatives); check_header Checks (incoming) email header against our X-Perlbug flags, also slurps up the Message-Id for future reference. my $i_ok = $o_perlbug->check_header($o_hdr); # or undef check_user Checks the address given (From usually) against the tm_user table, sets user or admin access priviliges via the switches mechanism accordingly. Returns admin name my $admin = $pb->check_user($mail->('From')); # -> user_id || blank return_info Takes data ($a_stuff), which may be a ref to the result array, and mails it to the From or Reply-To address, Cc:-ing it to any address given by the -e flag. my $i_ok = $pb->return_info($o_mail, $a_stuff); _mail Get and set the incoming mail object (Mail::Internet) Returned (used) via `splice()' in this node doh Wraps help message doH Returns more detailed help. get_header Get new perlbug Mail::Header, filled with appropriate values, based on given header. my $o_hdr = $o_email->get_header(); # completely clean my $o_hdr = $o_email->get_header($o_old_header); # plain (coerced as from us) my $o_hdr = $o_email->get_header($o_old_header, 'remap'); # maintain headers (nearly transparent) default Operates on given tag, from bugdb@perl.org: we're sending this out from here. Affects Message-Id(new), From(bugdb), Reply-To(maintainer) lines Keeps Subject|To|Cc for later modification? Filters anything else my @lines = $self->default($tag, @lines); remap Operating on a given tag, remaps (To|Cc) -> forwarding address, removes duplicates. Attempt to remain moderately invisible by maintaining all other original headers. my @lines = $self->remap($tag, @lines); send_mail Send a mail with protection. my $ok = $email->send_mail($o_hdr, $body); tester If test mail, turn header to maintainer and return header data for insertion defense Set mail defaults for _all_ mail emanating from here, calls `clean_header()' in this node, `trim_to()' in this node. my $o_hdr = $self->defense($o_hdr); clean_header Clean header of non-compliant 822 address lines using Mail::Address::parse() my $o_hdr = $o_mail->clean_header($o_hdr); trim_to Takes the header and returns it without any dodgy to, or cc addresses (or undef): my $o_hdr = $o_obj->trim_to($o_hdr); get_forward Operating on a single (or blank) address, returns a list of forwarding addresses. my $to = $perlbug->get_forward('perlbug@perl.org'); # perl5-porters@perl.org my $to = $perlbug->get_forward('perl-win32-porters@perl.org'); # perl-win32-porters@perl.org my $to = $perlbug->get_forward(); # perl5-porters@perl.org my @to = $perlbug->get_forward(); # perl5-porters@perl.org perl-win32-porters@perl.org etc... switch Returns appropriate method name to call to handle this mail. This enables you to bypass the suggested method with your own call (be it on your own head :-): my $call = $pb->switch(Mail::Internet->new(\$STDIN); do_new Deal with a new bug do_note Wrapper for a new note do_patch Wrapper for a new patch do_test Wrapper for a new test scan Scan for perl relevant data putting found or default switches in $h_data. Looking for both category=docs and '\brunning\s*under\ssome\s*perl' style markers. my $h_data = $o_mail->scan($body); my $res = $o_mail->bug_set($tid, $h_data); do_reply Deal with a reply to an existing bug - no acknowledgement, no forward (quiet) header2admin Given a Mail::Header object attempts to return a valid create admin command my $data = $o_email->header2admin($o_hdr); doe Email address to 'Cc:' to -e me.too@some.where.org doy New password dov Volunteer proposed bug modifications propose_close_@bugs.perl.org my $i_ok = $o_obj->dov('tid close patch'); doV Volunteer a new administrator register_MYUSERID@bugs.perl.org doa admin a bug close__patch_macos@bugs.perl.org doP Recieve a patch patch_*_*_*@bugs.perl.org doT Recieve a test test_@bugs.perl.org doN Recieve a note note_*@bugs.perl.org dow Forward (weiterleiten) mail onto all active administrators admin(s)@bugs.perl.org my $i_ok = $o_obj->dow($body); do_quiet Drop out quietly, no entry in database, silent dump into black hole. do_bounce Deal with a bounced mail assign_bugs Assign to this admin, so many, of these unclaimed bugs. N.B. the claimed bugs are shifted off the end of the referenced array! $ok = $pb->assign_bugs($admin, 5, \@unclaimed); check_mail Check headers against various given parameters, attempts to read all required lines/data. # call # Scope Regex my $o_new = $o_mail->process_header($o_hdr, $context); # Mail::Send object (ready to go) my @should = $o_hdr->get('X-Perlbug-Match'); # Subject: \-h\s\-o my @shouldnt = $o_hdr->get('X-Perlbug-Match-Non'); # To: \s*perlbug\@perl\.com my @failures = $o_hdr->get('X-Perlbug-Match-Bad'); # To: \s*perlbug\@perl\.org ($i_ok, $feedback) = $o_bugmail->check_mail($o_new, $body, \@should, \@shouldnt, \@shouldfail); warn "Mail header check failure: ($feedback)\n" unless $i_ok == 1; doD Mail me a copy of the latest database dump scan_header Scan a typical *@bugs.perl.org header my ($cmd, $body) = $o_mail->scan_header($o_hdr, $body); To: line can be any of: close__@bugs.perl.org = bug admin request register@bugs.perl.org = admin registration request admins@bugs.perl.org = admin mail forward Subject: line may look like: -h -o -H -d2 -l -A close 20000721.002 lib -r patch -e some@one.net admin_of_bug Checks given bugid and administrator against tm_bug_user, tm_bugs::sourceaddr, tm_cc. Now you can admin a bug if you're on the source address, or the Cc: list. administration_failure Deal with a failed administration attempt my $i_ok = $self->administration_failure($tid, $user, $commands); in_master_list Checks given address against ok-to-be-administrator email address list my $i_ok = $o_obj->in_master_list($address); AUTHOR ====== Richard Foley perlbug@rfi.net 1999 2000  File: pm.info, Node: Perlbug/Fix, Next: Perlbug/Format, Prev: Perlbug/Email, Up: Module List Command line interface to fixing perlbug database. ************************************************** NAME ==== Perlbug::Fix - Command line interface to fixing perlbug database. DESCRIPTION =========== Command line interface to fixing incorrect perlbug data. Note: `mig()' in this node will migrate from pre-2.26 database structure to current usage. USAGE ===== lowercase is indicator/report UPPERcase expands/effects > h # help > H # Helpful help > f # view erroneous flags > F # Fix erroneous flags > mig # check stuff > MIG # Fix stuff (migrate...) > # etc. METHODS ======= new Create new Perlbug::Fix object: my $o_fix = Perlbug::Fix->new(); process Processes the command given, gets and truncates the results, calls scroll flags Set flags to " in tm_tickets where flag is unknown in tm_flags map_flags Adjust bug flags, note, this also updates the flags table with missing values! cc Correct tm_cc table bugs Correct tm_tickets table messages Correct messages table notes Correct notes table claimants Correct claimants table patches Correct patch relations table users Correct users table action Process action on behalf of caller my $i_ok = $self->action('tm_table', 'UPDATE x SET y WHERE z etc...'); mig Migrate whole database x0 Migrate log x1 Migrate notes x2 Migrate patches x3 Migrate tests x99 Remove MIGRATE deadwood if everythings is OK x31 Update tm_claimants from tm_logs by userid x32 Assumes bugids in db, messages in dir, find messages which were not forwarded, forward them. Not the same as an historic trawl, which is looking for new/replies, etc. xspecial Specials AUTHOR ====== Richard Foley perlbug@rfi.net 2000  File: pm.info, Node: Perlbug/Format, Next: Perlbug/Log, Prev: Perlbug/Fix, Up: Module List Formats for email interface to perlbug database. ************************************************ NAME ==== Perlbug::Format - Formats for email interface to perlbug database. DESCRIPTION =========== Different formats which can be applied to the data returned from the perlbug database via l (l, l and l) interfaces: *aAhHl* If html is required, `-f h' should be used. The first letter following the -f switch is the only one used to define which format to use for all results emanating from a single email, `-f h' being set by default for a web call. Specific objects supported include: Bugs, Messages, Users, Patches, Tests and Notes. Currently this is not relevant for the -q (sql query) switch, as there is little value in attempting to second guess what may be called for in sql statements. SYNOPSIS ======== my $o_fmt = Perlbug::Format->new; my %data = ( 'some' => 'data', 'other' => 'stuff', ); my $str = $o_fmt->fmt(\%data); print $str; # 'some=data\nother=stuff\n' FORMATS ======= a ascii short - minimal listings default for mail interface A ASCII long - maximal block style listings h html short - minimal listings default for web interface H HTML short - maximal block style listings l lean list - ascii but purely for parsing minimal data L lean HTML - like l, but with html links - yek METHODS ======= new Create new Perlbug::Format object: my $do = Perlbug::Format->new(); context Set context ascii or html, sets pre- and post- values line_break Return the current line-break pre Return the current pre-setting pre Return the current post-setting fmt Default printout (of given hash, or anything) - very basic formatter of simple data. %data = ( 'this' => 'that', 'here' => [qw(there up down turnaround)], ); print $pb->fmt(\%data); this=that here=there up down turnaround _fmt_sql Format sql queries format_data Formats this, and writes (via a format) to results file. If it recognises the object via: bug(id), message(id), patch(id), note(id), user(id) the appropriate formatting is applied. my $res = $format->format_data(\%this); format_fields Format individual entries for output, handles bugs, messages, users, patches, tests, notes my $h_tkt = $o_perlbug->format_fields($h_tkt); schema Schema for database, should allow the database to format this for us ... overview Formating for overview. $fmt{'bugs'} = $data{'bugs'}; format_this Wrapper for calls to filehandle, local data. my $res = $obj->format_this('res', "FORMAT_$type_$format", $max); # $res = '' _current_target Any call which includes `format_this()' in this node, `format_data' in this node etc. will automatically set the _current_target to a copy of that data. This can then be inspected from here. print Dumper($obj->_current_target); start Sets start header for results. =cut sub start { return "; my $self = shift; my $flag = shift; my $format = shift || $self->current('format') || 'a'; $self->debug(3, "Section: $flag"); my $start = "; if ($format eq 'a') { $start = "$flag: \n"; } elsif ($format eq 'A') { $start = qq| ============================================================================== Section: $flag ------------------------------------------------------------------------------ |; } elsif ($format eq 'h') { $start = '

'; } elsif ($format eq 'H') { $start = '


'; } else { $self->debug(0, "Unknown format options: '$format'"); } $self->result($start, 1); return "; } sub finish { my $self = shift; return "; } # format WWW fields # ------------------------------------------------------------------------------ format_bug_fields Format individual bug entries for placement my $h_tkt = $o_web->format_bug_fields($h_tkt); format_message_fields Format individual message entries for placement my $h_msg = $o_web->format_message_fields($h_msg); format_patch_fields Format individual patch entries for placement my $h_pat = $o_web->format_patch_fields($h_pat); format_test_fields Format individual test entries for placement my $h_test = $o_web->format_test_fields($h_test); format_note_fields Format individual note entries for placement my $h_msg = $o_web->format_note_fields($h_msg); format_user_fields Format individual user entries for placement my $h_usr = $o_web->format_user_fields($h_usr); href Return list of perlbug.cgi?req=id&... hyperlinks to given list). Maintains format, rng etc. my @links = $o_web->href('bid', \@bids, 'visible element of link', [optional subject hint]); mailto Return mailto: for a particular ticket my $mailto = $o_web->mailto($h_tkt); popup Returns appropriate (cached) popup with optional default value inserted. my $popup = $web->popup('status', $unique_id, $default); $self->debug(3, "Admin ($1) of bug ($id) called."); $tkt{'category'} = $self->popup('category', $tkt{'category'}, $id.'_category'); $tkt{'osname'} = $self->popup('osname', $id.'_osname', $tkt{'osname'}); $tkt{'select'} = $cgi->checkbox(-'name'=>'bugid', -'checked' => '', -'value'=> $id); $tkt{'severity'} = $self->popup('severity', $id.'_severity', $tkt{'severity'}); $tkt{'status'} = $self->popup('status', $id.'_status', $tkt{'status'}); FORMAT_B_l Lean ascii format for tickets: FORMAT_B_A Default ASCII format for bugs: ... FORMAT_B_L Lean html format for tickets: FORMAT_B_h Html minimal format: ... FORMAT_B_H Html, tabled in block format: ... FORMAT_O_a Formating for overview (default). ... =cut format FORMAT_O_a_TOP = PerlBug Database overview, figures in brackets() are still open: ------------------------------------------------------------------------------ . format FORMAT_O_a = @<<<<<< $fmt{'_pre'} Bugs Messages Patches Tests Notes Admins 24hrs 7days 30days 90days @<<<<<<< @<<<<<<< @<<<<<< @<<<<< @<<<<< @<<<<<< @<<<<<< @<<<<<< @<<<<<<< @<<<<< $fmt{'bugs'}, $fmt{'messages'}, $fmt{'patches'}, $fmt{'tests'}, $fmt{'notes'}, $fmt{'administrators'}, $fmt{'days1'}, $fmt{'days7'}, $fmt{'days30'}, $fmt{'days90'} Ratios: Open to Closed Closed to Open Msgs to Bugs Bugs to Admins @<<<<<<<<<<<<< @<<<<<<<<<<<<< @<<<<<<<<<<<<< @<<<<<<<<<<<<<<< $fmt{'ratio_o2c'}, $fmt{'ratio_c2o'}, $fmt{'ratio_m2t'}, $fmt{'ratio_t2a'} Status: Open Closed Busy Onhold Abandoned Duplicate @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< $fmt{'open'}, $fmt{'closed'}, $fmt{'busy'}, $fmt{'onhold'}, $fmt{'abandoned'}, $fmt{'duplicate'} Category: Install Library Patch Core Docs Utilities @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< $fmt{'install'}, $fmt{'library'}, $fmt{'patch'}, $fmt{'core'}, $fmt{'docs'}, $fmt{'utilities'} Unknown Notabug OK @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< $fmt{'unknown'}, $fmt{'notabug'}, $fmt{'ok'} Severity: Fatal High Medium Low Wishlist @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< $fmt{'fatal'}, $fmt{'high'}, $fmt{'medium'}, $fmt{'low'}, $fmt{'wishlist'} OS: Generic Linux Win32 MacOS Solaris Hpux Aix @<<<<<<<<< @<<<<<<<<< @<<<<<<<<< @<<<<<< @<<<<<<<<< @<<<<<<<< @<<<<<<<< $fmt{'generic'}, $fmt{'linux'}, $fmt{'mswin32'}, $fmt{'macos'}, $fmt{'solaris'}, $fmt{'hpux'}, $fmt{'aix'}, @<<<<<< $fmt{'_post'} . FORMAT_O_h_TOP Formatting for html overview. FORMAT_S_a Default format for Schema fields for database (top elsewhere). FORMAT_S_h Html format for Schema fields for database (top elsewhere temporarily). FORMAT_M_l Messages lean format. FORMAT_M_a Messages list format. FORMAT_M_A Messages block ASCII format. FORMAT_M_h Messages in list html format. FORMAT_M_H Messages in block html format. FORMAT_U_l User list format. FORMAT_U_a User list format. FORMAT_U_h User in list html format. FORMAT_H_l History list format. FORMAT_H_a History list format. FORMAT_H_h History in list html format. FORMAT_N_l Note lean format. FORMAT_N_a Note list format. FORMAT_N_A Note block ASCII format. FORMAT_N_h Note in list html format. FORMAT_N_H Note in block html format. FORMAT_P_l Patch lean format. FORMAT_P_a Patch list format. FORMAT_P_A Patch block ASCII format. FORMAT_P_h Note in list html format. FORMAT_P_H Patch in block html format FORMAT_T_l Test lean format. FORMAT_T_a Test list format. FORMAT_T_A Test block ASCII format. FORMAT_T_h Test in list html format. FORMAT_T_H Test in block html format AUTHOR ====== Richard Foley perlbug@rfi.net Oct 1999  File: pm.info, Node: Perlbug/Log, Next: Perlbug/Note, Prev: Perlbug/Format, Up: Module List Module for generic logging/debugging functions to all Perlbug. ************************************************************** NAME ==== Perlbug::Log - Module for generic logging/debugging functions to all Perlbug. DESCRIPTION =========== Expected to be called from sub-classes, this needs some more work to cater comfortably for non-method calls. SYNOPSIS ======== my $o_log = Perlbug::Log->new('log' => $log, 'res' => $res); $o_log->append('res', "other data\n"); $o_log->append('log', "some data\n"); $o_log->append('res', "OK\n"); my $a_data = $o_log->read('res'); print $a_data; # 'other data\nOK\n' METHODS ======= new Create new Perlbug::Log object my $obj = Perlbug::Log->new('log' => $log, 'res' => $res, 'rng' => $rng, 'debug' => 2); debug Debug method, logs to `' in this node, with different levels of tracking: $pb->debug('duff usage'); # undefined second arg (treated as level 0) $pb->debug(0, 'always tracked')); # $Perlbug::Debug >= 0 $pb->debug(1, 'tracked if debug >= 1'); # key calls $pb->debug(2, 'tracked if debug >= 2'); # key calls plus data $pb->debug(3, 'tracked if debug >= 3'); # includes caller info etc. $pb->debug('in', 'args'); # in|out (2++, (data 4++)) $pb->debug('out', 'result'); # in|out, (2++, (data 4++)) fatal Deals with a fatal condition by logging and dieing, traps dies to come out here: &do_this or $pb->fatal($message); logg Logs args to log file, which is either 'pb_19980822', or pb_backup_log. Expected to be used via `' in this node. &do_this($self, 'x') and $pb->logg('Done that'); fh Define and return filehandles, keyed by 3 character string for our own purposes, otherwise the file name sitting in the system('text') dir. $o_log->fh($file, '+>>', 0755); append Storage area (file) for results from queries, returns the FH. my $pos = $log->append('res', 'store this stuff'); # $pos is position in file read Return the results of the queries from this session. my $a_data = $log->read('res'); truncate Truncate this file my $i_ok = $log->truncate('res'); prioritise Set priority nicer by given integer, or by 12. set_user Sets the given user to the runner of this script. copy Copy this to there $ok = $log->copy($file1, $file2); @file1_data = $log->copy($file1, $file2); link link this to there $ok = $log->link($source, $target, [-f]); create Create new file with this data: $ok = $self->create("$dir/$file.tmp", $data); syntax_check Check syntax on given file $ok = $self->syntax_check("$dir/$file.tmp"); DESTROY Cleanup log and result files. AUTHOR ====== Richard Foley perlbug@rfi.net Oct 1999 2000  File: pm.info, Node: Perlbug/Note, Next: Perlbug/Patch, Prev: Perlbug/Log, Up: Module List Perlbug test module placeholder ******************************* NAME ==== Perlbug::Test - Perlbug test module placeholder DESCRIPTION =========== x SYNOPSIS ======== y METHODS ======= new Create new Perlbug::Test object: my $o_test = Perlbug::Test->new(); # generic my $o_email_test = Perlbug::Test->new('Email'); # guess :-) AUTHOR ====== Richard Foley perlbug@rfi.net 2000  File: pm.info, Node: Perlbug/Patch, Next: Perlbug/TM, Prev: Perlbug/Note, Up: Module List Perlbug test module placeholder ******************************* NAME ==== Perlbug::Test - Perlbug test module placeholder DESCRIPTION =========== x SYNOPSIS ======== y METHODS ======= new Create new Perlbug::Test object: my $o_test = Perlbug::Test->new(); # generic my $o_email_test = Perlbug::Test->new('Email'); # guess :-) AUTHOR ====== Richard Foley perlbug@rfi.net 2000  File: pm.info, Node: Perlbug/TM, Next: Perlbug/Table, Prev: Perlbug/Patch, Up: Module List Bug support functions for Perlbug ********************************* NAME ==== Perlbug::TM - Bug support functions for Perlbug DESCRIPTION =========== Access to the database, bug get, set, id methods for Perlbug. SYNOPSIS ======== my $o_tm = Perlbug::TM->new; my $id = $o_tm->get_id('some long string with a tid [20010732.003] in it somewhere'); print "ID: $id\n"; # 20010732.003 METHODS ======= new Create new Perlbug::TM object: my $do = Perlbug::TM->new(); new_id Generate new_id for perlbug - YUK get_id Determine if the string contains a valid bug ID. my ($ok, $tid) = $obj->get_id($str); AUTHOR ====== Chris Masto chrism@netmonger.net and Richard Foley perlbug@rfi.net Oct 1999  File: pm.info, Node: Perlbug/Table, Next: Perlbug/Test, Prev: Perlbug/TM, Up: Module List Table access ************ NAME ==== Perlbug::Table - Table access DESCRIPTION =========== Simple access to all database tables USAGE ===== my $o_bug = $Perlbug::Table->new('BUG', 'ticketid'); print "Our table has ".$o_bug->columns." columns\n"; my $h_data = $o_bug->fetch($bug_id); print "Bug subject: ->$$h_data{'subject'}<- \n"; METHODS ======= new Call with table name my $o_message = $Perlbug::Table->new('MESSAGE', 'primarykey'); If 'primarykey' is not given, it will be built from "ref($class).'ID'": no support for multiple column primary key combos, yet.  File: pm.info, Node: Perlbug/Test, Next: Perlbug/Testing, Prev: Perlbug/Table, Up: Module List Perlbug test module placeholder ******************************* NAME ==== Perlbug::Test - Perlbug test module placeholder DESCRIPTION =========== x SYNOPSIS ======== y METHODS ======= new Create new Perlbug::Test object: my $o_test = Perlbug::Test->new(); # generic my $o_email_test = Perlbug::Test->new('Email'); # guess :-) AUTHOR ====== Richard Foley perlbug@rfi.net 2000  File: pm.info, Node: Perlbug/Testing, Next: Perlbug/Web, Prev: Perlbug/Test, Up: Module List Perlbug testing module ********************** NAME ==== Perlbug::Testing - Perlbug testing module DESCRIPTION =========== Utility functions for Perlbug test scripts. If run within a 'make test' sequence, the prints will normally only appear from the todo, ok and `notOK' calls. Output is seen from output when `TEST_VERBOSE' is set to 1, or when the script is being run directly. Note that files with iseven(filename)s (test_2, test_8, etc) are normally expected to succeed with the given function test, and odd names are expected to fail, thus giving a checkable failure. Names with only a zero, ie: my_test_0 are purely placeholders, and should be ignored. SYNOPSIS ======== use Perlbug::Testing; use Testing; plan('todo' => 8); # will do nine(9) my $test = 0; my $o_test = Perlbug::Testing->new('Email'); # currently ignored my @tests = get_tests('testmails/head2head', qw(this that etc)); my ($i_ok, $data) = $o_test->check_header(*STDIN); # for example if ($i_ok == 1) { # == 1 (hopefully :-) || 0 :-( ok($test); } else { notok($test); } output($test, 'data'); output("done test($test)"); METHODS ======= new Create new Perlbug::Testing object: my $o_test = Perlbug::Testing->new(); # generic my $o_email_test = Perlbug::Testing->new('Email'); # guess :-) output prints given args iseven Return 0(odd) or 1(even) based on last number of given filename my $num = iseven($filename); get_tests Wraps getting test material from test directory, incorporates test count. my @test = get_tests($t_dir, qw(this that and the other)); AUTHOR ====== Richard Foley perlbug@rfi.net 2000  File: pm.info, Node: Perlbug/Web, Next: Persistence/Database/SQL, Prev: Perlbug/Testing, Up: Module List Web interface to perlbug database. ********************************** NAME ==== Perlbug::Web - Web interface to perlbug database. DESCRIPTION =========== Methods for web access to perlbug database via *Note Perlbug: Perlbug, module. SYNOPSIS ======== my $o_web = Perlbug::Web->new; print $o_web->header; print $o_web->request('help'); print $o_web->footer; METHODS ======= new Create new Perlbug::Web object. my $web = Perlbug::Web->new; setup Setup Perlbug::Web $o_perlbug->setup($cgi); check_user Access authentication via http, we just prime ourselves with data from the db as well. Should really be integrated as a database lookup via Apache, but we do not know this will be the webserver? header Return consistent header. print $web->header; switch Parse switch request Handle all web requests overview Wrapper for doo method graph Display pie or mixed graph for category of bugs etc., mixed to come. nid Wrapper for don note access tid Wrapper for dot test id access pid Wrapper for dop patch id access bid Wrapper for dob bugid access patches Wrapper for dop patchid access uid Wrapper for dou user/administrator access hist History mechanism for bugs and users. Move formatting to Format::history !!! headers Headers for all objects (m, n, p, t) by id mheader Headers for message pheader Headers for patches nheader Headers for notes theader Headers for tests bidmids Wrapper for bugid and messageid access mids Wrapper for retrieve by messageid access delete Wrapper for delete access update Wrapper for update access nocc Wrapper for nocc update access sql_query Open field sql query processor web_query Form bug search web query results current_buttons Returns array of relevant buttons by context key my @buttons = $o_web->current_buttons('search update reset', scalar(@uids), [$colspan]); footer Return consistent footer. print $web->footer; administrators List of administrators spec Returns specifications for the Perlbug system. help Web based help menu for perlbug. print $web->help; administration_failure Deal with a failed administration attempt my $i_ok = $self->administration_failure($bid, $user, $commands); todo To do list, may be appended to adminfaq adminFAQ search Search form into result with chosen params as defaults... case Handle case sensitivity from web search form. format_web_query Produce SQL query for bug search from CGI query. my $query = $web->format_web_query; wildcard Convert '*' into '%' for sqlquery my $string = $self->wildcard('5.*'); web_update For bugs and users tenify Create range of links to split (by tens or more) bugids from web query result. $self->tenify(\@_bids, 7); # in chunks of 7 range Store and retrieve range of bugs, swap between using filesystem and database? $id = $o_web->range($id, $data); # get and set comment Return string as html comment my $commented = $o_web->comment(qq||); hide AUTHOR ====== Richard Foley perlbug@rfi.net Oct 1999