ONO::Cron::Service::Hourly

package ONO::Cron::Service::Hourly;
################################################################################
# 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;

use ONO::ToolBox::SendMail;
use ONO::Cron::Service::ToolBox;

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

#: ONO Cron Service hourly tasks.

sub run {

#: Execution logic.

my (
$self,
$db,
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$timestamp,
$switches,
) = @_;

my $DATA = ONO::Cron::Service::ToolBox->print("Service running: Hourly",$switches);

# my %vars;

############################################################################
# basic protection
############################################################################

foreach my $opt ('web','schoolweb') {
if (ONO::IO->exists($opt)) {

$DATA .= ONO::Cron::Service::ToolBox->print("- protecting: $opt",$switches);

foreach my $opt2 ('data') {
if (ONO::IO->exists("$opt/$opt2")) {
ONO::IO->htaccess("$opt/$opt2",":");
}
}
}
}

foreach my $opt ('var') {
if (ONO::IO->exists($opt)) {

$DATA .= ONO::Cron::Service::ToolBox->print("- protecting: $opt",$switches);

ONO::IO->htaccess($opt,":");

}
}

############################################################################
# clean up the /pdf/ directory
############################################################################

if (ONO::IO->exists("pdf") && ONO::IO->sysload() < 25) {
$DATA .= ONO::Cron::Service::ToolBox->print("- /pdf directory found, cleaning up...",$switches);
my ($files, $deleted) = (0,0);
foreach my $file (ONO::IO->dir("pdf")) {
if ($file =~ /^pdf-/ && $file =~ /\.pdf$/) {

$files++;
my $delete_exec;

if ($file =~ /^pdf-(workplan|report|print|evaluation)(-|_)(.*?)(-|_)(.*?)\.pdf$/) {
my $date = $3;
if (length $date == 8) {
if ($date < "${year}${mon}00") {
$delete_exec++;
}
}
} else {
if ($file =~ /^pdf-(.*?)(-|_)(.*?)\.pdf$/) {
my $date = $1;
if (length $date == 8) {
if ($date < "${year}${mon}00") {
$delete_exec++;
}
}
}
}

if (!$delete_exec && $file =~ $file =~ /^pdf-virclass-(.*?)-(.*?)-(.*?)-(.*?)\.pdf$/) {
my $date = $3;
if (length $date == 8) {
if ($date < "${year}${mon}00") {
$delete_exec++;
}
}
}

if ($delete_exec) {
$deleted++;
$DATA .= ONO::Cron::Service::ToolBox->print(" - deleting: $file",$switches);
ONO::IO->rm("pdf/$file");
}

}
}
$DATA .= ONO::Cron::Service::ToolBox->print("- $files files found, $deleted have been deleted",$switches);
}

############################################################################
# clean up /var/tmp/apps/exercises
############################################################################

if (ONO::IO->exists("var/tmp/apps/exercises") && ONO::IO->sysload() < 25) {

my $threshold = time()-(60*60*24*31);
my $mon2 = $mon-1;
if ($mon2 < 0) {
$mon2 = 0;
}
if (length $mon2 < 2) {
$mon2 = "0$mon2";
}
my $counter;

foreach my $area (ONO::IO->dir("var/tmp/apps/exercises")) {
if ($area =~ /[a-z0-9]/ && $counter < 4096) {
$counter++;
foreach my $d1 (ONO::IO->dir("var/tmp/apps/exercises/$area")) {
if ($d1 =~ /[a-z0-9]/ && $counter < 4096) {
$counter++;
foreach my $d2 (ONO::IO->dir("var/tmp/apps/exercises/$area/$d1")) {
if ($d2 =~ /[a-z0-9]/ && $counter < 4096) {
$counter++;
foreach my $d3 (ONO::IO->dir("var/tmp/apps/exercises/$area/$d1/$d2")) {
if ($d3 =~ /[a-z0-9]/ && $counter < 4096) {
&garbage_by_timestamp("","var/tmp/apps/exercises/$area/$d1/$d2/$d3",$threshold,"$year$mon2");
$counter++;
foreach my $d4 (ONO::IO->dir("var/tmp/apps/exercises/$area/$d1/$d2/$d3")) {
if ($d4 =~ /[a-z0-9]/ && $counter < 4096) {
&garbage_by_timestamp("","var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4",$threshold,"$year$mon2");
$counter++;
foreach my $d5 (ONO::IO->dir("var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4")) {
if ($d5 =~ /[a-z0-9]/ && $counter < 4096) {
&garbage_by_timestamp("","var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4/$d5",$threshold,"$year$mon2");
$counter++;
foreach my $d6 (ONO::IO->dir("var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4/$d5")) {
if ($d6 =~ /[a-z0-9]/ && $counter < 4096) {
&garbage_by_timestamp("","var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4/$d5/$d6",$threshold,"$year$mon2");
$counter++;
foreach my $d7 (ONO::IO->dir("var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4/$d5/$d6")) {
if ($d7 =~ /[a-z0-9]/ && $counter < 4096) {
&garbage_by_timestamp("","var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4/$d5/$d6/$d7",$threshold,"$year$mon2");
$counter++;
foreach my $d8 (ONO::IO->dir("var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4/$d5/$d6/$d7")) {
if ($d8 =~ /[a-z0-9]/ && $counter < 4096) {
&garbage_by_timestamp("","var/tmp/apps/exercises/$area/$d1/$d2/$d3/$d4/$d5/$d6/$d7/$d8",$threshold,"$year$mon2");
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}

############################################################################
# all done
############################################################################

return $DATA;

}

###############################################################################
# garbage collector for app exercise caches
###############################################################################

sub garbage_by_timestamp {

#: Garbage collection.

my (
$self,
$file,
$threshold,
$thresmon,
) = @_;

if ($file =~ m~^(.*)/(.*?)\.txt$~) {
my $filename = $2;
if (substr($filename,0,6) < $thresmon) {
ONO::IO->rm($file);
}
} else {

my $filename = $file;
$filename =~ s~^(.*)/~~;
if (length $filename == 10 && $filename =~ /[0-9]/ && $filename !~ /[A-Za-z]/ && $filename < $threshold) {
ONO::IO->rmdirsoft($file);
}
}
}

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

1;

__END__