I am currently stuck on a personal project/learning project of mine on my personal server running Linux Fedora. I took an old open-source web chat called Ralf's Chat from sourceforge and I'm trying to modernize it, update and add a few features. It is a Perl/CGI script using MySQL database to store data and it displays chat messages and all other data (settings page, input form and users online list) via HTML frames which I am also trying to do away with and use newer methods. The problem where I am stuck is trying to use AJAX to smoothly load data and send incoming data to the server instead of relying on the annoying and disruptive way it currently uses which is via use of meta http-equiv refresh tags. Unfortunately I am not sure exactly where in this script to do so or the right way to code it as I have yet to use AJAX side of Javascript.
The script currently has the following scripts and their purpose is as follows:
- Chat.cgi - handles chat/message stuff Chat2.cgi - specifies all the
userlevel, session, settings, profile, etc. related stuff Chatpm.cgi
- Post message script Chatsa.cgi - "Still alive" or users online script. Config.cgi - stores config variables
- Shared.cgi - contains shared/misc. subroutines
and all the corresponding html pages joined together via HTML frames in html/chatframes.cgi which must go!
Here is the current subroutines that handles posting messages if this will help, this is from shared.cgi
my $pm_type = $_[0];
my $pm_from = $_[1];
my $pm_to = $_[2];
my $pm_message = $_[3];
if ($pm_message) {
# checking recipient (if set), checking sender, too, for preventing infinite loop
if ($pm_to and not &nick_exists($pm_to) and &nick_exists($pm_from)) {
&postmsg("command", "MSG", $session{'name'}, &msgargs($msg{'unf'}, [$pm_to]));
} else {
my $message_id = &gettime.".$$.";
if ($msgcount++ > 'Y') {
$msgcount = 'A';
}
$message_id .= $msgcount;
for (my $n=0; $n<2; $n++) {
$message_id .= chr(int(rand(26))+65);
}
# kill linebreaks
$pm_message =~ s/
/ /g;
my $msg;
if ($pm_type eq "public") {
# LOG PUBLIC MSG
&logfile("[MSG] $session{'name'}: $pm_message", 3);
# remove old public messages
if ($use_dbi) {
# <DBI>
$sth = $dbh->prepare("SELECT message_timestamp FROM $data{'messages'} WHERE type='public' AND room=$session{'room'} ORDER BY message_timestamp DESC");
$sth->execute;
my $i = 1;
while (my $row = $sth->fetchrow_arrayref) {
$i++;
if ($i >= $message_limit) {
$dbh->do("DELETE FROM $data{'messages'} WHERE message_timestamp<$$row[0] AND room=$session{'room'}");
last;
}
}
# </DBI>
} else {
# <NODBI>
&file_open("messages", ">");
my @messages = <READFILEMESSAGES>;
my @messages2;
my $i = 1;
while (@messages) {
my $temp = pop @messages;
my @temp = split(/;;/, $temp);
unshift @messages2, $temp if ($i < $message_limit or $temp[6] != $session{'room'});
$i++ if ($temp[0] eq "public");
}
foreach (@messages2) {
print WRITEFILEMESSAGES;
}
&file_close("messages", ">");
# </NODBI>
}
$pm_message = &wash_msg($pm_message);
$msg = "<B>$pm_from</B>: $pm_message";
} elsif ($pm_type eq "private") {
$pm_message = &wash_msg($pm_message);
$msg = "<B>[$pm_from]</B> $pm_message";
&logfile("[PRIVATE] FROM: $pm_from TO: $pm_to: $msg", 3);
} elsif ($pm_type eq "private_out") {
$pm_message = &wash_msg($pm_message);
$msg = "<B>[->$pm_from]</B> $pm_message";
} elsif ($pm_type eq "action") {
$msg = "$pm_message";
} elsif ($pm_type eq "command") {
$msg = "<B>[$pm_from]</B> $pm_message";
} elsif ($pm_type eq "memo") {
$msg = "<B>[$pm_from]</B> $pm_message";
} elsif ($pm_type eq "me") {
$pm_message = &wash_msg($pm_message);
$msg = "<B>*$pm_from $pm_message</B>";
} elsif ($pm_type eq "plain") {
$msg = "$pm_message";
}
if ($pm_type ne "action") {
if ($query{'selected_action'}) {
$msg = "<IMG SRC="$actions{$query{'selected_action'}}" ALIGN=LEFT>$msg";
}
if ($posting_time) {
$msg = "<SPAN CLASS="time">".strftime($posting_time_format, localtime($timestamp))."</SPAN> $msg";
}
if ($session{'color'} ne "standard" and $pm_type =~ /^(public|private|private_out|memo|me)$/) {
$msg = "<FONT COLOR="#$session{'color'}">$msg</FONT>";
}
}
# remove old private messages
if ($pm_to) {
if ($use_dbi) {
# <DBI>
$sth = $dbh->prepare("SELECT message_timestamp FROM $data{'messages'} WHERE message_to='$pm_to' ORDER BY message_timestamp DESC");
$sth->execute;
my $i = 1;
while (my $row = $sth->fetchrow_arrayref) {
$i++;
if ($i >= $message_limit) {
$dbh->do("DELETE FROM $data{'messages'} WHERE message_timestamp<$$row[0] AND message_to='$pm_to'");
last;
}
}
# </DBI>
} else {
# <NODBI>
&file_open("messages", ">");
my @messages = <READFILEMESSAGES>;
my @messages2;
my $i = 1;
while (@messages) {
my $temp = pop @messages;
my @temp = split(/;;/, $temp);
unshift @messages2, $temp if ($i < $message_limit or !$temp[2]);
$i++ if (lc($temp[2]) eq lc($_[2]));
}
foreach (@messages2) {
print WRITEFILEMESSAGES;
}
&file_close("messages", ">");
# </NODBI>
}
}
if ($use_dbi) {
# <DBI>
$msg =~ s/'/'/g;
$sth = $dbh->do("INSERT INTO $data{'messages'} VALUES ('$pm_type', '$pm_from', '$pm_to', '$msg', $timestamp, '$message_id', $session{'room'})");
# </DBI>
} else {
# <NODBI>
&file_open("messages", "a");
print APPENDFILEMESSAGES "$pm_type;;$pm_from;;$pm_to;;$msg;;$timestamp;;$message_id;;$session{'room'}
";
&file_close("messages", "a");
# </NODBI>
}
}
}
}
sub wash_msg { # $_[0] msg to 'wash'
"e($_[0]);
# link urls
# *://* (eg. http or ftp
$_[0] =~ s/(w*://[^ "]+)/<A HREF="$scriptgu_name?$1" TARGET="_blank">$1</A>/g;
# mailto:*
$_[0] =~ s/(mailto:.+)/<A HREF="$1">$1</A>/g;
# Bad Word Filter
foreach (@bad_words) {
$_[0] =~ s/Q$_E/$filter/gi;
}
# Smileys / Replace
while ((my $key, my $value) = each %replace) {
&kill_special_chars($key);
&kill_special_chars($value);
$_[0] =~ s/Q$keyE/$value/g;
}
return $_[0];
}
sub kill_special_chars {
# kill ;
$_[0] =~ s/;/;/g;
# kill '
$_[0] =~ s/'/'/g;
# kill
$_[0] =~ s/\/\/g;
}
sub quote { # quote special characters
&kill_special_chars($_[0]);
# kill html-tags
$_[0] =~ s/</</g;
$_[0] =~ s/>/>/g;
$_[0] =~ s/"/"/g;
# kill linebreaks
$_[0] =~ s/(
|
|
)/<BR>/g;
# kill trailing ;
$_[0] =~ s/;$/; /g;
}
sub unquote { # unquote special characters
$_[0] =~ s/<BR>/
/g;
}
The part in is for using the optional flat-file mode which I am not, I'm using the DBI.
Here is the current chatframes.cgi which displays all script output and needs to use something other than frames
sub chatframes_html {
print << "[END]";
<HTML>
<HEAD>
<TITLE>$html_title</TITLE>
</HEAD>
[END]
if ($banner_url) {
print << "[END]";
<FRAMESET ROWS="65,*,60" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
<FRAME SRC="$banner_url" SCROLLING=NO>
[END]
} else {
print << "[END]";
<FRAMESET ROWS="*,60" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
[END]
}
print << "[END]";
<FRAMESET COLS="*,150" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
[END]
if ($session{'streaming'}) {
print << "[END]";
<FRAME NAME="main" SRC="$scriptst_name?action=stream&id=$query{'id'}&pause=$pause">
[END]
} else {
print << "[END]";
<FRAME NAME="main" SRC="$script_name?action=chat&id=$query{'id'}&pause=$pause#end">
[END]
}
if ($room) {
print << "[END]";
<FRAMESET ROWS="*,70" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>
<FRAME SRC="$scriptsa_name?action=stillalive&id=$query{'id'}">
<FRAME SRC="$script2_name?action=rooms&id=$query{'id'}" SCROLLING=NO>
</FRAMESET>
[END]
} else {
print << "[END]";
<FRAME SRC="$scriptsa_name?action=stillalive&id=$query{'id'}">
[END]
}
print << "[END]";
</FRAMESET>
<FRAME SRC="$scriptpm_name?action=chatinput_html&id=$query{'id'}" scrolling=no>
</FRAMESET>
</HTML>
[END]
}
1;
# EOF
Any help would be greatly appreciated. Thank you.
question from:
https://stackoverflow.com/questions/65858503/how-do-i-utilize-ajax-within-an-older-perl-cgi-web-chat-script-that-currently-us