ONO::Cron::CronSync::Web

package ONO::Cron::CronSync::Web;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################

use strict;

use ONO::IO;

###############################################################################
# ONO
###############################################################################

#: Website related services for ONO's CronSync service.

sub run {

my (
$self,
$CRON_DIR,
$job,
$data_ref,
$TYPE_ref,
$vars_ref,
$vpath,
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,
$timestamp,
$switches,
) = @_;

#: Execution logic.

my %data = %$data_ref;
my %TYPE = %$TYPE_ref;
my %vars = %$vars_ref;

my ($DATA,$MAIL);

if ($data{'type'} eq "web_analytics") {

foreach my $site (ONO::IO->dir("var/log/apache")) {
if ($site !~ /\./ && $site =~ /[A-Za-z0-9]/) {
ONO::IO->mkdir("var/log/apache/$site/analytics");
foreach my $opt ('today','week','month') {
ONO::IO->mkdir("var/log/apache/$site/analytics/$opt");
my @files = ('current.log');
my $files_counter;
my $REPORT = "Starting to process logs on $mday/$mon/$year \@ $hour:$min:$sec\n";
if ($opt eq "week" || $opt eq "month") {
@files = ();
my $max_files = 7;
if ($opt eq "month") {
$max_files = 31;
}
foreach my $file (reverse sort ONO::IO->ls("var/log/apache/$site")) {
if ($file !~ /^\./ && $file =~ /\.log$/ && $file ne "current.log" && $files_counter < $max_files) {
$files_counter++;
@files = (@files,$file);
}
}
}

my (%IP,%AGENT);

foreach my $file (@files) {
$REPORT .= "Reading data from '$file'...\n";
foreach my $line (ONO::IO->list("var/log/apache/$site/$file")) {
if ($line =~ m~(.*?) (.*?) (.*?) (.*?) "(.*?)" "(.*?)"~) {
my $ip = $2;
my $time = $4;
my $url = $5;
my $agent = lc $6;

$IP{$ip}++;

if ($agent =~ /(macintosh|windows|linux|iphone|ipad|android|mobile)/i) {
$agent = $1;
}
if ($agent =~ /(apachehttpclient|whatsapp)/) {
$agent = "mobile";
}
if ($agent =~ /(python|fetch|mozilla|libwww)/) {
$agent = "unknown";
}

$agent =~ s~[^a-z]~~g;
if ($agent) {
$AGENT{$agent}++;
}
}
}
}

my ($users,$bounces,$pages) = (0,0,0);

foreach my $key (keys %IP) {
$users++;
if ($IP{$key} < 2) {
$bounces++;
} else {
$pages = $pages + $IP{$key};
}
}
ONO::IO->store("var/log/apache/$site/analytics/$opt/ip_user_stats.txt","$users:$bounces:$pages:");

my $UA;
foreach my $key (reverse sort {$AGENT{$a} <=> $AGENT{$b}} keys %AGENT) {
$UA .= "$AGENT{$key}:$key\n";
}
ONO::IO->store("var/log/apache/$site/analytics/$opt/user_agents.txt",$UA);

ONO::IO->store("var/log/apache/$site/analytics/$opt/report.txt",$REPORT);
}
}
}

}

if ($data{'type'} eq "web_import") {
}
if ($data{'type'} eq "web_export") {
}
if ($data{'type'} eq "user_import") {
}
if ($data{'type'} eq "user_export") {
}
if ($data{'type'} eq "user_rmexp") {
}
if ($data{'type'} eq "user_htaccess") {
}

return ($DATA,$MAIL);

}

###############################################################################
# end of script
###############################################################################

1;

__END__