Ticket #134: contrib syslog - parser.pl

File contrib syslog - parser.pl, 27.1 KB (added by matt, 4 months ago)
Line 
1#!/usr/bin/perl -w
2
3use strict;
4$|=1;
5use Proc::Daemon;
6use Proc::PID::File;
7use Sys::Syslog;
8use DBI;
9use HTTP::Date qw( str2time time2iso );
10use HTML::Entities;
11use Data::Uniqid qw ( luniqid );
12use Date::Manip;
13use Socket;
14use Digest::MD5 qw(md5);
15use Math::Round;
16use JSON::XS;
17use URI::Escape;
18
19use constant TYPE_ACTION_URL   => 1;
20use constant TYPE_OUTLINK  => 2;
21use constant TYPE_DOWNLOAD => 3;
22use constant TYPE_ACTION_NAME => 4;
23use constant TYPE_ECOMMERCE_ITEM_SKU => 5;
24use constant TYPE_ECOMMERCE_ITEM_NAME => 6;
25use constant TYPE_ECOMMERCE_ITEM_CATEGORY => 7;
26
27use constant LENGTH_HEX_ID_STRING => 16;
28use constant LENGTH_BINARY_ID => 8;
29
30# SQL
31my $hostname = '127.0.0.1';
32my $port = '3306';
33my $database = 'pwk';
34my $password = 'pass';
35my $user = 'piwik';
36my $driver = 'mysql';
37
38# Daemonize
39Proc::Daemon::Init();
40
41$SIG{INT} = \&SHUTDOWN;
42$SIG{TERM} = \&SHUTDOWN;
43
44if (Proc::PID::File->running()) {
45        print "Already running\n";
46        exit 0;
47}
48
49my $logfile = "/var/log/piwik_tracker.fifo";
50openlog("parser", "ndelay,pid", "local1");
51
52#SQL Query
53my $action_id = q{
54    SELECT
55        idaction,
56        type,
57        name
58    FROM
59        piwik_log_action
60    WHERE
61        (hash = CRC32(?) AND name = ? AND type = '4' )
62        OR
63        (hash = CRC32(?) AND name = ? AND type = '1')
64};
65
66my $visit = q{
67    SELECT
68        idvisitor,
69        visit_last_action_time,
70        visit_first_action_time,
71        idvisit,
72        visit_exit_idaction_url,
73        visit_exit_idaction_name,
74        visitor_returning,
75        visitor_days_since_first,
76        visitor_days_since_order,
77        referer_name,
78        referer_keyword,
79        referer_type,
80        visitor_count_visits,
81        visit_goal_buyer,
82        custom_var_k1,custom_var_v1,
83        custom_var_k2,custom_var_v2,
84        custom_var_k3,custom_var_v3,
85        custom_var_k4,custom_var_v4,
86        custom_var_k5,custom_var_v5
87    FROM
88        piwik_log_visit
89    WHERE
90        visit_last_action_time >= ?
91        AND
92        idsite = ?
93        AND
94        config_id = ?
95    ORDER BY visit_last_action_time DESC LIMIT 1
96};
97
98my $know_visit = q{
99    UPDATE
100        piwik_log_visit
101    SET
102        visit_total_actions = visit_total_actions + 1,
103        visit_exit_idaction_url = ?,
104        visit_exit_idaction_name = ?,
105        visit_last_action_time = ?,
106        visit_total_time = ?,
107        idvisitor = ?,
108        visit_goal_buyer = ?
109    WHERE
110        idsite = ?
111        AND
112        idvisit = ?
113};
114
115my $link_visit_action = q{
116    INSERT INTO
117        piwik_log_link_visit_action
118    (idvisit, idsite, idvisitor, server_time, idaction_url, idaction_name, idaction_url_ref, idaction_name_ref, time_spent_ref_action)
119    VALUES
120        (?,?,?,?,?,?,?,?,?)
121};
122
123my %CountryList = (
124                'ad' => 'eur',
125                'ae' => 'asi',
126                'af' => 'asi',
127                'ag' => 'amc',
128                'ai' => 'amc',
129                'al' => 'eur',
130                'am' => 'asi',
131                'ao' => 'afr',
132                'aq' => 'ant',
133                'ar' => 'ams',
134                'as' => 'oce',
135                'at' => 'eur',
136                'au' => 'oce',
137                'aw' => 'amc',
138                'ax' => 'eur',
139                'az' => 'asi',
140                'ba' => 'eur',
141                'bb' => 'amc',
142                'bd' => 'asi',
143                'be' => 'eur',
144                'bf' => 'afr',
145                'bg' => 'eur',
146                'bh' => 'asi',
147                'bi' => 'afr',
148                'bj' => 'afr',
149                'bl' => 'amc',
150                'bm' => 'amc',
151                'bn' => 'asi',
152                'bo' => 'ams',
153                'bq' => 'amc',
154                'br' => 'ams',
155                'bs' => 'amc',
156                'bt' => 'asi',
157                'bv' => 'ant',
158                'bw' => 'afr',
159                'by' => 'eur',
160                'bz' => 'amc',
161                'ca' => 'amn',
162                'cc' => 'asi',
163                'cd' => 'afr',
164                'cf' => 'afr',
165                'cg' => 'afr',
166                'ch' => 'eur',
167                'ci' => 'afr',
168                'ck' => 'oce',
169                'cl' => 'ams',
170                'cm' => 'afr',
171                'cn' => 'asi',
172                'co' => 'ams',
173                'cr' => 'amc',
174                'cu' => 'amc',
175                'cv' => 'afr',
176                'cw' => 'amc',
177                'cx' => 'asi',
178                'cy' => 'eur',
179                'cz' => 'eur',
180                'de' => 'eur',
181                'dj' => 'afr',
182                'dk' => 'eur',
183                'dm' => 'amc',
184                'do' => 'amc',
185                'dz' => 'afr',
186                'ec' => 'ams',
187                'ee' => 'eur',
188                'eg' => 'afr',
189                'eh' => 'afr',
190                'er' => 'afr',
191                'es' => 'eur',
192                'et' => 'afr',
193                'fi' => 'eur',
194                'fj' => 'oce',
195                'fk' => 'ams',
196                'fm' => 'oce',
197                'fo' => 'eur',
198                'fr' => 'eur',
199                'ga' => 'afr',
200                'gb' => 'eur',
201                'gd' => 'amc',
202                'ge' => 'asi',
203                'gf' => 'ams',
204                'gg' => 'eur',
205                'gh' => 'afr',
206                'gi' => 'eur',
207                'gl' => 'amn',
208                'gm' => 'afr',
209                'gn' => 'afr',
210                'gp' => 'amc',
211                'gq' => 'afr',
212                'gr' => 'eur',
213                'gs' => 'ant',
214                'gt' => 'amc',
215                'gu' => 'oce',
216                'gw' => 'afr',
217                'gy' => 'ams',
218                'hk' => 'asi',
219                'hm' => 'ant',
220                'hn' => 'amc',
221                'hr' => 'eur',
222                'ht' => 'amc',
223                'hu' => 'eur',
224                'id' => 'asi',
225                'ie' => 'eur',
226                'il' => 'asi',
227                'im' => 'eur',
228                'in' => 'asi',
229                'io' => 'asi',
230                'iq' => 'asi',
231                'ir' => 'asi',
232                'is' => 'eur',
233                'it' => 'eur',
234                'je' => 'eur',
235                'jm' => 'amc',
236                'jo' => 'asi',
237                'jp' => 'asi',
238                'ke' => 'afr',
239                'kg' => 'asi',
240                'kh' => 'asi',
241                'ki' => 'oce',
242                'km' => 'afr',
243                'kn' => 'amc',
244                'kp' => 'asi',
245                'kr' => 'asi',
246                'kw' => 'asi',
247                'ky' => 'amc',
248                'kz' => 'asi',
249                'la' => 'asi',
250                'lb' => 'asi',
251                'lc' => 'amc',
252                'li' => 'eur',
253                'lk' => 'asi',
254                'lr' => 'afr',
255                'ls' => 'afr',
256                'lt' => 'eur',
257                'lu' => 'eur',
258                'lv' => 'eur',
259                'ly' => 'afr',
260                'ma' => 'afr',
261                'mc' => 'eur',
262                'md' => 'eur',
263                'me' => 'eur',
264                'mf' => 'amc',
265                'mg' => 'afr',
266                'mh' => 'oce',
267                'mk' => 'eur',
268                'ml' => 'afr',
269                'mm' => 'asi',
270                'mn' => 'asi',
271                'mo' => 'asi',
272                'mp' => 'oce',
273                'mq' => 'amc',
274                'mr' => 'afr',
275                'ms' => 'amc',
276                'mt' => 'eur',
277                'mu' => 'afr',
278                'mv' => 'asi',
279                'mw' => 'afr',
280                'mx' => 'amn',
281                'my' => 'asi',
282                'mz' => 'afr',
283                'na' => 'afr',
284                'nc' => 'oce',
285                'ne' => 'afr',
286                'nf' => 'oce',
287                'ng' => 'afr',
288                'ni' => 'amc',
289                'nl' => 'eur',
290                'no' => 'eur',
291                'np' => 'asi',
292                'nr' => 'oce',
293                'nu' => 'oce',
294                'nz' => 'oce',
295                'om' => 'asi',
296                'pa' => 'amc',
297                'pe' => 'ams',
298                'pf' => 'oce',
299                'pg' => 'oce',
300                'ph' => 'asi',
301                'pk' => 'asi',
302                'pl' => 'eur',
303                'pm' => 'amn',
304                'pn' => 'oce',
305                'pr' => 'amc',
306                'ps' => 'asi',
307                'pt' => 'eur',
308                'pw' => 'oce',
309                'py' => 'ams',
310                'qa' => 'asi',
311                're' => 'afr',
312                'ro' => 'eur',
313                'rs' => 'eur',
314                'ru' => 'eur',
315                'rw' => 'afr',
316                'sa' => 'asi',
317                'sb' => 'oce',
318                'sc' => 'afr',
319                'sd' => 'afr',
320                'se' => 'eur',
321                'sg' => 'asi',
322                'sh' => 'afr',
323                'si' => 'eur',
324                'sj' => 'eur',
325                'sk' => 'eur',
326                'sl' => 'afr',
327                'sm' => 'eur',
328                'sn' => 'afr',
329                'so' => 'afr',
330                'sr' => 'ams',
331                'st' => 'afr',
332                'sv' => 'amc',
333                'sx' => 'amc',
334                'sy' => 'asi',
335                'sz' => 'afr',
336                'tc' => 'amc',
337                'td' => 'afr',
338                'tf' => 'ant',
339                'tg' => 'afr',
340                'th' => 'asi',
341                'tj' => 'asi',
342                'tk' => 'oce',
343                'tl' => 'asi',
344                'tm' => 'asi',
345                'tn' => 'afr',
346                'to' => 'oce',
347                'tr' => 'eur',
348                'tt' => 'amc',
349                'tv' => 'oce',
350                'tw' => 'asi',
351                'tz' => 'afr',
352                'ua' => 'eur',
353                'ug' => 'afr',
354                'um' => 'oce',
355                'us' => 'amn',
356                'uy' => 'ams',
357                'uz' => 'asi',
358                'va' => 'eur',
359                'vc' => 'amc',
360                've' => 'ams',
361                'vg' => 'amc',
362                'vi' => 'amc',
363                'vn' => 'asi',
364                'vu' => 'oce',
365                'wf' => 'oce',
366                'ws' => 'oce',
367                'ye' => 'asi',
368                'yt' => 'afr',
369                'za' => 'afr',
370                'zm' => 'afr',
371                'zw' => 'afr',
372                'xx' => 'unk',
373        );
374
375my $new_visit = q{
376    INSERT INTO
377        piwik_log_visit
378   
379        (   idsite,
380            visitor_localtime,
381            idvisitor,
382            visitor_returning,
383            visitor_count_visits,
384            visitor_days_since_last,
385            visitor_days_since_order,
386            visitor_days_since_first,
387            visit_first_action_time,
388            visit_last_action_time,
389            visit_entry_idaction_url,
390            visit_entry_idaction_name,
391            visit_exit_idaction_url,
392            visit_exit_idaction_name,
393            visit_total_actions,
394            visit_total_time,
395            visit_goal_converted,
396            visit_goal_buyer,
397            referer_type,
398            referer_name,
399            referer_url,
400            referer_keyword,
401            config_id,
402            config_os,
403            config_browser_name,
404            config_browser_version,
405            config_resolution,
406            config_pdf,
407            config_flash,
408            config_java,
409            config_director,
410            config_quicktime,
411            config_realplayer,
412            config_windowsmedia,
413            config_gears,
414            config_silverlight,
415            config_cookie,
416            location_ip,
417            location_browser_lang,
418            location_country,
419            location_provider,
420            location_continent)
421    VALUES
422        (   ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
423};
424
425sub getConfigHash
426{
427    my $hash = md5( @_ );
428    return substr($hash,0,LENGTH_BINARY_ID);
429}
430
431sub SHUTDOWN() {
432    #unlink($pidfile);
433    closelog();
434    exit;
435}
436
437sub try (&@) {
438    my($try,$catch) = @_;
439    eval { &$try };
440    if ($@) {
441        local $_ = $@;
442        &$catch;
443    }
444}
445
446sub catch (&) { $_[0] }
447
448sub getRequest
449{
450    my $json_string = shift;
451    my %request = %{ decode_json( $json_string ) };
452    return %request;
453}
454
455sub parseURL
456{
457    my $url = shift;
458    my $parse_query = shift;
459
460    $url =~ /
461            \s*
462            (?:
463                # scheme:subscheme:\/\/
464                ([a-z]+) : (?: ([a-z]*) : )? \/\/
465            )?
466            (?:
467                # username:password@
468                ( [^:@]* ) (?: : ([^:@]*) )? @
469            )?
470            (
471                # hostname|localhost|IP
472                (?: [a-z0-9_-]+ \. )+ [a-z]{2,}
473                |
474                localhost
475                |
476                (?: (?: [01]?\d\d? | 2[0-4]\d | 25[0-5] ) \. ){3}
477                (?: (?: [01]?\d\d? | 2[0-4]\d | 25[0-5] ) )
478            )
479            (?:
480                # :port
481                : (\d+)
482            )?
483            (?:
484                # \/path
485                ([^:\?\#]+)
486            )?
487            (?:
488                # ?query
489                \? ([^\#]+)
490            )?
491            (?:
492                # #fragment
493                \# ([^\s]+)
494            )?
495            \s*
496    /ix;
497    return () unless defined $5;
498    my %result = (
499                scheme                => $1 || '',
500                subscheme        => $2 || '',
501                user                => $3 || '',
502                pass                => $4 || '',
503                host                => $5,
504                port                => $6 || '',
505                path                => $7 || '',
506                query                => $8 || '',
507                fragment        => $9 || '',
508        );
509
510    return %result unless $parse_query;
511
512    my %query = ();
513    for my $par (split('&', $result{query})) {
514        next unless ( $par =~ /([^=]+)=(.*)/ );
515        $query{$1} = $2;
516    }
517    $result{query} = \%query;
518
519    return %result;
520}
521
522
523sub getRefererInformation
524{
525    use constant REFERER_TYPE_DIRECT_ENTRY              => 1;
526        use constant REFERER_TYPE_SEARCH_ENGINE     => 2;
527        use constant REFERER_TYPE_WEBSITE                       => 3;
528        use constant REFERER_TYPE_CAMPAIGN                      => 6;
529
530        my $refererUrl = shift;
531        my $currentUrl = shift;
532        my $idSite = shift;
533
534        # default values for the referer_* fields
535        my %refererUrlParse;
536        % refererUrlParse = parseURL($refererUrl) if $refererUrl;
537
538        my %currentUrlParse;
539        %currentUrlParse = parseURL($currentUrl) if $currentUrl;
540        my $typeRefererAnalyzed = REFERER_TYPE_DIRECT_ENTRY;
541        my $nameRefererAnalyzed = '';
542        my $keywordRefererAnalyzed = '';
543        my $refererHost = '';
544
545        $refererHost = $refererUrlParse{'host'} if(defined $refererUrlParse{'host'});
546        my $refererDetected = 0;
547#TODO Companies are not supported yet!
548#       if( defined( $currentUrlParse{'host'} ) &&      getCampaignParameters )
549#       {
550#               $refererDetected = 1;
551#       }
552        unless($refererDetected)
553        {
554        my $SearchEngine = 0;
555        my $DirectEntry = 0;
556        if($refererHost =~ /^$/)
557        {
558                #is the referer host the current host?
559            if(defined $currentUrlParse{'host'})
560            {
561                my $currentHost = lc($currentUrlParse{'host'});
562                if($currentHost eq lc($refererHost))
563                {
564                        $typeRefererAnalyzed = REFERER_TYPE_DIRECT_ENTRY;
565                        my $DirectEntry = 1;
566                }
567            }
568#TODO This feature is not yet implemented.
569#           if(isHostKnownAliasHost($refererHost, $idsite))
570#           {
571#               $typeRefererAnalyzed = REFERER_TYPE_DIRECT_ENTRY;
572#               my $DirectEntry = 1;
573#           }
574        }
575
576        if(%refererUrlParse)
577        {
578            $typeRefererAnalyzed = REFERER_TYPE_SEARCH_ENGINE;
579            $nameRefererAnalyzed = $refererUrlParse{'host'};
580            $keywordRefererAnalyzed = $refererUrlParse{'query'};
581            $SearchEngine = 1;
582        }
583        $refererDetected = 1 if( $DirectEntry || $SearchEngine );
584        }
585        if( !($refererHost =~ /^$/) && !$refererDetected)
586        {
587                $typeRefererAnalyzed = REFERER_TYPE_WEBSITE;
588                $nameRefererAnalyzed = lc($refererHost);
589        }
590        my %refererInformation = (
591                'referer_type'          => $typeRefererAnalyzed,
592                'referer_name'          => $nameRefererAnalyzed,
593                'referer_keyword'       => $keywordRefererAnalyzed,
594                'referer_url'           => $refererUrl,
595        );
596        return %refererInformation;
597}
598
599
600sub getVisitorUniqueId
601{
602    return md5(luniqid);
603}
604
605sub getUserSettingsInformation
606{
607    my( $request, $visitorIP) = @_;
608
609    my $plugin_Flash                    = $$request{'fla'} || 0;
610    my $plugin_Java                     = $$request{'java'} || 0;
611    my $plugin_Director                 = $$request{'dir'} || 0;
612    my $plugin_Quicktime                = $$request{'qt'} || 0;
613    my $plugin_RealPlayer               = $$request{'realp'} || 0;
614    my $plugin_PDF                          = $$request{'pdf'} || 0;
615    my $plugin_WindowsMedia     = $$request{'wma'} || 0;
616    my $plugin_Gears                    = $$request{'gears'} || 0;
617    my $plugin_Silverlight              = $$request{'ag'} || 0;
618    my $plugin_Cookie           = $$request{'cookie'} || 0;
619        my $browserName             = $$request{'browserName'}||'UNK';
620    my $browserVersion          = $$request{'browserVersion'}||'';
621    my $os                                      = $$request{'os'}||'UNK';
622    my $resolution                      = $$request{'res'}||'unknown';
623    my $browserLang                 = $$request{'browserLang'};
624    my $config_id = getConfigHash($os.$browserName.$browserVersion.$plugin_Flash.$plugin_Java.$plugin_Director.$plugin_Quicktime.$plugin_RealPlayer.$plugin_PDF.$plugin_WindowsMedia.$plugin_Gears.$plugin_Silverlight.$plugin_Cookie.$visitorIP.$browserLang);
625    my %userSettingsInformation = (             'config_id'                     => $config_id,
626                                                        'config_os'                     => $os,
627                                                        'config_browser_name'   => $browserName,
628                                                        'config_browser_version' => $browserVersion,
629                                                        'config_resolution'     => $resolution,
630                                                        'config_pdf'                    => $plugin_PDF,
631                                                        'config_flash'                  => $plugin_Flash,
632                                                        'config_java'                   => $plugin_Java,
633                                                        'config_director'               => $plugin_Director,
634                                                        'config_quicktime'              => $plugin_Quicktime,
635                                                        'config_realplayer'     => $plugin_RealPlayer,
636                                                        'config_windowsmedia'   => $plugin_WindowsMedia,
637                                                        'config_gears'                  => $plugin_Gears,
638                                                        'config_silverlight'    => $plugin_Silverlight,
639                                                        'config_cookie'                 => $plugin_Cookie,
640                                                        'location_browser_lang' => $browserLang
641                                  );
642    return %userSettingsInformation;
643}
644
645
646my $dbh = DBI->connect("DBI:$driver:database=$database;host=$hostname", $user, $password) or die print "Can't connect";
647my $sth = $dbh->do( "SET NAMES utf8" ) || die "Can't prepare statement: $DBI::errstr";
648
649my @row = ();
650
651my $succsess = 0;
652my $skip = 0;
653my $unknowURL = 0;
654my $unknowName = 0;
655my $jsonErr = 0;
656syslog("debug", "Parser started!");
657my $part = "";
658open FIL, "+< $logfile" or syslog("debug", "The FIFO file \"$logfile\" is missing, and this program can't run without it.:$!");
659while (my $s=<FIL>)
660{
661    while ($s=~s/.*save,(.*)//)
662    {
663        my $visitorKnow = 0;
664        my $isLastActionInTheSameVisit = 0;
665        my $idActionUrl;
666        my $idActionName;
667        my $err = 0;
668        my $data = $1;
669#        syslog("debug", $data);
670        if($data=~s/.*part:(.*)//)
671        {
672            unless($part)
673            {
674                $part .="$1";
675                next;
676            }
677            $data = $part.$1;
678            $part = "";
679        }
680        my %request =();
681        try{
682            %request = getRequest($data);
683        }catch{
684            $err = 1;
685        };
686        if( $err )
687        {
688            $jsonErr++;
689            next;
690        }
691        my $visitorIP = inet_aton( $request{'ipString'} );
692
693        my $visitTimestamp = $request{'dateTime'};
694        my $visitTime = time2iso($visitTimestamp);
695
696        my %userInfo = getUserSettingsInformation(\%request, $visitorIP );
697        #TODO Check whether there is 'custom variables', to get information and set a flag in case of
698
699        #Get from the database id for the actionName and actionUrl
700        $sth = $dbh->prepare( $action_id ) || die "Can't prepare statement: $DBI::errstr";
701       
702        my $url = $request{'url'};
703        if( !($url = ~/^$/) && defined($request{'action_name'}))
704        {
705            $url =~s/\?&/\?/g;
706            $sth->execute($request{'action_name'},$request{'action_name'},$url,$url);
707            while (@row = $sth->fetchrow_array)
708            {
709                $idActionUrl = $row[0] if $row[1] == TYPE_ACTION_URL;
710                $idActionName = $row[0] if $row[1]== TYPE_ACTION_NAME;
711            }
712            $sth->finish;
713            unless($idActionUrl)
714            {
715                $sth->prepare("INSERT INTO pwk_log_action ( name, hash, type ) VALUES (?,CRC32(?),?)");
716                $sth->execute($url,$url,TYPE_ACTION_URL);
717                $idActionUrl = $sth->{mysql_insertid};
718                $sth->finish;
719            }
720            unless($idActionName)
721            {
722                $sth->prepare("INSERT INTO pwk_log_action ( name, hash, type ) VALUES (?,CRC32(?),?)");
723                $sth->execute($request{'action_name'},$request{'action_name'},TYPE_ACTION_NAME);
724                $idActionName = $sth->{mysql_insertid};
725                $sth->finish;
726            }
727        }
728        else
729        {
730            $idActionUrl=0;
731        }
732        $idActionName = 0 unless $idActionName;
733        #Check whether the earlier visit and get the last visit
734        my $visit_time = time2iso($visitTimestamp - 1800);
735        $sth = $dbh->prepare($visit ) || die "Can't prepare statement: $DBI::errstr";
736        $sth->execute( $visit_time, $request{'idsite'}, $userInfo{'config_id'});
737        my $rows = $sth->rows;
738        my @visitorInfo = ();
739        if($rows>0)
740        {
741            while (@row = $sth->fetchrow_array){
742                for my $key (0..(scalar @row)-1){
743                   push(@visitorInfo, ${ $sth->{NAME} }[$key]);
744                   push(@visitorInfo, (defined $row[$key])?$row[$key]:"");
745                }
746            }
747            $visitorKnow=1;
748        }
749        my %visitorInfo = @visitorInfo;
750        $#visitorInfo = -1;
751        $sth->finish;
752        if( defined $visitorInfo{'visit_last_action_time'} )
753        {
754            my $visit_time = DateCalc($visitTime,"30 minutes ago");
755            my $last_visit_time = ParseDate($visitorInfo{'visit_last_action_time'});
756            my $tmp = Date_Cmp($visit_time, $last_visit_time);
757            if($tmp < 1)
758            {
759                $isLastActionInTheSameVisit = 1;
760            }
761        }
762        if($visitorKnow && $isLastActionInTheSameVisit)
763        {
764            my $totalTime = $visitTimestamp  -  str2time($visitorInfo{'visit_first_action_time'});
765            my $timeSpentRefererAction= $visitTimestamp  -  str2time($visitorInfo{'visit_last_action_time'});
766            $visitorInfo{'time_spent_ref_action'} = $timeSpentRefererAction;
767            last if $totalTime < 0;
768            $sth = $dbh->prepare( $know_visit ) || die "Can't prepare statement: $DBI::errstr";
769            $sth->execute(  $idActionUrl,
770                            $idActionName,
771                            $visitTime,
772                            $totalTime,
773                            $visitorInfo{'idvisitor'},
774                            $visitorInfo{'visit_goal_buyer'},
775                            $request{'idsite'},
776                            $visitorInfo{'idvisit'},
777                          ) || die "Can't prepare statement: $DBI::errstr";
778        }
779        if(!$visitorKnow || !$isLastActionInTheSameVisit)
780        {
781            ( $request{'h'}, $request{'m'}, $request{'s'} ) = UnixDate($visitTimestamp, "%H", "%M", "%S") unless ( $request{'h'} && $request{'m'} && $request{'s'} ) ;
782            my $localTime = $request{'h'}.":".$request{'m'}.":".$request{'s'};
783            my $idcookie;
784            $idcookie = $visitorInfo{'idvisitor'} if $visitorKnow;
785            if(!$idcookie)
786            {
787                $idcookie = pack("H*", substr(getVisitorUniqueId, 0, LENGTH_HEX_ID_STRING));
788                $visitorInfo{'idvisitor'} = $idcookie;
789            }
790            my $defaultTimeOnePageVisit = 0;
791            #Days since first visit
792            my $cookieFirstVisitTimestamp = $request{'_idts'};
793            $cookieFirstVisitTimestamp = $visitTimestamp unless($cookieFirstVisitTimestamp);
794
795            my $daysSinceFirstVisit = round(($visitTimestamp - $cookieFirstVisitTimestamp)/86400);
796            $daysSinceFirstVisit = 0 if( $daysSinceFirstVisit < 0);
797
798            #Number of Visits
799            my $visitCount = $request{'_idvc'} || 1;
800
801            # Days since last visit
802            my $daysSinceLastVisit = 0;
803            my $lastVisitTimestamp = $request{'_viewts'};
804            if($lastVisitTimestamp)
805            {
806                $daysSinceLastVisit = round(($visitTimestamp - $lastVisitTimestamp)/86400);
807                $daysSinceLastVisit = 0 if( $daysSinceLastVisit < 0);
808            }
809            my $daysSinceLastOrder = 0;
810            my $isReturningCustomer = 0;
811
812            my $lastOrderTimestamp = $request{'_ects'};
813            if($lastOrderTimestamp)
814            {
815                $daysSinceLastOrder = round(($visitTimestamp - $lastOrderTimestamp)/86400);
816                $daysSinceLastOrder = 0 if($daysSinceLastOrder < 0);
817                $isReturningCustomer = 1;
818            }
819
820            #User settings
821            my $refererUrl      = $request{'urlref'} || "";
822            my $currentUrl      = $request{'url'} || "";
823            $visitorInfo{'time_spent_ref_action'} = 0;
824            $visitorInfo{'visit_exit_idaction_url'} = 0;
825            $visitorInfo{'visit_exit_idaction_name'} = 0;
826
827            #referep raser
828            my %refererInfo = getRefererInformation($refererUrl, $currentUrl, $request{'idsite'});
829
830            my $location_provider = gethostbyaddr($visitorIP, AF_INET);
831            $location_provider = "Ip" unless $location_provider;
832
833            $sth = $dbh->prepare( $new_visit ) || die "Can't prepare statement: $DBI::errstr";
834            $sth->execute(  $request{'idsite'},
835                            $localTime,
836                            $idcookie,
837                            $isReturningCustomer ? 2 : ( $visitCount > 1 || $visitorKnow ),
838                            $visitCount,
839                            $daysSinceLastVisit,
840                                $daysSinceLastOrder,
841                                $daysSinceFirstVisit,
842                            $visitTime,
843                            $visitTime,
844                            $idActionUrl,
845                            $idActionName,
846                            $idActionUrl,
847                            $idActionName,
848                            1,
849                            $defaultTimeOnePageVisit,
850                            0,
851                            0,
852                            $refererInfo{'referer_type'},
853                            $refererInfo{'referer_name'},
854                            $refererInfo{'referer_url'},
855                            $refererInfo{'referer_keyword'},
856                            $userInfo{'config_id'},
857                            $userInfo{'config_os'},
858                            $userInfo{'config_browser_name'},
859                            $userInfo{'config_browser_version'},
860                            $userInfo{'config_resolution'} || 'unknown',
861                            $userInfo{'config_pdf'},
862                            $userInfo{'config_flash'},
863                            $userInfo{'config_java'},
864                            $userInfo{'config_director'},
865                            $userInfo{'config_quicktime'},
866                            $userInfo{'config_realplayer'},
867                            $userInfo{'config_windowsmedia'},
868                            $userInfo{'config_gears'},
869                            $userInfo{'config_silverlight'},
870                            $userInfo{'config_cookie'},
871                            $visitorIP,
872                            $userInfo{'location_browser_lang'},
873                            $request{'country'},
874                            $location_provider,
875                            $CountryList{$request{'country'}}
876                          ) || die "Can't prepare statement: $DBI::errstr";
877        }
878
879        # Update the information of Visitor activity.
880        $visitorInfo{'idvisit'} = $sth->{mysql_insertid} unless( defined $visitorInfo{'idvisit'});
881        $sth = $dbh->prepare( $link_visit_action ) || die "Can't prepare statement: $DBI::errstr";
882        $sth->execute(  $visitorInfo{'idvisit'},
883                        $request{'idsite'},
884                        $visitorInfo{'idvisitor'},
885                        $visitTime,
886                        $idActionUrl,
887                        $idActionName,
888                        $visitorInfo{'visit_exit_idaction_url'},
889                        $visitorInfo{'visit_exit_idaction_name'},
890                        $visitorInfo{'time_spent_ref_action'}
891                     ) || die "Can't prepare statement: $DBI::errstr";
892        $succsess ++;
893    }
894}
895$dbh->disconnect;
896close FIL;
897exit(0)