# Copyright (c) 2003 AdCycle.com All rights reserved. # http://www.adcycle.com - download the lastest version of adcycle package AdCookies; use strict; sub new { my $this = shift; my $class = ref($this) || $this; my $self = {}; bless $self, $class; return $self; } sub parse_query{ my($self,$buf,$token)=@_; my $value; my $length=length($buf); my $token_length=length($token); my $idx=index($buf,"$token\="); my $idx2=index($buf,"\&",$idx+1); if($idx2!=-1){ $value=substr($buf,$idx+$token_length+1,$idx2-($idx+$token_length+1)); } if($idx2==-1){ $value=substr($buf,$idx+$token_length+1,$length-($idx+$token_length+1)); } if($idx==-1){ $value=""; } return $value; } sub parse_cookie{ my($self,$buf,$token)=@_; my $value; my $length=length($buf); my $token_length=length($token); my $idx=index($buf,"$token\="); my $idx2=index($buf,"\;",$idx); if($idx2!=-1){ $value=substr($buf,$idx+$token_length+1,$idx2-($idx+$token_length+1)); } if($idx2==-1){ $value=substr($buf,$idx+$token_length+1,$length-($idx+$token_length+1)); } if($idx==-1){ $value=""; } return $value; } sub parse_cookies{ my($self,$master,@cidref)=@_; my $cookie_depth=$master->{COOKIE_DEPTH}; my $gid=$master->{GID}; my $unix_stamp=$master->{UNIX_STAMP}; my $cidtot=@cidref; my %icount; my %ccount; my(@slot)=split(/\|/,$master->{impr_cookie}); # >> multi-layout add-on if($master->{layout} eq "multi"){ $master->{db}->set_lock("cplock$master->{TID}","10"); my $timed=$unix_stamp-15; my(@cacheref)=$master->{db}->select_multi_row_hash("SELECT * FROM adcache WHERE REMOTE='$master->{remote}' AND TID=$master->{TID} AND LOG_TIME > $timed ORDER BY LOG_TIME"); my $cachetot=@cacheref; for(my $j=0;$j<$cachetot;$j++){ my($temp2_cid,$temp2_mid,$temp2_count,$temp2_time,$temp2_id)=split(/\:/,$cacheref[$j]->{SLOT}); my @new_slot; my $replace="yes"; for(my $k=0;$k<$cookie_depth;$k++){ my $seg="out"; my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$slot[$k]); if($temp_cid==$temp2_cid && $temp2_time>=$temp_time){ $seg="in"; } if($temp_cid==$temp2_cid && $temp2_time<$temp_time){ $replace="no"; } if($seg eq "out"){ push(@new_slot,$slot[$k]); } } if($replace eq "yes"){ unshift(@new_slot,$cacheref[$j]->{SLOT}); } @slot=@new_slot; } } # << multi-layout add-on my @new_slot; for(my $k=0;$k<$cookie_depth;$k++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$slot[$k]); my $time_from_last=$unix_stamp-$temp_time; if($temp_cid > 0){ my $include="yes"; for(my $j=0;$j<$cidtot;$j++){ my $seconds_delay=$cidref[$j]->{IMPR_DELAY}*3600; if($temp_cid==$cidref[$j]->{CID} && $time_from_last>=$seconds_delay && $seconds_delay!=0){ $include="no"; } if($temp_cid==$cidref[$j]->{CID}){ $icount{$cidref[$j]->{CID}}=$temp_count; } } if($include eq "yes"){ push(@new_slot,$slot[$k]); } } } @slot=@new_slot; # -- << IMPR end filter out by old time # -- >> CLICK filter out old by time my(@click_slot)=split(/\|/,$master->{click_cookie}); my @new_slot; for(my $k=0;$k<$cookie_depth;$k++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$click_slot[$k]); my $time_from_last=$unix_stamp-$temp_time; if($temp_cid > 0){ my $include="yes"; for(my $j=0;$j<$cidtot;$j++){ my $seconds_delay=$cidref[$j]->{CLICK_DELAY}*3600; if($temp_cid==$cidref[$j]->{CID} && $time_from_last>=$seconds_delay && $seconds_delay!=0){ $include="no"; } if($temp_cid==$cidref[$j]->{CID}){ $ccount{$cidref[$j]->{CID}}=$temp_count; } } if($include eq "yes"){ push(@new_slot,$click_slot[$k]); } } } @click_slot=@new_slot; # -- << CLICK end filter out by old time $master->{ICOUNT}=\%icount; $master->{CCOUNT}=\%ccount; $master->{SLOT}=\@slot; $master->{CLICK_SLOT}=\@click_slot; return $master; } sub count_screen{ my($self,$master,@cidref)=@_; my $cookie_depth=$master->{COOKIE_DEPTH}; my $cidtot=@cidref; my @slot=@{$master->{SLOT}}; my @click_slot=@{$master->{CLICK_SLOT}}; my @new_cidref; for(my $j=0;$j<$cidtot;$j++){ my $good_campaign="yes"; # -- >> IMPR filter out old by time for(my $k=0;$k<$cookie_depth;$k++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$slot[$k]); my $count=$cidref[$j]->{IMPR_LIMIT}; if($temp_cid==$cidref[$j]->{CID} && $temp_count>=$count && $count!=0){ $good_campaign="no"; } } # -- << IMPR end filter out by old time # -- >> CLICK filter out old by time if($good_campaign eq "yes"){ for(my $k=0;$k<$cookie_depth;$k++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$click_slot[$k]); my $count=$cidref[$j]->{CLICK_LIMIT}; if($temp_cid==$cidref[$j]->{CID} && $temp_count>=$count && $count!=0){ $good_campaign="no"; } } } # -- << CLICK end filter out by old time if($good_campaign eq "yes"){ push(@new_cidref,$cidref[$j]); } } @cidref=@new_cidref; return @cidref; } # >> COOKIE RANDOM WEIGHTED sub cookie_random_weighted{ my($self,$master,@cidref)=@_; my $cidtot=@cidref; my $cookie_depth=$master->{COOKIE_DEPTH}; my @slot=@{$master->{SLOT}}; my %icount=%{$master->{ICOUNT}}; my %grid=%{$master->{GRID}}; my $cidref; # find min val my $min_count=1000000; for(my $k=0;$k<$cidtot;$k++){ if($icount{$cidref[$k]->{CID}}<$min_count){ $min_count=$icount{$cidref[$k]->{CID}}+0; } } # build array my @new_cidref; if($min_count==0){ for(my $k=0;$k<$cidtot;$k++){ if($icount{$cidref[$k]->{CID}}==$min_count){ push(@new_cidref,$cidref[$k]); } } @cidref=@new_cidref; $cidtot=@cidref; # >> select the campaign to display srand(); my $BNRAND=int(rand(1000)); my $TOTAL; my $mediaref; for(my $k=0;$k<$cidtot;$k++){ $TOTAL=$TOTAL+$grid{$cidref[$k]->{CID}}; } if($TOTAL==0){$TOTAL=$TOTAL+1;} my $MULT=1000/$TOTAL; my @rank=0; my $run=0; my $FOUND_cp=0; my $old_value=0; my $done; for(my $k=0;$k<$cidtot;$k++){ $rank[$k]=$run+($grid{$cidref[$k]->{CID}}*$MULT); $run=$rank[$k]; if($rank[$k]>=$BNRAND && $rank[$k]>=$old_value && $FOUND_cp!=10){ $FOUND_cp=10; $cidref=$cidref[$k]; $done="YES"; } $old_value=$rank[$k]; } # << end select campaign to display }else{ my @new_cidref; for(my $k=0;$k<$cookie_depth;$k++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$slot[$k]); for(my $j=0;$j<$cidtot;$j++){ if($temp_cid == $cidref[$j]->{CID}){ $cidref=$cidref[$j]; } } } } return $cidref; } # << COOKIE RANDOM WEIGHTED # >> COOKIE ORDERED WEIGHTED sub cookie_ordered_weighted{ my($self,$master,@cidref)=@_; my $cidtot=@cidref; my %icount=%{$master->{ICOUNT}}; my $cookie_depth=$master->{COOKIE_DEPTH}; my @slot=@{$master->{SLOT}}; my $cidref; my $max_count=100000; my $target_cid=0; # find min val my $min_count=1000000; for(my $k=0;$k<$cidtot;$k++){ if($icount{$cidref[$k]->{CID}}<$min_count){ $min_count=$icount{$cidref[$k]->{CID}}+0; } } if($min_count==0){ for(my $k=0;$k<$cidtot;$k++){ if($icount{$cidref[$k]->{CID}}<$max_count){ $target_cid=$cidref[$k]->{CID}; $max_count=$icount{$cidref[$k]->{CID}}; } } for(my $k=0;$k<$cidtot;$k++){ if($cidref[$k]->{CID}==$target_cid){ $cidref=$cidref[$k]; } } }else{ my @new_cidref; for(my $k=0;$k<$cookie_depth;$k++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$slot[$k]); for(my $j=0;$j<$cidtot;$j++){ if($temp_cid == $cidref[$j]->{CID}){ $cidref=$cidref[$j]; } } } } return $cidref; } # << COOKIE ORDERED WEIGHTED # >> RANDOM WEIGHTED sub random_weighted{ my($self,$master,@cidref)=@_; my $cidtot=@cidref; my %grid=%{$master->{GRID}}; my $cidref; # >> select the campaign to display srand(); my $BNRAND=int(rand(1000)); my $TOTAL; my $mediaref; for(my $k=0;$k<$cidtot;$k++){ $TOTAL=$TOTAL+$grid{$cidref[$k]->{CID}}; } if($TOTAL==0){$TOTAL=$TOTAL+1;} my $MULT=1000/$TOTAL; my @rank=0; my $run=0; my $FOUND_cp=0; my $old_value=0; my $done; for(my $k=0;$k<$cidtot;$k++){ $rank[$k]=$run+($grid{$cidref[$k]->{CID}}*$MULT); $run=$rank[$k]; if($rank[$k]>=$BNRAND && $rank[$k]>=$old_value && $FOUND_cp!=10){ $FOUND_cp=10; $cidref=$cidref[$k]; $done="YES"; } $old_value=$rank[$k]; } # << end select campaign to display return $cidref; } # << RANDOM WEIGHTED # >> RANDOM SELECT sub random_select{ my($self,$master,@cidref)=@_; my $cidtot=@cidref; my %grid=%{$master->{GRID}}; my $cidref; # >> select the campaign to display srand(); my $BNRAND=int(rand(1000)); my $TOTAL; my $mediaref; for(my $k=0;$k<$cidtot;$k++){ $TOTAL=$TOTAL+100; } if($TOTAL==0){$TOTAL=$TOTAL+1;} my $MULT=1000/$TOTAL; my @rank=0; my $run=0; my $FOUND_cp=0; my $old_value=0; my $done; for(my $k=0;$k<$cidtot;$k++){ $rank[$k]=$run+(100*$MULT); $run=$rank[$k]; if($rank[$k]>=$BNRAND && $rank[$k]>=$old_value && $FOUND_cp!=10){ $FOUND_cp=10; $cidref=$cidref[$k]; $done="YES"; } $old_value=$rank[$k]; } # << end select campaign to display return $cidref; } # << RANDOM SELECT # >> TARGET sub target{ my($self,$master,$cidref)=@_; my $cid=$cidref->{CID}; my $keywords=$master->{keywords}; $keywords=~ tr/A-Z/a-z/; my $remote=$master->{remote}; my $page_url=$master->{page_url}; my $hostname=$master->{hostname}; #get the values my(@targetref)=$master->{db}->select_multi_row_hash("SELECT TARGET_ID,VALUE FROM target WHERE CID='$cid' AND STATUS=1"); my $targettot=@targetref; my $key_match="no"; my $ip_match="no"; my @target; my @match; $match[1]="no"; $target[1]="no"; $match[2]="no"; $target[2]="no"; $match[3]="yes"; $target[3]="no"; $match[4]="no"; $target[4]="no"; $match[5]="yes"; $target[5]="no"; $match[6]="no"; $target[6]="no"; $match[7]="no"; $target[7]="no"; $match[8]="yes"; $target[8]="no"; for(my $k=0;$k<$targettot;$k++){ my $id=$targetref[$k]->{TARGET_ID}; my $value=$targetref[$k]->{VALUE}; # >> 1- keyword targeting if($id==1){ $value=~tr/A-Z/a-z/; $keywords=~tr/A-Z/a-z/; $keywords=~s/\++/ /g; $target[1]="yes"; if(index($keywords,$value)!=-1){ $match[1]="yes"; } } # << 1- keyword targeting # >> 2- ip target if($id==2){ $target[2]="yes"; my $len=length($value); my $sub=substr($remote,0,$len); if($value eq $sub){ $match[2]="yes"; } } # << 2- ip target # >> 3- ip block if($id==3){ $target[3]="yes"; my $len=length($value); my $sub=substr($remote,0,$len); if($value eq $sub){ $match[3]="no"; } } # << 3- ip block # >> 4- page_url target if($id==4){ $value=~tr/A-Z/a-z/; $page_url=~tr/A-Z/a-z/; $page_url=~s/\++/ /g; $target[4]="yes"; if(index($page_url,$value)!=-1){ $match[4]="yes"; } } # << 4- page_url target # >> 5- page_url block if($id==5){ $value=~tr/A-Z/a-z/; $page_url=~tr/A-Z/a-z/; $page_url=~s/\++/ /g; $target[5]="yes"; if(index($page_url,$value)!=-1){ $match[5]="no"; } } # << 5- page_url block # >> 6- exact keyword targeting if($id==6){ $value=~tr/A-Z/a-z/; $keywords=~tr/A-Z/a-z/; $keywords=~s/\++/ /g; $target[6]="yes"; if($keywords eq $value){ $match[6]="yes"; } } # << 6- exact keyword targeting # >> 7- hostname target if($id==7){ $target[7]="yes"; $value=~tr/A-Z/a-z/; $hostname=~tr/A-Z/a-z/; if(index($hostname,$value)!=-1){ $match[7]="yes"; } } # << 7- hostname target # >> 8- hostname block if($id==8){ $target[8]="yes"; $value=~tr/A-Z/a-z/; $hostname=~tr/A-Z/a-z/; if(index($hostname,$value)!=-1){ $match[8]="no"; } } # << 8- hostname block } my $status="good"; for(my $k=1;$k<10;$k++){ if($target[$k] eq "yes" && $match[$k] eq "no"){ $status="bad"; } } return $status; } # << TARGET sub output_cookie{ my($self,$master)=@_; # get the config and env vars my $remote=$master->{remote}; my $timestamp=$master->{timestamp}; my $type=$master->{type}; # get the arrays from the master source my @slot=@{$master->{SLOT}}; my $cid=$master->{CID}; my $mid=$master->{MID}; my $gid=$master->{GID}; my $id=$master->{ID}; my $cookie_depth=$master->{COOKIE_DEPTH}; if($cid>0){ # >> build the cookie my $match_found="no"; my $match_location=0; my $time_match=0; my $count_match=0; for(my $j=0;$j<$cookie_depth;$j++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$slot[$j]); if($cid==$temp_cid){ $match_location=$j; $time_match=$temp_time; $count_match=$temp_count; $match_found="yes"; } } my $cookie_out; if($match_found eq "yes"){ my $new_count=$count_match+1; $cookie_out=qq~$cid:$mid:$new_count:$time_match:$id~; unshift(@slot,"$cookie_out"); splice(@slot,$match_location+1,1); }else{ $cookie_out=qq~$cid:$mid:1:$master->{UNIX_STAMP}:$id~; unshift(@slot,"$cookie_out"); } # >> multi-layout add-on if($master->{layout} eq "multi"){ my $insert_list=[["REMOTE",$remote],["TID",$master->{TID}],["SLOT","$cookie_out"],["LOG_TIME",$master->{UNIX_STAMP}]]; $master->{db}->insert_row("adcache",$insert_list,""); $master->{db}->release_lock("cplock$master->{TID}"); my $dta=$master->{UNIX_STAMP}-15; my $part=substr($master->{UNIX_STAMP},7,2); if($part==77){ $master->{db}->{adcycle}->do("DELETE FROM adcache WHERE LOG_TIME<$dta"); } } # << multi-layout add-on my $impression_cookie; my $value; for(my $k=0;$k<$cookie_depth;$k++){ $value.=$slot[$k]."|"; } $impression_cookie = $master->{query}->cookie(-name=>"i$master->{TID}", #impression list -value=>"$value", -expires=>'+30d', -path=>'/', ); $impression_cookie = $master->{query}->unescape("$impression_cookie"); # << build the cookie # >> deliver the cookie if($type eq "ssi"){ $master->{impr_cookie}=qq~ ~; }else{ $master->{impr_cookie}=qq~Set-Cookie: $impression_cookie\n~; } # << deliver the cookie } return $master; } sub find_cookie_match{ my($self,$master)=@_; my $cookie_depth=$master->{COOKIE_DEPTH}; my(@slot)=split(/\|/,$master->{impr_cookie}); my $click_match="no"; my $mid=0; my $cid=0; for(my $k=0;$k<$cookie_depth;$k++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$slot[$k]); if($temp_id==$master->{ID} && $click_match eq "no"){ $cid=$temp_cid; $mid=$temp_mid; $click_match="yes"; } } return $cid,$mid; } sub click_check{ my($self,$master,$cidref)=@_; my $cookie_depth=$master->{COOKIE_DEPTH}; my $gid=$master->{GID}; my $unix_stamp=$master->{UNIX_STAMP}; my %ccount; # -- >> CLICK filter out old by time my(@click_slot)=split(/\|/,$master->{click_cookie}); my @new_slot; $master->{GOOD_CLICK}="yes"; for(my $k=0;$k<$cookie_depth;$k++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$click_slot[$k]); my $time_from_last=$unix_stamp-$temp_time; if($temp_cid > 0){ my $include="yes"; my $seconds_delay=$cidref->{CLICK_DELAY}*3600; if($temp_cid==$cidref->{CID} && $time_from_last>=$seconds_delay && $seconds_delay!=0){ $include="no"; } if($temp_cid==$cidref->{CID} && $temp_count>=$cidref->{CLICK_LIMIT} && $include eq "yes" && $cidref->{CLICK_LIMIT}!=0){ $master->{GOOD_CLICK}="no"; } if($temp_cid==$cidref->{CID} && $include eq "yes" && $cidref->{CLICK_LIMIT}==0 && $master->{ID}==$temp_id && $time_from_last<15){ $master->{GOOD_CLICK}="no"; } if($temp_cid==$cidref->{CID}){ $ccount{$cidref->{CID}}=$temp_count; } if($include eq "yes"){ push(@new_slot,$click_slot[$k]); } } } @click_slot=@new_slot; # -- << CLICK end filter out by old time $master->{CCOUNT}=\%ccount; $master->{CLICK_SLOT}=\@click_slot; return $master; } sub output_click_cookie{ my($self,$master,$cidref)=@_; # get the arrays from the master source my @slot=@{$master->{CLICK_SLOT}}; my $cid=$master->{CID}; my $mid=$master->{MID}; my $gid=$master->{GID}; my $id=$master->{ID}; my $cookie_depth=$master->{COOKIE_DEPTH}; # >> build the cookie my $match_found="no"; my $match_location=0; my $time_match=0; my $count_match=0; for(my $j=0;$j<$cookie_depth;$j++){ my($temp_cid,$temp_mid,$temp_count,$temp_time,$temp_id)=split(/\:/,$slot[$j]); if($cid==$temp_cid){ $match_location=$j; $time_match=$temp_time; $count_match=$temp_count; $match_found="yes"; } } if($match_found eq "yes"){ my $new_count=$count_match+1; if($cidref->{CLICK_LIMIT}==0){ $time_match=$master->{UNIX_STAMP}; # for double click check } unshift(@slot,"$cid:$mid:$new_count:$time_match:$id"); splice(@slot,$match_location+1,1); }else{ unshift(@slot,"$cid:$mid:1:$master->{UNIX_STAMP}:$id"); } my $click_cookie; my $value; for(my $k=0;$k<$cookie_depth;$k++){ $value.=$slot[$k]."|"; } $click_cookie = $master->{query}->cookie(-name=>"c$master->{TID}", #impression list -value=>"$value", -expires=>'+30d', -path=>'/', ); $click_cookie = $master->{query}->unescape("$click_cookie"); # << build the cookie $master->{click_cookie}=qq~Set-Cookie: $click_cookie\n~; return $master; } # Copyright (c) 2003 AdCycle.com All rights reserved. # http://www.adcycle.com - download the lastest version of adcycle 1;