Beefy Boxes and Bandwidth Generously Provided by pair Networks Frank
There's more than one way to do things


by epoptai (Curate)
on Mar 12, 2001 at 19:37 UTC ( #63816=sourcecode: print w/ replies, xml ) Need Help??

Category: Chatterbox Clients
Author/Contact Info epoptai
Description: framechat is a Perl/CGI XML CB client modeled on the chatterbox frameset at perlmonks. Includes message inbox, private chat, history, xp nodelet, rep change tracker, new nodes ticker, links to vital nodes and more.

To use just fill in the configuration variables (first!) and call it from your local web server.

functions include:

- emulates perlmonks chatterbox linking standards
- integrated message inbox with cc to self option
- new nodes ticker
- rep change ticker with history
- extract and display $NORM
- textarea input for editing extended messages
- large messages chunked for multiple send
- super search form with perldoc, cpan, google and babelfish
- launchpad for accessing your favorite search engines

Run it and select help for more info.

WARNING: Client authentication makes framechat more secure but exercise caution. Do not allow public access to your installation of framechat!

New in 2.0

  • New nodes ticker!
  • Rep change ticker with history!
  • Client login & quit for better security.
  • Create & edit optional external config file.
  • Tools control panel to see & set parameters.
  • /ignore and /unignore and see who's being ignored.
  • /logout and /login implemented.
    • Not in the userlist but still see chat.
    • All links to perlmonks become logged out.
    • History still functions if enabled.
    • Logout disables node title lookup.


  • Faster thanks to less print statements.
  • More robust error handling (esp. xml parsing).
  • XP nodelet now shows xp gain and loss messages (Ack!)
  • inbox/launchpad/newnode frame can remember state.
  • Notes added to update notification.

    Fixed in 2.0:

  • Bug in link parser that caused italic history after an unclosed i tag.
  • Last \$norm should now appear when code updated.
  • Code is less redundant and more readable.

    Fixed in 2.01:

  • A new node with 0 rep showed +0 change (a printf feature).
  • New nodes and check update didn't work if proxy in use.
  • New nodes loadtime was 1 second off.

    Fixed in 2.02:

  • Empty document error if history file for present day didn't exist.
  • IIS breakage addressed with a new config var: $broken.
  • Change to talk frame enables submit with Tab+Enter sequence (thanks grinder).
  • <i> tags would italicize cb text, oops.
  • Rep related data files now 50% smaller.
  • Added config file syntax status feedback and warnings.
  • Improved the help and tools sections.
  • NEW: Node rep history graph!

    Fixed in 2.03:

  • control chrs in chat xml not being stripped due to missing /d modifier on tr in sub fixxml.
  • client authentication erroneously succeeded if username and password not defined.

    Fixed in 2.04:

  • Repaired the chat frame and norm parser to conform with changes at perlmonks.
  • Added support for the latest shortcut tags: pad, kobe, jargon, perldoc. If you use an external config file these need to be added to the @tags array so they appear in the pulldown menu in the input frame, as well as a few items added to the %launch_urls hash.

To run framechat under mod_perl use OeufMayo's mod_perl patch.

At 102k framechat 2.04 is too large to be posted to perlmonks! Download it from

The file to download named is a plain text file. You won't be accessing a demo or any kind of CGI script, just the source code.

Here's a screenshot

Comment on framechat
Re: framechat (XP progress bar)
by OeufMayo (Curate) on Mar 13, 2001 at 00:27 UTC

    First, big ++ to epoptai for this really nice CB client with tons of functionnalities. Hey! it even links to Babelfish!
    Though this is a realy cool piece of code, I wanted to add a nifty progress bar (like the one in the Tk Client), so here it is (you may want to change the colors to git your favorite theme)

    Line 290:

    my$nxtlvl = ($xpinfo->{'level'}+1); # line 290 my@levelXP = qw(0 0 20 50 100 200 500 1000 1600 2300 3000); my $percentXP = int(( ($xpinfo->{'xp'} - $levelXP[$xpinfo->{'level'}]) + / ($xpinfo->{'xp'}-$levelXP[$xpinfo->{'level'}]+$xpinfo->{'xp2nextle +vel'})) * 100) ; my @XPcolors = qw(4A2625 71131C 9A0213 BD0606 FF0000 9E3B00 1D8700 41A +F00 12E800 00FF00); my $rest = abs(100-$percentXP);

    Line 297

    <table border="0" height="100%" width="100%" cellpadding="0" cellspaci +ng="0" align="center"> # Line 297 <tr><td><table border="0" cellpadding="0" cellspacing="0" width="100%" +><tr><td bgcolor="#$XPcolors[int($percentXP/10)-1]" width="$percentXP +%">&nbsp;</td><td width="$rest%"bgcolor="#CCCCCC">&nbsp;</td></tr></t +able></td></tr>

    Update: Added coloration according to the user's progress (gradient from red to green)

    Cheers, OeufMayo

    my $OeufMayo = new PerlMonger::Paris({http => ''});</kbd>
Re: framechat
by a (Friar) on Mar 14, 2001 at 03:38 UTC
    On Solaris 2.5/Apache I got a few troubles. One, ENV{TEMP} wasn't defined, so I did:
    my $temp = $ENV{TEMP} || "/tmp"; ... # so then my $today = "$temp/$yr$mo$mday.txt"; my $normfile = "$temp/.norm"; my $cookies = "$temp/.cookies";
    I also was getting a few 100 uninit errors so I:
    if($i{sexisgood} and $i{'sexisgood'}=~/submit/){&msgsend()} if($i{op} and $i{'op'}=~/message/){&sendit($i{'message'})} if ( $i{n} ) { if($i{'n'}=~/norm/){&norm()} if($i{'n'}=~/self/){&self()} } print header; if ( $i{n} ) { if($i{'n'}=~/hist/){&history()} if($i{'n'}=~/users/){&users()} ... if($i{'n'}=~/help/){&help()} } else { # if $i{n} #unless($i{'n'} ){ print<<HTML; <title>framechat</title> <frameset cols="*,20%" border="$fborder"> ... </frameset> </frameset> HTML } # if ${n} exit
    and finally, all my chat/msgs were showing up as arrar refs so I followed all the makelinks calls:
    &makelinks($message->{'content'}); if ( ref($content) eq "ARRAY" ) { $content = join("", @{$content}); }
    to get back text. I think:
    my $content = &makelinks($message->{'content'});
    would be a little nicer than the global $content, unless you need to get at it elsewhere. Finally, and, this isn't probably your doing, but all my boxes (behind the black) say:
    Can't use string ("<CHATTER><INFO site="http://perl") as a symbol ref while "strict refs" in use at /usr/local/lib/perl5/site_perl/5.005/i86pc-solaris/XML/Parser/ + line 451.
    I fear my xml isn't up to date. Pretty cool stuff, and well worth all that testing, though I loan you, heck give you the 50 or so extra spaces to use after 'my' ;-> Thanks for the code!


      Thank you a, one at a time:

      Your first fix to temp didn't work for me, changing the || to "or" worked, but generated a warning about useless use in void context. The following works for me:

      if(-d "/tmp"){$temp = "/tmp"} else {$temp = $ENV{TEMP}}
      I'll take your advice about checking for uninitialized variables. I was being lazy.

      I don't understand your next problem with array refs, and suspect it's related to the last problem you associate with outdated xml modules, but will include your fix to increase compatability.

      $content is global because it's used in three subroutines.

      Your final problem is troubling. I'd like to know which version of Expat to check for so i could throw a nicer warning with a link to the module on cpan.

      ps - Thanks to OeufMayo for the cool xp progress patch.

        Replies then: the idea was to handle a not filled in ENV TEMP. The || works fine here, e.g. try
        use strict; $ENV{TEMP} = "goo go"; my $temp = $ENV{TEMP} || "/tmp"; print "t $temp\n";
        what do you get when it doesn't work? I guess for max portability, you'd probably want a combo of your and my fix, I was just trying to avoid assuming ENV{TEMP} was valid (as mine wasn't ;-).

        I understand $content is used in 3 places, but isn't it being filled in each time by makelinks? If one sub were filling it in (beside makelinks) and another needing access, global, but it appears its used 'locally' each time it has data in it. A style quibble, really, I just was trying to figure out the array bug and had to poke a bit deeper to see makelinks was filling in $content. It appears, w/ data, by 'magic' otherwise. is 2.29, I'll try upgrading things to see if that's the trouble. Huh. Perhaps this ver returns an array ref instead of a string?

        Update: upgraded to Parser 2.30 - same stuff. Both the array ref and the XML as ref problem. I'll keep poking - perhaps a debug box where we could see the xml as it arrives?

        Update 2:Hmm. If I turn off 'fatalsToBrowser' no complaints and it appears the complaint is from Expat doing an eval around:$ioref = *{$arg}{IO}; where $arg is the incoming xml. I gather its supposed to die ($@ is my error msg) but why this floats up to cgi::carp for me and not you ???


Re: framechat (tweaked for proxy, prob w/Chat+Userlist dl)
by ybiC (Prior) on Mar 24, 2001 at 01:49 UTC
    Waay cool, epoptai!

    My boxes are behind a Squid proxy, so I added the following (first line to config vars section, second line to login sub)

    my $proxy = 'http://proxy.dom:port'; $ua->proxy(http=>"$proxy");
    Everything appears to work, except the Chat and Userlist frames which report "download failed, try again?".

    Update: Chat+Userlist download fixed by epoptai below.

    Update for authenticated proxy: First two lines to config vars section, third line immediately above $req=POST in login sub
    (Works in other scripts from behind MS-Proxy, but as yet untested with framechat.)

    my $proxyid = ''; my $proxypass = ''; $req->proxy_authorization_basic("$proxyid", "$proxypass");

    Update: corrected $req->proxy... syntax above. Thanks, epoptai   8^)
        stumbling toward Perl Adept
        (it's pronounced "why-bick")

      Alternatively, you can setenv HTTP_PROXY=
      And let LWP handle it automagically.

      Update: There was an old patch here. The source code has since been updated, and this node edited to make the root a little smaller.
Re: framechat
by Boldra (Deacon) on Apr 17, 2001 at 12:28 UTC
    I love the framechat, many thanks Epoptai! I do enjoy the little "@verb" game you played (an addition to Vrooms own toy).

    I've added a few extra verbs to my own version of framechat, here's my new list:
    my @verb = qw(lurking romping hanging wandering stumbling sneaking floating hovering levitating scrambling shuffling fumbling fiddling trapsing crawling fart-arsing dancing prancing walking sock-sliding hopping astrally-projecting);
    Does anyone else have any additions?

    (if you aren't sure what this is about, see the first 4 lines of the users sub)
Re: framechat (mod_perl patch)
by OeufMayo (Curate) on Jun 12, 2001 at 19:47 UTC

    Once again epoptai++ for this really nice update.

    Here's a patch for the mod_perl users which allows them to run framechat with mod_perl. This is really faster than the regular version because the whole script is only loaded once, and all the script has to do then is to fetch the XML and print it.

    It is implemented as a Apache::Registry handler, if I got some time and if there's enough interest, I could maybe come up with a full blown Apache::Framechat for all the CB addicts around.

    #!/usr/bin/perl open (CGI, $ARGV[0]) or die "Cannot open $ARGV[0]:$!\n"; open (MOD, ">") or die "Cannot open +$!\n"; { local $/; $cgi = <CGI>; } # you know epoptai's spacebar sometime stuck... :P $cgi =~ s[my\s*%i\s*=\s*map\s*{\s*\$_\s*=>\s*param\(\$_\)}\s*param;][$ +&;\nsub mod_perl_run {]is; $cgi =~ s[</noframes></html>~;.exit][$&\n}]is; $cgi =~ s[^__END__][=cut]is; print MOD $cgi . "\n'mod_perl is cool.';"; open (MOD2, ">") or die "Cannot open launch_framec$!\n"; print MOD2 <<'__script__'; #!perl use strict; require "./"; mod_perl_run(); __script__ print STDERR "Done. You can now run!\n";

    framechat2 mod-perl

    #!/usr/bin/perl open (CGI, $ARGV[0]) or die "Cannot open $ARGV[0]:$!\n"; open (MOD, ">") or die "Cannot open +$!\n"; { local $/; $cgi = <CGI>; } # you know epoptai's spacebar sometime stuck... :P $cgi =~ s[# mod_perl_patch_begin][# mod_perl_patch_begin\nsub mod_perl +_run {]is; $cgi =~ s[# mod_perl_patch_end][# mod_perl_patch_end\n}]is; print MOD $cgi . "\n1;"; open (MOD2, ">") or die "Cannot open launch_framec$!\n"; print MOD2 <<'__script__'; #!perl use strict; require "./"; mod_perl_run(); __script__ print STDERR "Done. You can now run!\n";

    20010613 - update: Fixed the __END__ token problem, and returns a true value;

    20010825 - update: Updated the patch for framechat2

    my $OeufMayo = new PerlMonger::Paris({http => ''});</kbd>
      I'm not quite sure I understand where this fits in the framechat2 scheme of things. It's an Apache::Registry handler, so I originally thought it belongs in, which is called from my PerlRequire line in httpd.conf, but that didn't work, and reading the code, I don't see where you hook into $WEB/framechat/ (or whatever).

      Can you provide a quick installation blurb on this so I can figure out how to get this working under mod_perl?

      What is

      What is

      Update: Apparently the patch collides directly with my existing, and will need some more investigating to get them to co-exist. My looks like this:

      use strict; $ENV{GATEWAY_INTERFACE} =~ /^CGI-Perl/ or die "GATEWAY_INTERFACE not P +erl!"; use Apache::Registry (); use CGI (); CGI->compile(':all'); use CGI::Carp (); use DBI (); use DBD::mysql ();
Re: framechat
by grinder (Bishop) on Aug 28, 2001 at 13:07 UTC
    I added a couple of links to the bottom right-hand frame, to get to reputer and xNN (because everyone has them too, right?).

    Change sub ctrl to something like this:

    sub ctrl { # display links and $NORM if(-e $normfile){ $norm = io('read',$normfile,$norm)} else {$norm = 'n +/a'} $norm = 'n/a' unless $norm =~ /\S/; my $extra = ''; if( $url_xnn or $url_reputer ) { $extra = '<li><nobr>'; $extra .= qq{<a href="$url_xnn" target="_blank">xNN</a>} if $url_x +nn; $extra .= '&nbsp;-&nbsp;' if $url_xnn and $url_reputer; $extra .= qq{<a href="$url_reputer" target="_blank">reputer</a>} i +f $url_reputer; $extra .= '</nobr></li>'; } my$prnt = qq~<html> $bodytag <table border="0" height="100%" width="100%" cellpadding="0" cellspaci +ng="0" align="center"> <tr><td><font size="-1">$extra

    And right up the top with the rest of the definitions, you want to add something like:

    my $url_xnn = '/cgi-bin/nn.cgi'; # url to xNN script my $url_reputer = '/cgi-bin/reputer.cgi'; # url to reputer script

    and you're all set! You can leave one or the other blank and it will do The Right Thing.

    g r i n d e r
Re: framechat
by Anonymous Monk on Apr 04, 2003 at 03:23 UTC
    Has anyone noticed the very ugly logging bug with this most-recent copy of, where it repeatedly appends the existing log to the end of the log at every refresh interval? It makes for an exponentially-growing log file, which is near-impossible to search for actual useful content.
Re: framechat
by ysth (Canon) on Feb 07, 2007 at 03:50 UTC

Back to Code Catacombs

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://63816]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2014-04-18 04:25 GMT
Find Nodes?
    Voting Booth?

    April first is:

    Results (461 votes), past polls