393 lines
16 KiB
Perl
Executable File
393 lines
16 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
package Alarm;
|
|
|
|
use Mojolicious::Lite;
|
|
use List::Util qw(shuffle);
|
|
use Mojo::Util qw/html_unescape term_escape/;
|
|
use Time::Duration;
|
|
use Date::Parse;
|
|
use Time::Piece;
|
|
use Crypt::Simple;
|
|
use File::Slurp;
|
|
use Mojo::JSON qw(decode_json encode_json);
|
|
use Data::Dumper;
|
|
use Time::HiRes qw(gettimeofday time);
|
|
|
|
require "./gb.pl";
|
|
require "./subroutines.pl";
|
|
require "./Manager.pl";
|
|
require "./Websocket.pl";
|
|
my $config_file = read_file('./config.json');
|
|
my $config = decode_json $config_file;
|
|
our $logfile = &subs::home($config->{'logfile'});
|
|
`touch $logfile` if not -e $logfile;
|
|
our $log = Mojo::Log->new(path => $logfile);
|
|
my $device = &subs::device_setter();
|
|
my $last_moment = &subs::rightNow();
|
|
my $last_paper_moment = &subs::rightNow();
|
|
|
|
|
|
sub alarm_clock() {
|
|
my ($dber,$dot,$sql) = &subs::database_grabber();
|
|
|
|
return unless $dber;
|
|
my $timestamp = &subs::rightNow();
|
|
$last_moment = &subs::rightNow();
|
|
my $query = &subs::db_query('select * from appointments where (timestamp <= ? and seen is null) or ((type = ? or type = ? or type = ? or type=? or type = ?) and stop_timestamp is not null and stop_timestamp <= ? and stop_seen is null ) order by timestamp',
|
|
$timestamp, 'start','record','video','audio','screen',$timestamp);
|
|
|
|
my $alarm = $query->hashes;
|
|
|
|
my $duty_watch = &subs::db_query('select * from appointments where duties is not null and next_duty <= ? and next_duty is not null', $timestamp)->hashes;
|
|
foreach my $dw ( @{$duty_watch} ) {
|
|
my $duties = eval { return decode_json $dw->{'duties'} } || [];
|
|
my @seen_duties;
|
|
foreach my $duty ( @{$duties} ) {
|
|
my $jduty = encode_json $duty;
|
|
if ($duty->{'timestamp'} <= $timestamp) {
|
|
push @{$alarm}, {
|
|
app => $dw->{'app'},
|
|
type => $duty->{'duty'},
|
|
uuid => $dw->{'uuid'},
|
|
data => $jduty,
|
|
timestamp => $dw->{'timestamp'}
|
|
};
|
|
push @seen_duties, $duty->{'duuid'};
|
|
}
|
|
}
|
|
foreach my $sd ( @seen_duties ) {
|
|
@{$duties} = grep { $_->{'duuid'} && $_->{'duuid'} ne $sd } @{$duties};
|
|
}
|
|
my $next_duty = $duties->[0]->{'timestamp'};
|
|
@{$duties} = grep { $_->{'duuid'} } @{$duties};
|
|
@{$duties} = sort { $a->{'timestamp'} <=> $b->{'timestamp'} } @{$duties};
|
|
|
|
my $jduties = encode_json $duties;
|
|
if (scalar @{$duties} == 0) {
|
|
$jduties = undef;
|
|
}
|
|
&subs::db_update('appointments', { duties => $jduties, next_duty => $next_duty, server_time => &subs::rightNow() }, { app => $dw->{'app'}, uuid => $dw->{'uuid'} });
|
|
}
|
|
|
|
if (scalar @{$alarm} > 0) {
|
|
my $interval = 'second';
|
|
my $default_warranty = &subs::setting_grabber({ app => 'me', setting => 'warranty' }) || '-10d';
|
|
|
|
my $warranty = &subs::ago_calc($default_warranty, $timestamp);
|
|
my $t = &{$subs::time_subs->{$interval}}($timestamp);
|
|
my $t1 = ($timestamp - $t);
|
|
foreach my $a ( @{$alarm} ) {
|
|
&subs::db_query('update appointments set seen = ? where uuid=?', 'yes',$a->{'uuid'});
|
|
&subs::cache_delete({ app => $a->{'app'}, context => 'template' });
|
|
my $type = $a->{'type'};
|
|
|
|
if ($a->{'stop_timestamp'} && $a->{'stop_timestamp'} <= $timestamp && grep { $a->{'type'} eq $_ } qw/start video audio screen record/) {
|
|
|
|
if ($a->{'type'} eq 'start' || $a->{'type'} eq 'record') {
|
|
if ($a->{'type'} eq 'record') {
|
|
my $data = eval { return decode_json $a->{'data'} } || {};
|
|
my $recording_type = &subs::setting_grabber({ app => $a->{'app'}, setting => 'record' }) || 'system';
|
|
if ($data->{'recorder'} eq 'security') {
|
|
&Manager::record_video_stop({ app => $a->{'app'}, uuid => $a->{'uuid'}, timestamp => $a->{'timestamp'} });
|
|
}
|
|
elsif ($data->{'recorder'} eq 'system') {
|
|
&Manager::record_audio_stop({ app => $a->{'app'}, uuid => $a->{'uuid'}, timestamp => $a->{'timestamp'} });
|
|
}
|
|
else {
|
|
&Websocket::send('music', { console => 'jpStop(\'' . $a->{'app'} . '\',\'' . $data->{'recorder'} . '\',\'' . $a->{'uuid'} . '\');' });
|
|
}
|
|
}
|
|
else {
|
|
&subs::db_query('update appointments set seen = ?,type=?, stop_seen=? where uuid=?', 'yes','stop', 'yes',$a->{'uuid'});
|
|
}
|
|
&subs::intelligent_automation_toggle({ app => $a->{'app'}, 'state' => 'off', timestamp => $timestamp });
|
|
$type = 'stop';
|
|
|
|
my $sources = &subs::db_select('appointments', undef, { source_uuid => $a->{'uuid'} })->hashes;
|
|
|
|
foreach my $so ( @{$sources} ) {
|
|
push @{$sources}, @{&subs::db_select('appointments', undef, { source_uuid => $so->{'uuid'} })->hashes};
|
|
if ( $so->{'type'} eq 'start' && (!$so->{'stop_timestamp'} || $so->{'stop_timestamp'} <= $timestamp) ) {
|
|
my $dur = $so->{'timestamp'} - $timestamp;
|
|
&subs::db_update('appointments', { stop_seen => 'yes', type => 'stop', duration => $dur }, { source_uuid => $so->{'source_uuid'}, uuid => $so->{'uuid'} });
|
|
&budget_runner($so->{'app'});
|
|
&subs::intelligent_automation_toggle({ appt_uuid => $so->{'uuid'}, app => $so->{'app'}, 'state' => 'off', timestamp => $timestamp });
|
|
&Websocket::send('tab', { console => 'appointmentDetailGrabber(\'' . $so->{'app'} . '\',\'' . $so->{'uuid'} .'\');'});
|
|
}
|
|
}
|
|
|
|
}
|
|
else {
|
|
&subs::db_query('update appointments set seen = ?, stop_seen=? where uuid=?', 'yes', 'yes',$a->{'uuid'});
|
|
}
|
|
&Websocket::send('tab', { console => 'appointmentDetailGrabber("' . $a->{'app'} . '","' . $a->{'uuid'} .'");' });
|
|
|
|
}
|
|
elsif ($a->{'type'} eq 'start' || $a->{'type'} eq 'record') {
|
|
&subs::intelligent_automation_toggle({ app => $a->{'app'}, 'state' => 'on', timestamp => $a->{'timestamp'} });
|
|
|
|
my $sources = &subs::db_select('appointments', undef, { source_uuid => $a->{'uuid'} })->hashes;
|
|
|
|
foreach my $so ( @{$sources} ) {
|
|
push @{$sources}, @{&subs::db_select('appointments', undef, { source_uuid => $so->{'uuid'} })->hashes};
|
|
if ( $so->{'type'} eq 'start' && (!$so->{'stop_timestamp'} || $so->{'stop_timestamp'} <= $timestamp) ) {
|
|
&subs::db_update('appointments', { seen => 'yes' }, { source_uuid => $so->{'source_uuid'}, uuid => $so->{'uuid'} });
|
|
&budget_runner($so->{'app'});
|
|
&subs::intelligent_automation_toggle({ appt_uuid => $so->{'uuid'}, app => $so->{'app'}, 'state' => 'on', timestamp => $timestamp });
|
|
&Websocket::send('tab', { console => 'appointmentDetailGrabber(\'' . $so->{'app'} . '\',\'' . $so->{'uuid'} .'\');'});
|
|
}
|
|
}
|
|
if ($a->{'type'} eq 'record') {
|
|
my $recording_type = &subs::setting_grabber({ app => $a->{'app'}, setting => 'record' }) || 'system';
|
|
my $data = eval { return decode_json $a->{'data'} } || {};
|
|
if ($data->{'recorder'} eq 'security') {
|
|
&Manager::record_video({ app => $a->{'app'}, uuid => $a->{'uuid'}, timestamp => $a->{'timestamp'} });
|
|
} elsif ($data->{'recorder'} eq 'system') {
|
|
&Manager::record_audio({ app => $a->{'app'}, uuid => $a->{'uuid'}, timestamp => $a->{'timestamp'} });
|
|
}
|
|
elsif ($data->{'recorder'} eq 'screen') {
|
|
&Websocket::send('music', { console => 'jpScreen(\'' . $a->{'app'} . '\',\'' . $a->{'uuid'} . '\');' });
|
|
}
|
|
else {
|
|
&Websocket::send('music', { console => 'jpStart(\'' . $a->{'app'} . '\',\'' . $data->{'recorder'} . '\',\'' . $a->{'uuid'} . '\');' });
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
elsif ($a->{'type'} eq 'stop' || $a->{'type'} eq 'cancel') {
|
|
&subs::intelligent_automation_toggle({ app => $a->{'app'}, 'state' => 'off', timestamp => $timestamp });
|
|
}
|
|
elsif ($a->{'type'} eq 'image') {
|
|
my $data = decode_json $a->{'data'};
|
|
my $c = app->build_controller;
|
|
$c->stash('app' => $a->{'app'});
|
|
$c->session('timestamp' => $timestamp);
|
|
my ($file,$ocr) = &Manager::take_picture($c,{ app => $a->{'app'}, timestamp => $timestamp, camera => $data->{'camera'}, uuid => $a->{'uuid'} });
|
|
}
|
|
elsif ($a->{'type'} eq 'scan') {
|
|
my $scandata = decode_json $a->{'data'};
|
|
my $c = app->build_controller;
|
|
$c->stash('app' => $a->{'app'});
|
|
$c->stash('timestamp' => $a->{'timestamp'});
|
|
my $file = &Manager::scan($c, $scandata);
|
|
}
|
|
|
|
|
|
&subs::appt_header_printer({ app => $a->{'app'} });
|
|
my $settings = &subs::settings_grabber({ app => $a->{'app'} }) || {};
|
|
my $name = &subs::format_name($a->{'app'});
|
|
my $app = &subs::unformat_name($a->{'app'});
|
|
my $account = &subs::format_name($a->{'account'});
|
|
if ($settings->{'notification'} && $settings->{'notification'} eq 'on') {
|
|
&Manager::notification_sender({
|
|
app => $app,
|
|
role => 'all',
|
|
uuid => $a->{'uuid'},
|
|
type => $type,
|
|
settings => $settings,
|
|
sound => 'crystal.mp3',
|
|
title => $name,
|
|
},$dot);
|
|
}
|
|
if ($a->{'type'} =~ /command|kill|record/) {
|
|
my $command = $settings->{$a->{'type'}};
|
|
my $resulter = &subs::run_command($app,$command);
|
|
if ($a->{'type'} eq 'command') {
|
|
&subs::setting_setter({ app => $app, setting => 'toggle', value => 'on' });
|
|
}
|
|
elsif ($a->{'type'} eq 'kill') {
|
|
&subs::setting_setter({ app => $app, setting => 'toggle', value => 'off' });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
my $ticket_query = &subs::db_query('select count(*) from tickets where status = ? and warranty < ?', 'active', $timestamp);
|
|
my $t_count = $ticket_query->text;
|
|
if ($t_count > 0) {
|
|
my $ticket_update_query = &subs::db_query('update tickets set status = ? where status = ? and warranty < ?', 'expired', 'active', $timestamp);
|
|
my $msg = { app => 'box_office', console => 'ticket_list()' };
|
|
my $server_time = &subs::rightNow();
|
|
&Websocket::send('server', $msg);
|
|
}
|
|
|
|
my $warranty_query = &subs::db_query('select * from appointments where warranty < ?',$timestamp);
|
|
my $haircut = $warranty_query->hashes;
|
|
|
|
foreach my $h ( @{$haircut} ) {
|
|
foreach my $t ( qw/appointments/ ) {
|
|
&Manager::delete_app($h->{'app'}, $h->{'uuid'},$h->{'server_time'},'alarm runner');
|
|
#&subs::db_delete($t, { app => $h->{'app'}, uuid => $h->{'uuid'} });
|
|
}
|
|
if (grep { $_ ne $h->{'app'} } qw/misc customs music __president me/) {
|
|
&subs::vacuum($h->{'app'});
|
|
}
|
|
}
|
|
|
|
my $backups = [];#&subs::db_query('select * from backups where warranty < ?', $timestamp)->hashes;
|
|
foreach my $b ( @{$backups} ) {
|
|
if (-e $b->{'destination'}) {
|
|
my $commander = 'shred -u ' . $b->{'destination'};
|
|
# `$commander`;
|
|
}
|
|
#&subs::db_delete('backups', { uuid => $b->{'uuid'} });
|
|
}
|
|
|
|
my $paper_q = &subs::db_query('select * from magazine where status=? and timestamp >= ? and timestamp <= ? and warranty >=?', 'publish',$last_paper_moment, $timestamp,$timestamp);
|
|
my $papers = $paper_q->hashes;
|
|
foreach my $paper ( @{$papers} ) {
|
|
my $c = app->build_controller;
|
|
$paper->{'art'} = $c->render_to_string(template => 'article', art => $paper);
|
|
&Manager::paperRoute($paper);
|
|
}
|
|
$last_paper_moment = &subs::rightNow();
|
|
&subs::db_query('delete from magazine where warranty < ?', $timestamp);
|
|
&subs::db_query('delete from continent where warranty < ?', $timestamp);
|
|
&subs::db_query('delete from websites where warranty < ?', $timestamp);
|
|
&subs::db_query('delete from cache where warranty < ?', $timestamp);
|
|
|
|
my $websocks = &subs::db_query('select * from websockets where warranty < ?', $timestamp);
|
|
foreach my $webs (@{$websocks->hashes}) {
|
|
my $art_query = &subs::db_query('delete from drawings where browser_tab_id = ?', $webs->{'browser_tab_id'});
|
|
my $del_query = &subs::db_query('delete from websockets where browser_tab_id = ?', $webs->{'browser_tab_id'});
|
|
}
|
|
}
|
|
|
|
sub budget_watcher() {
|
|
my ($db,$database,$sql) = &subs::database_grabber('memory');
|
|
unless (&subs::setting_grabber({ app => 'me', setting => 'budget_alarm', device => $device }) eq 'on') { return 0; }
|
|
my $w_time = &subs::rightNow() + &subs::time_abbrev_translator('1m',&subs::rightNow());
|
|
|
|
my $budgets = &subs::db_query('select distinct(app) as app,* from settings where setting = ? and device = ? and value is not null','budget', $device)->hashes;
|
|
my $settings;
|
|
foreach my $b ( @{$budgets} ) {
|
|
my $app = $b->{'app'};
|
|
my @buds = split /,/, $b->{'value'};
|
|
my $scope;
|
|
$settings->{$app} = &subs::settings_grabber({ app => $app }) unless $settings->{$app};
|
|
foreach my $circumstance ( keys %{$gb::budget_modes} ) {
|
|
my $cache_budget = &subs::cache_get({ app => $app, context => 'budget', subcontext => $circumstance });
|
|
if ($cache_budget->{'scope'}) {
|
|
$scope = $cache_budget->{'scope'};
|
|
}
|
|
foreach my $bud ( @buds ) {
|
|
my @bt = split '/', $bud;
|
|
$scope = $bt[-1];
|
|
if (1) {
|
|
my $budget = &Manager::budget_calculator({
|
|
app => $app,
|
|
circumstance => $circumstance,
|
|
scope => $scope,
|
|
budget => $bud,
|
|
settings => $settings->{$app}
|
|
});
|
|
if ($budget->{'is_scope'} && $circumstance eq $budget->{'circumstance'}) {
|
|
my $server_time = &subs::rightNow();
|
|
$budget->{'timestamp'} = &subs::rightNow();
|
|
|
|
&subs::cache_delete({ app => $app, context => 'template' });
|
|
&subs::cache_set({ app => $app, context => 'budget', subcontext => $circumstance }, $budget);
|
|
|
|
if ($cache_budget->{'status'} ne $budget->{'status'}) {
|
|
my $websockets = &subs::db_query('select * from websockets where app = ? and windows like ? and server_time > ? and windows is not null order by timestamp DESC',
|
|
'tab', '%app":"' . $app . '%', $server_time - 5000)->hashes;
|
|
if (scalar @{$websockets} > 0) {
|
|
my $msg = {
|
|
app => $app,
|
|
type => 'budget',
|
|
budget => {
|
|
colour => $budget->{'colour'},
|
|
circumstance => $budget->{'circumstance'},
|
|
}
|
|
};
|
|
&Websocket::send('tab', $msg);
|
|
&subs::appt_header_printer({ app => $app });
|
|
}
|
|
|
|
my $message = &subs::format_name($app) . ' is ' . $budget->{'status'} . ' for ' . $circumstance . ': ' . $budget->{'formatted_value'} . '/' . $budget->{'formatted_budgeted'};
|
|
if (&subs::setting_grabber({ app => $app, setting => 'notification', device => $device }) eq 'on') {
|
|
&Manager::notification_sender({
|
|
app => $app,
|
|
role => 'all',
|
|
title => &subs::format_name($app),
|
|
synth => $budget->{'synth'},
|
|
words => $app,
|
|
message => $message,
|
|
image => "/images/decipherable/chart.png",
|
|
type => 'budget'
|
|
},$database);
|
|
}
|
|
#&Manager::budget_autocalc({
|
|
# app => $app,
|
|
# circumstance => $circumstance,
|
|
#});
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
sub housekeeping() {
|
|
|
|
my ($db,$database,$sql) = &subs::database_grabber();
|
|
my $server_time = &subs::rightNow();
|
|
my $settings = &subs::settings_grabber({ app => '__president', device => $device });
|
|
my @cache_folders = split /\n/, $settings->{'cache_folders'};
|
|
foreach my $cf (@cache_folders) {
|
|
if ($cf ne '/' && $cf ne &subs::home('~/') && $cf =~ /[a-z0-9A-Z]/) {
|
|
my $folder = &subs::home($cf);
|
|
my $doomed = `ls -a $cf`;
|
|
|
|
my @doomed = split /\n/, $doomed;
|
|
foreach my $doom ( @doomed ) {
|
|
my $rip = $folder . '/' . $doom;
|
|
unless ($doom eq '.' || $doom eq '..') {
|
|
# my $success = `shred -u $rip`;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
my $expiration = &subs::ago_calc('-1h', $server_time);
|
|
my $websockets = &subs::db_query('delete from websockets where server_time < ? and room is not null', $expiration);
|
|
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
sub task_checker() {
|
|
my $server_time = &subs::rightNow();
|
|
my $tasks = &subs::db_query('select app from settings where setting = ? and value is not null','tasks')->hashes;
|
|
foreach my $task ( @{$tasks} ) {
|
|
my $app = $task->{'app'};
|
|
my $taskskis = &subs::task_grabber($app);
|
|
my $websockets = &subs::db_query('select * from websockets where app = ? and windows like ? and server_time > ? and windows is not null order by timestamp DESC',
|
|
'tab', '%app":"' . $app . '%', $server_time - 5000)->hashes;
|
|
if (scalar @{$websockets} > 0) {
|
|
|
|
my $msg = {
|
|
app => $app,
|
|
type => 'html',
|
|
selector => '.re_tasks[app="' . $app . '"]',
|
|
content => $taskskis->{'html'}
|
|
};
|
|
&Websocket::send('server', $msg);
|
|
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
1;
|