--- loncom/interface/lonmsg.pm 2001/08/13 19:36:39 1.20
+++ loncom/interface/lonmsg.pm 2007/05/02 19:56:34 1.202
@@ -1,71 +1,196 @@
# The LearningOnline Network with CAPA
-#
# Routines for messaging
#
-# (Routines to control the menu
+# $Id: lonmsg.pm,v 1.202 2007/05/02 19:56:34 raeburn Exp $
+#
+# Copyright Michigan State University Board of Trustees
+#
+# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
+#
+# LON-CAPA 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.
+#
+# LON-CAPA 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.
#
-# (TeX Conversion Module
+# You should have received a copy of the GNU General Public License
+# along with LON-CAPA; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
-# 05/29/00,05/30 Gerd Kortemeyer)
+# /home/httpd/html/adm/gpl.txt
#
-# 10/05 Gerd Kortemeyer)
+# http://www.lon-capa.org/
#
-# 10/19,10/20,10/30,
-# 02/06/01 Gerd Kortemeyer
-# 07/27 Guy Albertelli
-# 07/27,07/28,07/30,08/03,08/06,08/08,08/09,08/10,8/13 Gerd Kortemeyer
package Apache::lonmsg;
+=pod
+
+=head1 NAME
+
+Apache::lonmsg: supports internal messaging
+
+=head1 SYNOPSIS
+
+lonmsg provides routines for sending messages.
+
+Right now, this document will cover just how to send a message, since
+it is likely you will not need to programmatically read messages,
+since lonmsg already implements that functionality.
+
+The routines used to package messages and unpackage messages are not
+only used by lonmsg when creating/extracting messages for LON-CAPA's
+internal messaging system, but also by lonnotify.pm which is available
+for use by Domain Coordinators to broadcast standard e-mail to specified
+users in their domain. The XML packaging used in the two cases is very
+similar. The differences are the use of $uname and
+$udom in stored internal messages, compared
+with $email in stored
+Domain Coordinator e-mail for the storage of information about
+recipients of the message/e-mail.
+
+=head1 FUNCTIONS
+
+=over 4
+
+=cut
+
use strict;
-use Apache::lonnet();
-use vars qw($msgcount);
-use HTML::TokeParser;
-use Apache::Constants qw(:common);
+use Apache::lonnet;
+use HTML::TokeParser();
+use Apache::lonlocal;
+use Mail::Send;
+use LONCAPA qw(:DEFAULT :match);
+
+{
+ my $uniq;
+ sub get_uniq {
+ $uniq++;
+ return $uniq;
+ }
+}
# ===================================================================== Package
sub packagemsg {
- my ($subject,$message,$citation)=@_;
- $message=~s/\\<\;/g;
- $message=~s/\>/\>\;/g;
- $citation=~s/\\<\;/g;
- $citation=~s/\>/\>\;/g;
- $subject=~s/\\<\;/g;
- $subject=~s/\>/\>\;/g;
+ my ($subject,$message,$citation,$baseurl,$attachmenturl,
+ $recuser,$recdomain,$msgid,$type,$crsmsgid,$symb,$error,$recipid)=@_;
+ $message =&HTML::Entities::encode($message,'<>&"');
+ $citation=&HTML::Entities::encode($citation,'<>&"');
+ $subject =&HTML::Entities::encode($subject,'<>&"');
+ #remove machine specification
+ $baseurl =~ s|^http://[^/]+/|/|;
+ $baseurl =&HTML::Entities::encode($baseurl,'<>&"');
+ #remove machine specification
+ $attachmenturl =~ s|^http://[^/]+/|/|;
+ $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');
+ my $course_context = &get_course_context();
my $now=time;
- $msgcount++;
- my $partsubj=$subject;
- $partsubj=&Apache::lonnet::escape($partsubj);
- $partsubj=substr($partsubj,0,50);
- my $msgid=&Apache::lonnet::escape(
- $now.':'.$partsubj.':'.$ENV{'user.name'}.':'.
- $ENV{'user.domain'}.':'.$msgcount.':'.$$);
- return $msgid,
- ''.$ENV{'user.name'}.''.
- ''.$ENV{'user.domain'}.''.
+ my $msgcount = &get_uniq();
+ unless(defined($msgid)) {
+ $msgid = &buildmsgid($now,$subject,$env{'user.name'},$env{'user.domain'},
+ $msgcount,$course_context,$symb,$error,$$);
+ }
+ my $result = ''.$env{'user.name'}.''.
+ ''.$env{'user.domain'}.''.
''.$subject.''.
- ''.
- ''.$ENV{'SERVER_NAME'}.''.
+ '';
+ if (defined($crsmsgid)) {
+ $result.= ''.$course_context.''.
+ ''.$env{'request.course.sec'}.''.
+ ''.$msgid.''.
+ ''.$crsmsgid.''.
+ ''.$message.'';
+ return ($msgid,$result);
+ }
+ $result .= ''.$ENV{'SERVER_NAME'}.''.
''.$ENV{'HTTP_HOST'}.''.
''.$ENV{'REMOTE_ADDR'}.''.
- ''.$ENV{'browser.type'}.''.
- ''.$ENV{'browser.os'}.''.
- ''.$ENV{'browser.version'}.''.
- ''.$ENV{'browser.mathml'}.''.
+ ''.$env{'browser.type'}.''.
+ ''.$env{'browser.os'}.''.
+ ''.$env{'browser.version'}.''.
+ ''.$env{'browser.mathml'}.''.
''.$ENV{'HTTP_USER_AGENT'}.''.
- ''.$ENV{'request.course.id'}.''.
- ''.$ENV{'request.role'}.''.
- ''.$ENV{'request.filename'}.''.
- ''.$msgid.''.
- ''.$message.''.
- ''.$citation.'';
+ ''.$course_context.''.
+ ''.$env{'request.course.sec'}.''.
+ ''.$env{'request.role'}.''.
+ ''.$env{'request.filename'}.''.
+ ''.$msgid.'';
+ if (ref($recuser) eq 'ARRAY') {
+ for (my $i=0; $i<@{$recuser}; $i++) {
+ if ($type eq 'dcmail') {
+ my ($username,$email) = split(/:/,$$recuser[$i]);
+ $username = &unescape($username);
+ $email = &unescape($email);
+ $username = &HTML::Entities::encode($username,'<>&"');
+ $email = &HTML::Entities::encode($email,'<>&"');
+ $result .= ''.
+ $email.'';
+ } else {
+ $result .= ''.$$recuser[$i].''.
+ ''.$$recdomain[$i].'';
+ }
+ }
+ } else {
+ $result .= ''.$recuser.''.
+ ''.$recdomain.'';
+ }
+ $result .= ''.$message.'';
+ if (defined($citation)) {
+ $result.=''.$citation.'';
+ }
+ if (defined($baseurl)) {
+ $result.= ''.$baseurl.'';
+ }
+ if (defined($attachmenturl)) {
+ $result.= ''.$attachmenturl.'';
+ }
+ if (defined($symb)) {
+ $result.= ''.$symb.'';
+ if ($course_context ne '') {
+ if ($course_context eq $env{'request.course.id'}) {
+ my $resource_title = &Apache::lonnet::gettitle($symb);
+ if (defined($resource_title)) {
+ $result .= ''.$resource_title.'';
+ }
+ }
+ }
+ }
+ if (defined($recipid)) {
+ $result.= ''.$recipid.'';
+ }
+ return ($msgid,$result);
+}
+
+sub get_course_context {
+ my $course_context;
+ if (defined($env{'form.replyid'})) {
+ my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)=
+ split(/\:/,&unescape($env{'form.replyid'}));
+ $course_context = $origcid;
+ }
+ foreach my $key (keys(%env)) {
+ if ($key=~/^form\.(rep)?rec\_(.*)$/) {
+ my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid) =
+ split(/\:/,&unescape($2));
+ $course_context = $origcid;
+ last;
+ }
+ }
+ if ($course_context eq '') {
+ $course_context = $env{'request.course.id'};
+ }
+ return $course_context;
}
# ================================================== Unpack message into a hash
sub unpackagemsg {
- my $message=shift;
+ my ($message,$notoken)=@_;
my %content=();
my $parser=HTML::TokeParser->new(\$message);
my $token;
@@ -73,7 +198,28 @@ sub unpackagemsg {
if ($token->[0] eq 'S') {
my $entry=$token->[1];
my $value=$parser->get_text('/'.$entry);
- $content{$entry}=$value;
+ if (($entry eq 'recuser') || ($entry eq 'recdomain')) {
+ push(@{$content{$entry}},$value);
+ } elsif ($entry eq 'recipient') {
+ my $username = $token->[2]{'username'};
+ $username = &HTML::Entities::decode($username,'<>&"');
+ $content{$entry}{$username} = $value;
+ } else {
+ $content{$entry}=$value;
+ }
+ }
+ }
+ if (!exists($content{'recuser'})) { $content{'recuser'} = []; }
+ if ($content{'attachmenturl'}) {
+ my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);
+ if ($notoken) {
+ $content{'message'}.='