]> git.p6c8.net - selfforum.git/blobdiff - selfforum-cgi/shared/Posting/_lib.pm
Lock.pm: several style changes, comments added and fixed a small bug
[selfforum.git] / selfforum-cgi / shared / Posting / _lib.pm
index 7143f6e36b78569c02c50bcd861bf578f0bbf879..0f3f015d1050431e3f0fdead3b69242331aef502 100644 (file)
@@ -4,8 +4,8 @@ package Posting::_lib;
 #                                                                              #
 # File:        shared/Posting/_lib.pm                                          #
 #                                                                              #
 #                                                                              #
 # File:        shared/Posting/_lib.pm                                          #
 #                                                                              #
-# Authors:     AndrĂ© Malo <nd@o3media.de>, 2001-02-25                          #
-#              Frank Schoenmann <fs@tower.de>, 2001-03-02                      #
+# Authors:     AndrĂ© Malo <nd@o3media.de>, 2001-03-03                          #
+#              Frank Schoenmann <fs@tower.de>, 2001-03-13                      #
 #                                                                              #
 # Description: Message access interface, time format routines                  #
 #                                                                              #
 #                                                                              #
 # Description: Message access interface, time format routines                  #
 #                                                                              #
@@ -13,24 +13,30 @@ package Posting::_lib;
 
 use strict;
 
 
 use strict;
 
-use vars qw(@EXPORT_OK);
-use base qw(Exporter);
-
 use Encode::Plain; $Encode::Plain::utf8 = 1;
 
 use XML::DOM;
 
 # ====================================================
 use Encode::Plain; $Encode::Plain::utf8 = 1;
 
 use XML::DOM;
 
 # ====================================================
-# Funktionsexport
+# Export
 # ====================================================
 
 # ====================================================
 
-@EXPORT_OK = qw(get_message_header get_message_body get_message_node parse_single_thread
-                hr_time short_hr_time long_hr_time
-                get_all_threads create_forum_xml_string
-                save_file);
+use constant SORT_ASCENT  => 0; # (young postings first)
+use constant SORT_DESCENT => 1;
+use constant KEEP_DELETED => 1;
+use constant KILL_DELETED => 0;
+
+use base qw(Exporter);
+@Posting::_lib::EXPORT_OK = qw(
+  get_message_header get_message_body get_message_node get_body_node parse_single_thread parse_xml_file
+  hr_time short_hr_time long_hr_time
+  get_all_threads create_forum_xml_string
+  save_file
+  SORT_ASCENT   SORT_DESCENT   KEEP_DELETED   KILL_DELETED
+);
 
 # ====================================================
 
 # ====================================================
-# Zugriff uebers DOM
+# Access via XML::DOM
 # ====================================================
 
 ### get_message_header () ######################################################
 # ====================================================
 
 ### get_message_header () ######################################################
@@ -61,34 +67,47 @@ sub get_message_header ($)
     subject  => ($subject -> hasChildNodes)?$subject -> getFirstChild -> getData:undef,
     email    => (defined ($email) and $email -> hasChildNodes)?$email -> getFirstChild -> getData:undef,
     home     => (defined ($home)  and $home  -> hasChildNodes)?$home  -> getFirstChild -> getData:undef,
     subject  => ($subject -> hasChildNodes)?$subject -> getFirstChild -> getData:undef,
     email    => (defined ($email) and $email -> hasChildNodes)?$email -> getFirstChild -> getData:undef,
     home     => (defined ($home)  and $home  -> hasChildNodes)?$home  -> getFirstChild -> getData:undef,
-    image    => (defined ($image) and $image -> hasChildNodes)?$image -> getFirstChild - >getData:undef,
+    image    => (defined ($image) and $image -> hasChildNodes)?$image -> getFirstChild -getData:undef,
     time     => $date -> getAttribute ('longSec')
   );
 
   \%conf;
 }
 
     time     => $date -> getAttribute ('longSec')
   );
 
   \%conf;
 }
 
+### get_body_node () ########################################################
+#
+# Search a specific message body in a XML tree
+#
+# Params: $xml  XML::DOM::Document Object (Document Node)
+#         $mid  Message ID
+# Return: MessageContent XML node (or -none-)
+#
+sub get_body_node ($$)
+{
+  my ($xml, $mid) = @_;
+
+  for ($xml->getElementsByTagName ('ContentList', 1)->item (0)->getElementsByTagName ('MessageContent', 0))
+  {
+    return $_ if ($_ -> getAttribute ('mid') eq $mid);
+  }
+
+  return;
+}
+
 ### get_message_body () ########################################################
 #
 # Read message body
 #
 ### get_message_body () ########################################################
 #
 # Read message body
 #
-# Params: $xml  XML tree
+# Params: $xml  XML::DOM::Document Object (Document Node)
 #         $mid  Message ID
 # Return: Scalar reference
 #
 sub get_message_body ($$)
 {
 #         $mid  Message ID
 # Return: Scalar reference
 #
 sub get_message_body ($$)
 {
-  my ($xml, $mid) = @_;
+  my $cnode = get_body_node ($_[0], $_[1]);
   my $body;
 
   my $body;
 
-  foreach ($xml->getElementsByTagName ('ContentList', 1)->item (0)->getElementsByTagName ('MessageContent', 0))
-  {
-    if ($_ -> getAttribute ('mid') eq $mid)
-    {
-      $body = ($_ -> hasChildNodes)?$_ -> getFirstChild -> getData:'';
-      last;
-    }
-  }
+  $body = ($cnode -> hasChildNodes)?$cnode -> getFirstChild -> getData:'' if $cnode;
 
   \$body;
 }
 
   \$body;
 }
@@ -97,10 +116,10 @@ sub get_message_body ($$)
 #
 # Search a specific message in a XML tree
 #
 #
 # Search a specific message in a XML tree
 #
-# Params: $xml  XML tree
+# Params: $xml  XML::DOM::Document Object (Document Node)
 #         $tid  Thread ID
 #         $mid  Message ID
 #         $tid  Thread ID
 #         $mid  Message ID
-# Return: Message XML node, Thread XML node
+# Return: Message XML node, Thread XML node (or -none-)
 #
 sub get_message_node ($$$)
 {
 #
 sub get_message_node ($$$)
 {
@@ -127,6 +146,26 @@ sub get_message_node ($$$)
   wantarray ? ($mnode, $tnode) : $mnode;
 }
 
   wantarray ? ($mnode, $tnode) : $mnode;
 }
 
+### sub parse_xml_file ($) #####################################################
+#
+# load the specified XML-File and create the DOM tree
+# this sub is only to avoid errors and to centralize the parse process
+#
+# Params: $file filename
+# Return: XML::DOM::Document Object (Document Node) or false
+#
+sub parse_xml_file ($) {
+  my $file = shift;
+  my $xml = eval {
+              local $SIG{__DIE__};
+              new XML::DOM::Parser (KeepCDATA => 1) -> parsefile ($file);
+            };
+
+  return if ($@);
+
+  $xml;
+}
+
 ###########################
 # sub parse_single_thread
 #
 ###########################
 # sub parse_single_thread
 #
@@ -260,7 +299,7 @@ sub sort_thread ($$) {
   \@smsg;
 }
 
   \@smsg;
 }
 
-### delete_message () ##########################################################
+### delete_messages () #########################################################
 #
 # Filter out deleted messages
 #
 #
 # Filter out deleted messages
 #
@@ -278,10 +317,7 @@ sub delete_messages ($)
     if ($_ -> {'deleted'})
     {
       my $n = $_ -> {'answers'} + 1;
     if ($_ -> {'deleted'})
     {
       my $n = $_ -> {'answers'} + 1;
-      for (@path)
-      {
-        $smsg -> [$_] -> {'answers'} -= $n;
-      }
+      $smsg -> [$_] -> {'answers'} -= $n for (@path);
       splice @$smsg,$z,$n;
     }
     else
       splice @$smsg,$z,$n;
     }
     else
@@ -308,26 +344,32 @@ sub delete_messages ($)
   return;
 }
 
   return;
 }
 
-###########################
-# sub get_all_threads
+### get_all_threads () #########################################################
+#
+# Read and Parse the main file (without any XML-module, they are too slow)
+#
+# Params: $file     /path/to/filename of the main file
+#         $deleted  hold deleted (invisible) messages in result (1) oder not (0)
+#         $sorted   direction of message sort: descending (0) (default) or ascending (1)
+# Return: scalar context: hash reference
+#           list context: list (\%threads, $last_thread, $last_message, $dtd, \@unids)
 #
 #
-# Hauptdatei laden und
-# parsen
-###########################
-
 sub get_all_threads ($$;$)
 {
   my ($file, $deleted, $sorted) = @_;
 sub get_all_threads ($$;$)
 {
   my ($file, $deleted, $sorted) = @_;
-  my ($last_thread, $last_message, @unids, %threads);
-  local *FILE;
+  my ($last_thread, $last_message, $dtd, @unids, %threads);
+  local (*FILE, $/);
 
   open FILE, $file or return undef;
   my $xml = join '', <FILE>;
   close(FILE) or return undef;
 
 
   open FILE, $file or return undef;
   my $xml = join '', <FILE>;
   close(FILE) or return undef;
 
-  if (wantarray) {
+  if (wantarray)
+  {
+    ($dtd)          = $xml =~ /<!DOCTYPE\s+\S+\s+SYSTEM\s+"([^"]+)">/;
     ($last_thread)  = map {/(\d+)/} $xml =~ /<Forum.+?lastThread="([^"]+)"[^>]*>/;
     ($last_thread)  = map {/(\d+)/} $xml =~ /<Forum.+?lastThread="([^"]+)"[^>]*>/;
-    ($last_message) = map {/(\d+)/} $xml =~ /<Forum.+?lastMessage="([^"]+)"[^>]*>/;}
+    ($last_message) = map {/(\d+)/} $xml =~ /<Forum.+?lastMessage="([^"]+)"[^>]*>/;
+  }
 
   my $reg_msg = qr~(?:</Message>
                      |<Message\s+id="m(\d+)"\s+unid="([^"]*)"(?:\s+invisible="([^"]*)")?(?:\s+archive="([^"]*)")?[^>]*>\s*
 
   my $reg_msg = qr~(?:</Message>
                      |<Message\s+id="m(\d+)"\s+unid="([^"]*)"(?:\s+invisible="([^"]*)")?(?:\s+archive="([^"]*)")?[^>]*>\s*
@@ -338,91 +380,95 @@ sub get_all_threads ($$;$)
                         <Date\s+longSec="(\d+)"[^>]*>\s*
                       </Header>\s*(?:(<)/Message>|(?=(<)Message\s*)))~sx;
 
                         <Date\s+longSec="(\d+)"[^>]*>\s*
                       </Header>\s*(?:(<)/Message>|(?=(<)Message\s*)))~sx;
 
-  while ($xml =~ /<Thread id="t(\d+)">([^<]*(?:<(?!\/Thread>)[^<]*)*)<\/Thread>/g) {
-
+  while ($xml =~ /<Thread id="t(\d+)">([^<]*(?:<(?!\/Thread>)[^<]*)*)<\/Thread>/g)
+  {
     my ($tid, $thread) = ($1, $2);
     my ($level, $cmno, @msg, @stack) = (0);
 
     my ($tid, $thread) = ($1, $2);
     my ($level, $cmno, @msg, @stack) = (0);
 
-    while ($thread =~ m;$reg_msg;g) {
-
-      if (defined($10)) {
+    while ($thread =~ m;$reg_msg;g)
+    {
+      if (defined($10))
+      {
         push @stack,$cmno if (defined $cmno);
         push @stack,$cmno if (defined $cmno);
-        push @msg, {};
-
-        if (defined $cmno) {
+        push @msg, {mid     => $1,
+                    unid    => $2,
+                    deleted => $3,
+                    archive => $4,
+                    name    => $5,
+                    cat     => $6,
+                    subject => $7,
+                    time    => $8,
+                    level   => $level++,
+                    unids   => [],
+                    kids    => [],
+                    answers => 0};
+
+        if (defined $cmno)
+        {
           push @{$msg[$cmno] -> {kids}}  => $#msg;
           push @{$msg[$cmno] -> {kids}}  => $#msg;
-          push @{$msg[$cmno] -> {unids}} => $2;}
-        else {
-          push @unids => $2;}
+          push @{$msg[$cmno] -> {unids}} => $2;
+        }
+        else
+        {
+          push @unids => $2;
+        }
 
 
-        for (@stack) {$msg[$_] -> {answers}++}
+        $msg[$_] -> {answers}++ for (@stack);
 
         $cmno=$#msg;
 
 
         $cmno=$#msg;
 
-       ($msg[-1] -> {mid},
-        $msg[-1] -> {unid},
-        $msg[-1] -> {name},
-        $msg[-1] -> {cat},
-        $msg[-1] -> {subject},
-        $msg[-1] -> {time})     = ($1, $2, $5, $6, $7, $8);
-
-        $msg[-1] -> {deleted} = $3;
-        $msg[-1] -> {archive} = $4;
-
-        $msg[-1] -> {name} =~ s/&amp;/&/g;
-        $msg[-1] -> {cat} =~ s/&amp;/&/g;
+        $msg[-1] -> {name}    =~ s/&amp;/&/g;
+        $msg[-1] -> {cat}     =~ s/&amp;/&/g;
         $msg[-1] -> {subject} =~ s/&amp;/&/g;
 
         $msg[-1] -> {subject} =~ s/&amp;/&/g;
 
-        $msg[-1] -> {unids} = [];
-        $msg[-1] -> {kids} = [];
-        $msg[-1] -> {answers} = 0;
-        $msg[-1] -> {level} = $level++;}
-
-      elsif (defined ($9)) {
-        push @msg, {};
-
-        if (defined $cmno) {
+      }
+      elsif (defined ($9))
+      {
+        push @msg, {mid     => $1,
+                    unid    => $2,
+                    deleted => $3,
+                    archive => $4,
+                    name    => $5,
+                    cat     => $6,
+                    subject => $7,
+                    time    => $8,
+                    level   => $level,
+                    unids   => [],
+                    kids    => [],
+                    answers => 0};
+
+        if (defined $cmno)
+        {
           push @{$msg[$cmno] -> {kids}}  => $#msg;
           push @{$msg[$cmno] -> {unids}} => $2;
           push @{$msg[$cmno] -> {kids}}  => $#msg;
           push @{$msg[$cmno] -> {unids}} => $2;
-          $msg[$cmno] -> {answers}++;}
-        else {
-          push @unids => $2;}
-
-        for (@stack) {$msg[$_] -> {answers}++}
-
-       ($msg[-1] -> {mid},
-        $msg[-1] -> {unid},
-        $msg[-1] -> {name},
-        $msg[-1] -> {cat},
-        $msg[-1] -> {subject},
-        $msg[-1] -> {time})     = ($1, $2, $5, $6, $7, $8);
+          $msg[$cmno] -> {answers}++;
+        }
+        else
+        {
+          push @unids => $2;
+        }
 
 
-        $msg[-1] -> {deleted} = $3;
-        $msg[-1] -> {archive} = $4;
+        $msg[$_] -> {answers}++ for (@stack);
 
 
-        $msg[-1] -> {name} =~ s/&amp;/&/g;
-        $msg[-1] -> {cat} =~ s/&amp;/&/g;
+        $msg[-1] -> {name}    =~ s/&amp;/&/g;
+        $msg[-1] -> {cat}     =~ s/&amp;/&/g;
         $msg[-1] -> {subject} =~ s/&amp;/&/g;
         $msg[-1] -> {subject} =~ s/&amp;/&/g;
+      }
+      else
+      {
+        $cmno = pop @stack; $level--;
+      }
+    }
 
 
-        $msg[-1] -> {level} = $level;
-        $msg[-1] -> {unids} = [];
-        $msg[-1] -> {kids} = [];
-        $msg[-1] -> {answers} = 0;}
-
-      else {
-        $cmno = pop @stack; $level--;}}
-
-  # ============
-  # Sortieren und bei Bedarf
-  # geloeschte Messages entfernen
-
-    my $smsg = sort_thread (\@msg, $sorted);
-    delete_messages ($smsg) unless ($deleted);
+    my $smsg = sort_thread (\@msg, $sorted);    # sort messages
+    delete_messages ($smsg) unless ($deleted);  # remove invisible messages
 
     $threads{$tid} = $smsg if (@$smsg);
   }
 
 
     $threads{$tid} = $smsg if (@$smsg);
   }
 
-  wantarray ? (\%threads, $last_thread, $last_message, \@unids) : \%threads;
+  wantarray
+    ? (\%threads, $last_thread, $last_message, $dtd, \@unids)
+    : \%threads;
 }
 
 ###########################
 }
 
 ###########################
@@ -552,4 +598,4 @@ sub long_hr_time ($) {
 # ====================================================
 
 # making require happy
 # ====================================================
 
 # making require happy
-1;
+1;
\ No newline at end of file

patrick-canterino.de