# Blosxom 'Like' plugin
# Mike Downey
# v0.2
# 08 Oct 2014
# Changes:
# 0.1: original version
# 0.2: Uses JQuery to post the click data and respond to the clicks.
package like;
use CGI;
use Fcntl ':flock';
use File::Path qw/mkpath/;
my $ip = $ENV{'REMOTE_ADDR'} || "null";
my $savedir = $blosxom::plugin_state_dir."/like/";
my %likeList;
my $cacheFile = $savedir."cachefile";
my $truncateLength = 25; # length to truncate story titles
my $numberToDisplay = 10;
my $showCount = 0; # 1 = yes.
$likeform;
$mostliked="";
$likescript= <<__ENDSCRIPT__
__ENDSCRIPT__
;
sub start{
if(-e $cacheFile){
my $fh;
my $line;
open $fh,$cacheFile or die("Cannot load $cacheFile");
flock $fh,LOCK_SH or die ("Cannot lock $cacheFile");
while($line=<$fh>){
chomp $line;
if($line ne ""){
my ($story,$count,$title) = split("\t",$line);
$likeList{$story}="$count\t$title";
}
}
my $i=0;
foreach $item (sort {$likeList{$b} <=> $likeList{$a}} keys %likeList){
#foreach $item (keys %likeList){
my ($count,$title) = split("\t",$likeList{$item});
if($count>0){
last if($i++>$numberToDisplay);
if(length($title)>$truncateLength){
$title = substr($title,0,$truncateLength)."...";
}
$mostliked = $mostliked."$title";
if($showCount){
$mostliked = $mostliked."($count)";
}
$mostliked = $mostliked."
";
}
}
}
1;
}
sub saveCacheFile(){
mkpath($savedir);
my $fh;
open $fh,">$cacheFile" or die("Can't save to $cacheFile");
flock $fh,LOCK_EX or die("Cannot lock $cacheFile");
my $key;
foreach $key (keys %likeList){
print $fh $key."\t".$likeList{$key}."\n";
}
close $fh;
}
# Check whether 'like' has been clicked or whether we're doing normal rendering.
sub skip{
my $q = new CGI;
my $name = $q->param('likefile'); return 0 if (not defined $name);
my $storydir = $q->param('likedir'); return 0 if (not defined $storydir);
# Like has been clicked so append to the saved file.
my ($count,$title) = split("\t",$likeList{$storydir.$name});
$count++;
$likeList{$storydir.$name} = "$count\t$title";
saveCacheFile();
mkpath($savedir.$storydir);
my $fh;
my $filename = $savedir.$storydir.$name.".txt";
open $fh,"+>>$filename" or die("Cannot open $filename");
flock $fh,LOCK_EX or die ("Cannot lock $filename");
# Read in the file and see whether we've seen this IP address before.
seek($fh,0,0);
my $line;
my $found = 0;
while($line = <$fh>){
my ($oldip,$date) = split("\t",$line);
if($ip eq $oldip){
$found=1;
last;
}
}
if(!$found){
seek($fh,0,2); # make sure we're at the end of the file
my ($Sec, $Min, $Hour, $Day, $Month, $Year)=gmtime;
$Year += 1900; $Month += 1;
my $output = "$ip\t$Day/$Month/$Year $Hour:$Min:$Sec\n";
print $fh $output;
}
close $fh;
return 1;
}
sub story{
my($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
my $lf = "${savedir}${path}/${filename}.txt";
my $likeCount=0;
my $line;
my $inputbutton = "";
if(-e $lf){
open $FH,$lf;
flock $FH,LOCK_SH or die ("Cannot lock $lf");
while($line=<$FH>){
$likeCount++;
my ($oldip,$date) = split("\t",$line);
if($ip eq $oldip){
$inputbutton = "";
}
}
close $FH;
}
my $hashkey = "$path/$filename";
my $hashval = "0\t".$$title_ref;
if(not defined $likeList{$hashkey}){
$likeList{$hashkey} = $hashval;
saveCacheFile();
}
else{
$hashval = $likeCount."\t".$$title_ref
}
$likeform="
$inputbutton |