===================================================================
RCS file: lib/TWiki/Plugins/VotePlugin/Core.pm,v
retrieving revision 1.1
diff -u -r1.1 lib/TWiki/Plugins/VotePlugin/Core.pm
--- lib/TWiki/Plugins/VotePlugin/Core.pm	2006/12/14 11:15:04	1.1
+++ lib/TWiki/Plugins/VotePlugin/Core.pm	2006/12/14 18:19:32
@@ -31,6 +31,20 @@
 }
 
 ###############################################################################
+# Stole this from TWiki.pm. Should be in Func.pm
+sub isTrue {
+    my( $value, $default ) = @_;
+
+    $default ||= 0;
+
+    return $default unless defined( $value );
+
+    $value =~ s/^\s*(.*?)\s*$/$1/gi;
+    $value =~ s/off//gi;
+    $value =~ s/no//gi;
+    return ( $value ) ? 1 : 0;
+}
+
 sub handleVote {
   my ($web, $topic, $args) = @_;
 
@@ -43,6 +57,8 @@
   my $theColor = &TWiki::Func::extractNameValuePair($args, 'color') || '';
   my $theBgColor = &TWiki::Func::extractNameValuePair($args, 'bgcolor') || '';
   my $theLimit = &TWiki::Func::extractNameValuePair($args, 'limit') || '-1';
+  my $theFreq = &TWiki::Func::extractNameValuePair($args, 'freq') || 'once';
+  my $isAnon = isTrue(&TWiki::Func::extractNameValuePair($args, 'anon') || 'on');
 
   my @theSelects = ();
   my @theOptions = ();
@@ -85,6 +101,8 @@
   $result .= "<form action=\"" . &TWiki::Func::getScriptUrl($web, $topic, 'vote') 
     . "\" method=\"post\">\n";
   $result .= "<input type=\"hidden\" name=\"id\" value=\"$theId\"/>\n";
+  $result .= "<input type=\"hidden\" name=\"anon\" value=\"$isAnon\"/>\n";
+  $result .= "<input type=\"hidden\" name=\"freq\" value=\"$theFreq\"/>\n";
   $result .= "<table class=\"VoteSelect\">\n";
 
   my %selectOptions;
@@ -153,8 +171,17 @@
     close VOTES;
   }
 
+  my $showVoters = ($theStyle =~ /voters/) && (! $isAnon);
+  my $showList   = ($theStyle =~ /list/) && (! $isAnon);
+  my $showBar    = ($theStyle =~ /bar/);
+  my $showPerc   = ($theStyle =~ /perc/);
+  my $showTotal  = ($theStyle =~ /total/);
+  my $showSum    = ($theStyle =~ /sum/);
+
   # collect statistics
   my %keyValueFreq;
+  my %keyValueVoters;
+  my %voterValue;
   my %totalVotes;
   foreach my $voter (keys %votes) {
     foreach my $key (keys %{$votes{$voter}}) {
@@ -164,6 +191,9 @@
       # count frequency of a key
       $keyValueFreq{$key}{$value}++;
 
+      # create voterlist if wanted
+      $keyValueVoters{$key}{$value}.=" $voter" if $showVoters;
+
       # count nr votes for a key
       $totalVotes{$key}++;
     }
@@ -182,7 +212,11 @@
     } else {
       $result .= "|||\n";
     }
-    $result .= "| *$key* || \n";
+    $result .= "| *$key* ||";
+    if ($showVoters) {
+      $result .= " *Who* |";
+    }
+    $result .= "\n";
     $n = $theLimit;
     foreach my $value (sort {$keyValueFreq{$key}{$b} <=> $keyValueFreq{$key}{$a}} keys %{$keyValueFreq{$key}}) {
       last if $n == 0;
@@ -190,7 +224,7 @@
       $result .= "| $value | ";
       my $freq = $keyValueFreq{$key}{$value};
       my $perc = int(1000 * $freq / $totalVotes{$key}) / 10;
-      if ($theStyle =~ /bar/) {
+      if ($showBar) {
 	$result .= '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr>'
 	  . '<td style="white-space:nowrap;border:0;'
 	  . ($theBgColor?'background:'.$theBgColor.'; ':'')
@@ -205,30 +239,50 @@
 	  . ($theBgColor?'background:'.$theBgColor.'; ':'')
 	  . ($theColor?'color:'.$theColor.'; ':'')
 	  . '">';
-	if ($theStyle =~ /perc/) {
+	if ($showPerc) {
 	  $result .= "$perc\%";
 	  if ($theStyle =~ /total/) {
 	    $result .= "&nbsp;($freq)";
 	  }
-	} elsif ($theStyle =~ /total/) {
+	} elsif ($showTotal) {
        	  $result .= "$freq";
 	} else {
 	  $result .= '&nbsp;';
 	}
 	$result .= '</td></tr></table>';
-      } elsif ($theStyle =~ /perc/) {
+      } elsif ($showPerc) {
 	$result .= $perc . '%';
-	if ($theStyle =~ /total/) {
+	if ($showTotal) {
 	  $result .= "&nbsp;($freq)";
 	}
       } else {
 	$result .= $freq;
       }
+      if ($showVoters) {
+        $result .= " |$keyValueVoters{$key}{$value}";
+      }
       $result .= " |\n";
     }
-    if ($theStyle =~ /sum/) {
-      $result .= "|||\n";
-      $result .= "|  $totalVotes{$key} votes ||\n";
+    if ($showSum) {
+      if ($showVoters) {
+        $result .= "||||\n";
+        $result .= "|  $totalVotes{$key} votes |||\n";
+      } else {
+        $result .= "|||\n";
+        $result .= "|  $totalVotes{$key} votes ||\n";
+      }
+    }
+    if ($showList) {
+      $result .= "\n*List of votes*\n| *Who* | *What* |\n";
+      foreach my $voter (keys %votes) {
+        $result .= "| $voter |";
+        foreach my $key (keys %{$votes{$voter}}) {
+          my $value = $votes{$voter}{$key};
+          # SMELL need to encode value in html-safe form
+          $result .= " $value |";
+        }
+        $result .= "\n";
+      }
     }
   }
   $result .= "\n</td></tr></table></div></div>";
@@ -249,7 +303,17 @@
   $formData->{id} = "" if ! $formData->{id};
   $formData->{id} = &securityFilter($formData->{id});
 
+  # SMELL this function should re-parse the topic to see if the poll exists
+  #       and to extract the parameters from there
+  my $theFreq = $formData->{freq};
+  my $isAnon  = ($formData->{anon} != 0);
+
   # create the attachment directory for this topic
+  # SMELL this should be handled by the store subsystem!
+  #       see TWiki:Codev.RecommendedStorageOfPluginData
+  # SMELL this setup means anybody can attach a set of votes, no?
+  # SMELL this setup means that if you don't have a .htaccess file,
+  #       anybody can read the votes file
   my $attachPath = &TWiki::Func::getPubDir() . "/$web/$topic";
   my $votesFile = &getVotesFile($web, $topic, $formData->{id});
   if(-e $attachPath) {
@@ -270,14 +334,27 @@
   if ($debug) {
     $host = int(rand(100)); # for testing
   } else {
-    $host = md5_base64("$ENV{REMOTE_ADDR}$user$date");
+    if ($theFreq eq 'once') {
+      if ($isAnon) {
+        $host = md5_base64("$user");
+      } else {
+        $host = $user;
+      }
+    } else {
+      # REMOTE_ADDR lets user vote once per IP, but it's slightly more anonymous
+      if ($isAnon) {
+        $host = md5_base64("$ENV{REMOTE_ADDR}$user$date");
+      } else {
+        $host = "$user $date";
+      }
+    }
   }
   
   # write the votes
   print VOTES "$date|$host";
   &writeDebug("keys=" . join(",", keys %{$formData}));
   foreach my $key (keys %{$formData}) {
-    next if $key eq "id";
+    next if $key eq "id" or $key eq "anon" or $key eq "freq";
     &writeDebug("$key=$formData->{$key}");
     print VOTES "|$key=$formData->{$key}"
   }
===================================================================
RCS file: data/TWiki/VotePlugin.txt,v
retrieving revision 1.1
diff -u -r1.1 data/TWiki/VotePlugin.txt
--- data/TWiki/VotePlugin.txt	2006/12/14 18:12:02	1.1
+++ data/TWiki/VotePlugin.txt	2006/12/14 18:14:06
@@ -1,4 +1,4 @@
-
+%META:TOPICINFO{author="wmertens" date="1166120046" format="1.1" reprev="1.2" version="1.2"}%
 <!--
 
    PLEASE DO NOT EDIT THIS TOPIC
@@ -13,6 +13,12 @@
 collected in a separate file ... basically inspired by the TWiki:Plugins/PollPlugin.
 
 ---++ Example
+If the plugin is installed, you can see what you get if you put the following in a topic:
+
+<blockquote>
+!%VOTE{id="FavoritMeal" select1="Drink" options1="Beer,Wine,Milk,Water" select2="Food" options2="Steak,Bread,Pasta,Pizza"}%
+</blockquote>
+
 %VOTE{id="FavoritMeal" select1="Drink" options1="Beer,Wine,Milk,Water" select2="Food" options2="Steak,Bread,Pasta,Pizza"}%
 
 <style type="text/css">
@@ -30,9 +36,11 @@
 | *name* | *description* | *example* |
 | id | The identifier of a poll. This must be unique per topic. \
        You can thus have multiple independent votes on the same topic page. | <nop>FaroritMeal |
-| style | Possible values are a combination of =bar=, =perc=, =total=  and =sum= \
+| style | Possible values are a combination of =bar=, =perc=, =total=, =sum=, =voters= and =list= \
      to specify the display style of the poll results \
           (default =bar,perc,total=). | =bar= |
+| freq | How often people can vote. Values: =once=, =daily=. Default =once=. | =daily= |
+| anon | Record votes anonymously. Default =on=. | =off= |
 | select&lt;n&gt; | As you can see in the above example multiple decisions can be made within \
        the same poll. This identifier must be unique within a poll. \
        You can have up to 5 selects per vote (sorry hardcoded;)) | Drinks |
@@ -44,7 +52,11 @@
 in an argument to a TWiki tag.
 
 The %<nop>VOTE{ ... }% will generate the selection box(es) and the poll results.
-The plugin will count only you latest vote. You might only vote once a day.
+The plugin will count only your latest vote.
+
+The =voters= style will show the people who voted for each value, and the =list= style will show a list of votes by users. Since that is pointless for anonymous votes, those styles are disabled if the votes are anonymous.
+
+*Warning*: Anonymous voting just creates an obfuscation of the person who voted. Dedicated people could retrieve the voter list given the list of votes. *Do not use this plugin for important polls*.
 
 ---++ Plugin Installation Instructions
 
@@ -92,3 +104,7 @@
 |  Appraisal: | TWiki:Plugins/%TOPIC%Appraisal |
 
 -- TWiki:Main.MichaelDaum - 31 Aug 2006
+
+%META:FILEATTACHMENT{name="rightbar.gif" attr="" autoattached="1" comment="" date="1157034622" path="rightbar.gif" size="196" user="UnknownUser" version=""}%
+%META:FILEATTACHMENT{name="leftbar.gif" attr="" autoattached="1" comment="" date="1157034622" path="leftbar.gif" size="196" user="UnknownUser" version=""}%
+%META:FILEATTACHMENT{name="mainbar.gif" attr="" autoattached="1" comment="" date="1157034622" path="mainbar.gif" size="148" user="UnknownUser" version=""}%
