Merge branch 'thh-bug37' into next
[usenet/newsstats.git] / NewsStats.pm
index a04ac0f..12334cd 100644 (file)
@@ -33,6 +33,7 @@ require Exporter;
   SplitPeriod
   ListMonth
   ListNewsgroups
+  ParseHierarchies
   ReadGroupList
   OutputData
   FormatOutput
@@ -184,7 +185,7 @@ sub ListNewsgroups {
     next if($TLH and !/^$TLH/);
     # don't count invalid newsgroups
     if(%ValidGroups and !defined($ValidGroups{$_})) {
-      &Bleat(1,sprintf("DROPPED: %s",$_));
+      warn (sprintf("DROPPED: %s\n",$_));
       next;
     }
     # add original newsgroup to %Newsgroups
@@ -230,8 +231,9 @@ sub ReadGroupList {
   my %ValidGroups;
   open (my $LIST,"<$Filename") or &Bleat(2,"Cannot read $Filename: $!");
   while (<$LIST>) {
-    s/^(\S+).*$/$1/;
+    s/^\s*(\S+).*$/$1/;
     chomp;
+    next if /^$/;
     $ValidGroups{$_} = '1';
   };
   close $LIST;
@@ -343,13 +345,13 @@ sub SplitPeriod {
 sub ListMonth {
 ################################################################################
 ### return a list of months (YYYY-MM) between start and end month
-### IN : $StartMonth, $EndMonth
-### OUT: @Months: array containing all months from $StartMonth to $EndMonth
-  my ($StartMonth, $EndMonth) = @_;
-  return (undef,undef)
-    if ($StartMonth !~ /^\d{4}-\d{2}$/ or $EndMonth !~ /^\d{4}-\d{2}$/);
-  # return if $StartMonth = $EndMonth
-  return ($StartMonth) if ($StartMonth eq $EndMonth);
+### IN : $MonthExpression ('YYYY-MM' or 'YYYY-MM to YYYY-MM')
+### OUT: @Months: array containing all months from $MonthExpression enumerated
+  my ($MonthExpression )= @_;
+  # return if single month
+  return ($MonthExpression) if ($MonthExpression =~ /^\d{4}-\d{2}$/);
+  # parse $MonthExpression
+  my ($StartMonth, $EndMonth) = split(' to ',$MonthExpression);
   # set $Year, $Month from $StartMonth
   my ($Year, $Month) = split /-/, $StartMonth;
   # define @Months
@@ -572,16 +574,49 @@ sub SQLGroupList {
   my ($Newsgroups) = @_;
   # substitute '*' wildcard with SQL wildcard character '%'
   $Newsgroups =~ s/\*/%/g;
+  return (undef,undef) if !CheckValidNewsgroups($Newsgroups);
   # just one newsgroup?
   return (SQLGroupWildcard($Newsgroups),$Newsgroups) if $Newsgroups !~ /:/;
+  my ($SQL,@WildcardGroups,@NoWildcardGroups);
   # list of newsgroups separated by ':'
-  my $SQL = '(';
   my @GroupList = split /:/, $Newsgroups;
   foreach (@GroupList) {
-     $SQL .= ' OR ' if $SQL gt '(';
-     $SQL .= SQLGroupWildcard($_);
+    if ($_ !~ /%/) {
+      # add to list of newsgroup names WITHOUT wildcard
+      push (@NoWildcardGroups,$_);
+    } else {
+      # add to list of newsgroup names WITH wildcard
+      push (@WildcardGroups,$_);
+      # add wildcard to SQL clause
+      # 'OR' if SQL clause is not empty
+      $SQL .= ' OR ' if $SQL;
+      $SQL .= 'newsgroup LIKE ?'
+    }
   };
-  $SQL .= ')';
+  if (scalar(@NoWildcardGroups)) {
+    # add 'OR' if SQL clause is not empty
+    $SQL .= ' OR ' if $SQL;
+    if (scalar(@NoWildcardGroups) < 2) {
+      # special case: just one newsgroup without wildcard
+      $SQL .= 'newsgroup = ?';
+    } else {
+      # create list of newsgroups to include: 'newsgroup IN (...)'
+      $SQL .= 'newsgroup IN (';
+      my $SQLin;
+      foreach (@NoWildcardGroups) {
+        $SQLin .= ',' if $SQLin;
+        $SQLin .= '?';
+      }
+      # add list to SQL clause
+      $SQL .= $SQLin .= ')';
+    }
+  }
+  # add brackets '()' to SQL clause as needed (more than one wildcard group)
+  if (scalar(@WildcardGroups)) {
+    $SQL = '(' . $SQL .')';
+  }
+  # rebuild @GroupList in (now) correct order
+  @GroupList = (@WildcardGroups,@NoWildcardGroups);
   return ($SQL,@GroupList);
 };
 
@@ -593,7 +628,6 @@ sub SQLGroupWildcard {
 ###                  (group.name or group.name.%)
 ### OUT: SQL code to become part of a 'WHERE' clause
   my ($Newsgroup) = @_;
-  # FIXME: check for validity
   if ($Newsgroup !~ /%/) {
     return 'newsgroup = ?';
   } else {
@@ -696,6 +730,19 @@ sub SQLBuildClause {
   return $SQLClause;
 };
 
+#####--------------------------- Verifications ----------------------------#####
+
+################################################################################
+sub CheckValidNewsgroups {
+################################################################################
+### syntax check of newgroup list
+### IN : $Newsgroups: list of newsgroups (group.one.*:group.two:group.three.*)
+### OUT: boolean
+  my ($Newsgroups) = @_;
+  my $InvalidCharRegExp = ',; ';
+  return ($Newsgroups =~ /[$InvalidCharRegExp]/) ? 0 : 1;
+};
+
 
 #####------------------------------- done ---------------------------------#####
 1;
This page took 0.012516 seconds and 4 git commands to generate.