home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / FAQ / discus_admin_1357211388 / source / notify.pl < prev    next >
Text File  |  2009-11-06  |  10KB  |  259 lines

  1. # FILE: notify.pl
  2. # DESCRIPTION: E-mail notification of posts
  3. #-------------------------------------------------------------------------------
  4. # DISCUS COPYRIGHT NOTICE
  5. #
  6. # Discus is copyright (c) 2002 by DiscusWare, LLC, all rights reserved.
  7. # The use of Discus is governed by the Discus License Agreement which is
  8. # available from the Discus WWW site at:
  9. #    http://www.discusware.com/discus/license
  10. #
  11. # Pursuant to the Discus License Agreement, this copyright notice may not be
  12. # removed or altered in any way.
  13. #-------------------------------------------------------------------------------
  14.  
  15. use strict;
  16. use vars qw($GLOBAL_OPTIONS $PARAMS $DCONF);
  17.  
  18. ###
  19. ### notify_handler
  20. ###
  21. ### Called from posting mechanism, this calculates who should receive the
  22. ### e-mail notification, decides what to send, and sends it
  23. ###
  24.  
  25. sub notify_handler {
  26.     my ($post_id, $page_number, $postargs, $pagedata, $args) = @_;
  27.     return undef if $GLOBAL_OPTIONS->{'email'} != 1;
  28.     my $passed = {};
  29.     $passed->{topic_number} = $postargs->{topic_number};
  30.     $passed->{page_number} = $page_number;
  31.     $passed->{post_id} = $post_id;
  32.     $passed->{real_author} = $postargs->{real_author};
  33.     $passed->{group} = $postargs->{group};
  34.     $passed->{pagedata} = defined $pagedata ? $pagedata : GetPage($passed->{topic_number}, $page_number);
  35.     $passed->{modonly} = 1 if ($args->{queue} || $GLOBAL_OPTIONS->{send_mail_only_admins});
  36.     $passed->{mypost} = (grep($_->{number} == $post_id, @{ $pagedata->{messages} }))[0];
  37.     $passed->{mypost} = $postargs if ref $passed->{mypost} eq "";
  38.     $passed->{new_conversation} = 0 + $postargs->{new_conversation};
  39.     $passed->{message_is_queued} = 0 + $args->{queue};
  40.     dreq("mailer");
  41.     $passed->{mailcfg} = email_configuration_read();
  42.     my @postlist = map { $_->{number} } @{ $pagedata->{messages} };
  43.     $passed->{postlist} = \@postlist;
  44.     $passed->{first_level} = $passed->{pagedata}->{head}->{levels}->[1]->{level_number};
  45.     my $recipients = notify_calculate_recipients($passed);
  46.     if ($DCONF->{debug_email_notification} == 1) {
  47.         open (FILE, ">> $DCONF->{admin_dir}/data/debug-email-notification.out");
  48.         print FILE "---------------------------------------------------------\n";
  49.         print FILE "E-mail notification for topic $passed->{topic_number}, page $passed->{page_number}\n";
  50.         print FILE "Post # $post_id by $passed->{real_author}:$passed->{group}\n";
  51.         print FILE "Message starts a new conversation: ", ("no","yes")[$passed->{new_conversation}], "\n";
  52.         print FILE "Message is queued: ", ("no","yes")[$passed->{message_is_queued}], "\n";
  53.         print FILE "E-mail notifications sent to these recipients at ", scalar localtime(time), "\n";
  54.         foreach my $z (keys %{$recipients}) {
  55.             print FILE "\t$recipients->{$z}->{'user'} ($z) HTML: ", ("off","on")[$recipients->{$z}->{html}], "\n";
  56.         }
  57.         close (FILE);
  58.     }
  59.     return undef if scalar(keys(%{ $recipients })) == 0;
  60.     $passed->{queue} = 1 if $args->{queue};
  61.     my $messages = notify_generate_messages($recipients, $passed);
  62.     notify_send_messages($messages, $passed);
  63. }
  64.  
  65. ###
  66. ### notify_calculate_recipients
  67. ###
  68. ### Decides who will receive e-mail notification of a particular post
  69. ###
  70.  
  71. sub notify_calculate_recipients {
  72.     my ($passed) = @_;
  73.     dreq("authpass");
  74.     if ($DCONF->{pro} && $GLOBAL_OPTIONS->{database} == 1 && ! $passed->{message_is_queued}) {
  75.         dreq("notifypr-PRO");
  76.         return notifypr_sql_calculate_recipients($passed);
  77.     }
  78.     my $recipients = {};
  79.     $passed->{modonly} = 1 if $passed->{message_is_queued};
  80.     my $db = $passed->{modonly} ? "passwd" : "users,passwd";
  81.     my $rdata = read_account_file($db, undef, { returnformat => 'single_array' });
  82.     my $topic = $passed->{topic_number};
  83.     my $poster = undef;
  84.     if ($DCONF->{pro} && ! $passed->{new_conversation} && ! $passed->{message_is_queued}) {
  85.         dreq("notifypr-PRO");
  86.         $poster = notifypr_calculate_reply($passed);
  87.     }
  88.     my $priv = undef;
  89.     if ($passed->{message_is_queued}) {
  90.         dreq("fcn-priv");
  91.         $priv = read_privilege_file();
  92.     }
  93.     foreach my $acct (@{ $rdata }) {
  94.         next if $acct->{email} !~ /^([\w\+\-\.]+)\@([\w\+\-\.]+)$/;
  95.         next if $acct->{pass} =~ /^\*/;
  96.         my $d = join(":", $acct->{user}, $acct->{database} eq "passwd" ? "MODERATOR" : "users");
  97.         my $h = _notify_create_hash($acct->{notify});
  98.         if ($passed->{message_is_queued}) {
  99.             next if $acct->{'database'} ne "passwd";
  100.             next if ! check_topic_authorization($acct->{'user'}, $topic, $priv);
  101.         }
  102.         if ($acct->{user} eq $passed->{real_author} && (($acct->{database} eq "users" && $passed->{group} ne "MODERATOR") || ($acct->{database} eq "passwd" && $passed->{group} eq "MODERATOR"))) {
  103.             if ($h->{'0'}) {
  104.                 $recipients->{ _notify_email_prepare($acct->{email}) } = _notify_create_record($acct, $h);
  105.             }
  106.         } else {
  107.             if ($h->{'00'} && $poster->{$d}) {
  108.                 $recipients->{ _notify_email_prepare($acct->{email}) } = _notify_create_record($acct, $h);
  109.             }
  110.             if ($h->{$topic}->{'*'} || ($passed->{first_level} && $h->{$topic}->{$passed->{first_level}})) {
  111.                 $recipients->{ _notify_email_prepare($acct->{email}) } = _notify_create_record($acct, $h);
  112.             }
  113.         }
  114.     }
  115.     return $recipients;
  116. }
  117.  
  118. sub _notify_create_record {
  119.     my ($acct, $h) = @_;
  120.     my $r = {};
  121.     $r->{'user'} = $acct->{'user'};
  122.     $r->{'pass'} = $acct->{'pass'};
  123.     $r->{'html'} = $h->{'000'} ? 1 : 0;
  124.     $r->{'html'} = 0 if $GLOBAL_OPTIONS->{disable_html_mail} == 1;
  125.     $r->{'name'} = $acct->{'fullname'};
  126.     $r->{'name'} = "\u$acct->{user}" if ($acct->{fullname} eq "" || $acct->{fullname} eq "fullname");
  127.     return $r;
  128. }
  129.  
  130. sub _notify_create_hash {
  131.     my ($notify) = @_;
  132.     my $out = {};
  133.     foreach my $t (split(/,/, $notify)) {
  134.         if ($t =~ m|^(\d+)/|) {
  135.             my $topic = $1;
  136.             foreach my $num ( split(/&/, $') ) {
  137.                 $out->{$topic}->{$num} = 1;
  138.             }
  139.         } else {
  140.             $out->{$t}->{'*'} = 1;
  141.         }
  142.     }
  143.     return $out;
  144. }
  145.  
  146. sub _notify_email_prepare {
  147.     my $email_in = case_lower($_[0]);
  148.     return $email_in;
  149. }
  150.  
  151. ###
  152. ### notify_generate_messages
  153. ###
  154. ### Generates all desired e-mail notification messages for recipients
  155. ###
  156.  
  157. sub notify_generate_messages {
  158.     my ($recipients, $passed) = @_;
  159.     my @msg_out = ();
  160.     my $tfile = fetch_template_file("notify");
  161.     my $pg = $passed->{pagedata};
  162.     my @m = ( $passed->{mypost} );
  163.     $pg->{head}->{param} = "Messages";
  164.     $pg->{messages} = \@m;
  165.     $pg->{general}->{messages_raw} = 0;
  166.     $pg->{general}->{skip_headers} = 1;
  167.     $pg->{general}->{secure} = 1 if ! -e "$DCONF->{message_dir}/$passed->{topic_number}";
  168.     $pg->{general}->{skip_bottom} = 1;
  169.     $pg->{general}->{no_icons_shown} = 1;
  170.     $pg->{general}->{no_rating_shown} = 1;
  171.     $pg->{general}->{no_message_icons_shown} = 1;
  172.     $pg->{levels} = $passed->{pagedata}->{head}->{levels};
  173.     $pg->{general}->{is_email_notification} = 1;
  174.     my $text = templ_int("*$passed->{topic_number}page", $pg);
  175.     my $poster_email = $passed->{'mypost'}->{email};
  176.     $poster_email = $1 if $poster_email =~ m|^mailto:(.*)|i;
  177.     foreach my $key (keys(%{ $recipients })) {
  178.         my $subst = {};
  179.         $subst->{general}->{wants_html} = $recipients->{$key}->{html};
  180.         $subst->{general}->{wants_html} = 0 if $GLOBAL_OPTIONS->{disable_html_mail};
  181.         $subst->{general}->{wants_html} = 0 if $passed->{'mailcfg'}->{'1message'} == 1;
  182.         $subst->{general}->{text_html} = $text;
  183.         $subst->{general}->{is_queued} = 1 if $passed->{queue};
  184.         $subst->{postdata} = $passed->{mypost};
  185.         $subst->{general}->{topic} = $passed->{topic_number};
  186.         $subst->{general}->{page} = $passed->{page_number};
  187.         $subst->{general}->{post} = $passed->{post_id};
  188.         $subst->{general}->{user} = $recipients->{$key}->{'user'};
  189.         $subst->{general}->{pass} = $recipients->{$key}->{'pass'};
  190.         $subst->{general}->{name} = $recipients->{$key}->{'name'};
  191.         $subst->{general}->{encpass} = crypt($recipients->{$key}->{'pass'}, "cookie");
  192.         $subst->{general}->{email} = $key;
  193.         $subst->{pagedata} = $pg;
  194.         $subst->{levels} = $pg->{levels};
  195.         $subst->{general}->{poster_email} = $poster_email;
  196.         $subst->{general}->{reply_disabled} = 1 if $passed->{mailcfg}->{'1message'} == 1;
  197.         $subst->{general}->{new_conversation} = $passed->{new_conversation};
  198.         push @msg_out, notify_format_message($subst, $tfile, $key, $recipients);
  199.     }
  200.     return \@msg_out;
  201. }
  202.  
  203. ###
  204. ### notify_format_message
  205. ###
  206. ### Uses the e-mail notification template to create the formatted message
  207. ###
  208.  
  209. sub notify_format_message {
  210.     my ($subst, $tfile, $key, $recipients) = @_;
  211.     $subst->{general}->{wants_html} = 0 if $subst->{general}->{is_queued};
  212.     $subst->{general}->{wants_html} = 0 if $GLOBAL_OPTIONS->{disable_html_mail} == 1;
  213.     my $p = {};
  214.     $p->{text} = templ_int("notify", $subst, $tfile);
  215.     $p->{text} =~ s/\+\+\+\s\w+\s\+\+\+\s\d+\s\+\+\+\s(.*?)\s\+\+\+/\[$1\]/g;
  216.     $p->{text} = char_convert($p->{text}, 1, { JSP => 1, convert_html => 2 }) if ! $subst->{general}->{wants_html};
  217.     $p->{text} =~ s/(\n\n+)/"<br>" x length($1)/ge if $subst->{general}->{wants_html};
  218.  
  219.     # This doesn't truly correspond to charconvert.conf, but trust us, it looks better
  220.     $p->{text} =~ s/\\\\/\\/g;
  221.     $p->{text} =~ s/\\\{/\{/g;
  222.     $p->{text} =~ s/\\\}/\}/g;
  223.  
  224.     # Remove images and embeds from HTML-formatted e-mail messages
  225.     if (! $GLOBAL_OPTIONS->{preserve_images_in_email}) {
  226.         $p->{text} =~ s/<img.*?>//gi;
  227.         $p->{text} =~ s/<embed.*?>//gi;
  228.     }
  229.  
  230.     # Want to make it so there is no dot on a line by itself
  231.     $p->{text} =~ s/\s+\.\s+/ \. /g;
  232.  
  233.     $p->{to} = $key;
  234.     $p->{subject} = $GLOBAL_OPTIONS->{subject_line} == 0 ? $subst->{pagedata}->{head}->{me_name} :
  235.         $GLOBAL_OPTIONS->{subject_line} == 1 && $subst->{pagedata}->{head}->{me_number} != $subst->{pagedata}->{head}->{topic_number} ? join(": ", $subst->{pagedata}->{head}->{topic_name}, $subst->{pagedata}->{head}->{me_name}) :
  236.         $GLOBAL_OPTIONS->{subject_line} == 1 ? $subst->{pagedata}->{head}->{topic_name} : read_language()->{EMAIL_NOTIFICATION_STATIC_SUBJECT};
  237.     $p->{subject} = char_convert($p->{subject}, 1, { JSP => 1, convert_html => 2 });
  238.     $p->{subject} = join(" ", read_language()->{EMAIL_TO_QUEUE_SUBJ}, $p->{subject}) if defined $subst->{general}->{is_queued};
  239.     $p->{html} = $subst->{general}->{wants_html};
  240.     return $p;
  241. }
  242.  
  243. ###
  244. ### notify_send_messages
  245. ###
  246. ### Uses mailer.pl and routines defined there to send the e-mail messages
  247. ###
  248.  
  249. sub notify_send_messages {
  250.     my ($messages, $passed) = @_;
  251.     my $par = $passed->{mailcfg};
  252.     dreq("mailer");
  253.     foreach my $msg (@{ $messages }) {
  254.         send_email_message({ to => $msg->{to}, subject => $msg->{subject}, html => $msg->{html} }, $msg->{text}, $par);
  255.     }
  256. }
  257.  
  258. 1;
  259.