#!/usr/bin/perl use strict; use warnings; package President; print $0 ."\n"; print `pwd` . "\n"; my $self = $$; print "I am $self\n"; use Mojolicious::Lite; use Mojo::IOLoop; use Mojo::Server::Daemon; use Mojo::Server::Morbo; use Mojo::Server::Prefork; use Mojo::Server::Hypnotoad; use Data::Dumper; use File::Slurp; use Time::Local; use Time::Piece; use Time::Duration; use Date::Parse; use Mojo::JSON qw(decode_json encode_json); use Mojo::Reactor::Poll; use threads 'exit' => 'threads_only'; my $working_dir = $0; my $present_dir = `pwd`; my $dump_dir = &home('~/.president'); `rm -R $dump_dir/*`; my $duty_file = &home('~/.president/on_duty'); `touch $duty_file`; write_file($duty_file, 0); my $config_file = read_file('./config.json'); my $config = decode_json $config_file; our $logfile = &home($config->{'logfile'}); `touch $logfile` if not -e $logfile; our $log = Mojo::Log->new(path => $logfile); if ($working_dir ne $present_dir) { my @folder = split '/', $working_dir; pop @folder; my $new_dir = join '/', @folder; print 'chdir to ' . $new_dir . "\n"; chdir $new_dir; print `pwd` . "\n"; } #`espeak "president has begun"`; my $environment = shift; my $cache_dir = &home('~/') . '.president'; `mkdir -p $cache_dir` unless -e $cache_dir; require './gb.pl'; $gb::duty_time = &subs::rightNow(); my $random_number = 0; until ($random_number > 1024 && $random_number < 65532) { $random_number = int(rand(65532)); } my $on_duty = 0; my $hour = localtime( &subs::rightNow() / 1000 )->strftime( "%H"); my $domain = $config->{'domain'} || '127.0.0.1'; #my $domain = '127.0.0.1'; my $device = &device_setter(); if ($device eq 'mobile') { `termux-wake-lock`; `sshd`; } if ($config->{'open_browser'} eq 'yes') { if ($device eq 'mobile') { threads->create(sub() { `termux-open https://127.0.0.1:$random_number/manager & ` }); } elsif ($device eq 'computer') { threads->create(sub() { `export DISPLAY=:0`; my $chrome = `chromium https://$domain:$random_number/manager &`; }); } } if ($environment) { if ($environment =~ /^dev/) { $config->{'environment'} = 'development'; } elsif ($environment =~ /^pro/) { $config->{'environment'} = 'production'; } } my $port = $random_number || $config->{'port'}; my $alarm_port = $port + 2; my $ws_port = $port + 1; my $dock_port = 3000; my $tty_port = $port + 3; if ($config->{'environment'} eq 'development') { $ws_port = $port; } my @threads; sub manager_starter() { my $ws_tty_port = $tty_port + 1; $ENV{PORT_AHOY} = $random_number; $ENV{PORT_MSG} = $ws_port; $ENV{PORT_BELL} = $alarm_port; $ENV{PORT_BESTOW} = $tty_port; $ENV{PORT_DOCK} = $dock_port; $ENV{PORT_COMS} = $ws_tty_port; $ENV{PORT_ENV} = $config->{'environment'}; $ENV{cookie_name} = 'president'; my $certs = ""; if (-e './server/fullchain.pem' && -e './server/privkey.pem') { $certs = "?cert=./server/fullchain.pem&key=./server/privkey.pem"; } my $time_count = 0; write_file($duty_file, &subs::rightNow()); $ENV{'MOJO_MAX_LINE_SIZE'} = "64000"; if ($config->{'environment'} eq 'development') { threads->create(sub() { print "Starting Locker Server on port " . $dock_port . "\n"; $ENV{MOJO_LISTEN} = 'https://*:' . $dock_port . $certs; $ENV{PURPOSE} = 'locker'; my $morbo = Mojo::Server::Morbo->new; $morbo->backend->watch(['./', './templates']); $morbo = $morbo->daemon(Mojo::Server::Daemon->new); $morbo->run('./Manager.pl'); }); if ($ENV{PORT_AHOY} != $ENV{PORT_MSG}) { threads->create(sub() { print "Starting WS Server on port " . $ws_port . "\n"; $ENV{MOJO_LISTEN} = 'https://*:' . $ws_port . $certs; $ENV{PURPOSE} = 'websocket'; my $morbo = Mojo::Server::Morbo->new; $morbo->backend->watch(['./', './templates']); $morbo = $morbo->daemon(Mojo::Server::Daemon->new); $morbo->run('./Manager.pl'); }); } threads->create(sub() { print "Starting Main Server on port " . $port . "\n"; $ENV{MOJO_LISTEN} = 'https://*:' . $port . $certs; $ENV{PURPOSE} = 'main'; my $morbo = Mojo::Server::Morbo->new; $morbo = $morbo->daemon(Mojo::Server::Daemon->new); $morbo->backend->watch(['./', './templates']); $morbo->run('./Manager.pl'); }); } elsif ($config->{'environment'} eq 'production') { push @threads, threads->create(sub() { print "Starting Pro Locker Server on port " . $dock_port . "\n"; $ENV{MOJO_LISTEN} = 'https://*:' . $dock_port . $certs; $ENV{PURPOSE} = 'locker'; my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]); $prefork->load_app('./Manager.pl'); $prefork->workers(1); $prefork->run; $log->info('after locker server'); }); push @threads, threads->create(sub() { print "Starting Pro WS Server on port " . $ws_port . "\n"; $ENV{MOJO_LISTEN} = 'https://*:' . $ws_port . $certs; $ENV{PURPOSE} = 'websocket'; my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]); $prefork->load_app('./Manager.pl'); $prefork->workers(1); $prefork->run; $log->info('after ws server'); }); push @threads, threads->create(sub() { print "Starting Pro Main Server on port " . $port . "\n"; $ENV{MOJO_LISTEN} = 'https://*:' . $port . $certs; $ENV{PURPOSE} = 'main'; my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]); $prefork->load_app('./Manager.pl'); $prefork->workers(7); $prefork->run; $log->info('after main server'); }); } else { print "I have no environment!\n"; } if ($device ne 'server') { threads->create(sub() { $ENV{PURPOSE} = "watch"; $ENV{MOJO_LISTEN} = 'https://*:' . $alarm_port . $certs; if ($config->{'environment'} eq 'development') { print "Starting Development Watch Server on $alarm_port\n"; my $morbo = Mojo::Server::Morbo->new; $morbo = $morbo->daemon(Mojo::Server::Daemon->new); $morbo->run('./watch.pl'); } elsif ($config->{'environment'} eq 'production') { print "Starting Pro Watch Server on port " . $alarm_port . "\n"; my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]); $prefork->load_app('./watch.pl'); $prefork->workers(3); $prefork->run; } }); threads->create(sub() { $ENV{PURPOSE} = "teletype"; $ENV{MOJO_LISTEN} = 'https://*:' . $tty_port . $certs; if ($config->{'environment'} eq 'development') { print "Starting Development TTY Server on $tty_port\n"; my $morbo = Mojo::Server::Morbo->new; $morbo = $morbo->daemon(Mojo::Server::Daemon->new); $morbo->run('./teletype.pl'); } elsif ($config->{'environment'} eq 'production') { print "Starting Pro TTY Server on port " . $tty_port . "\n"; my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]); $prefork->load_app('./teletype.pl'); $prefork->workers(3); $prefork->run; } }); threads->create(sub() { $ENV{MOJO_LISTEN} = 'http://*:' . $ws_tty_port ; if ($config->{'environment'} eq 'development') { print "Starting Development TTYws Server on $ws_tty_port\n"; my $morbo = Mojo::Server::Morbo->new; $morbo = $morbo->daemon(Mojo::Server::Daemon->new); $morbo->run('./teletype.pl'); } elsif ($config->{'environment'} eq 'production') { print "Starting Pro TTYws Server on port " . $ws_tty_port . "\n"; my $prefork = Mojo::Server::Prefork->new(listen => [ $ENV{MOJO_LISTEN} ]); $prefork->load_app('./teletype.pl'); $prefork->workers(1); $prefork->run; } }); } print "Starting Alarm Clock\n"; $ENV{PURPOSE} = "alarm"; require './Alarm.pl'; $gb::alarm_running = 0; $gb::budget_running = 0; $gb::housekeeping_running = 0; $gb::clothesline_running = 0; my $id = Mojo::IOLoop->recurring($gb::timeouts->{'alarm'} => sub () { if ($gb::alarm_running != 1) { $gb::alarm_running = 1; $gb::alarm_running = 0; } &Alarm::alarm_clock() if $config->{'environment'} eq 'production'; }); my $big = Mojo::IOLoop->recurring($gb::timeouts->{'budget'} => sub() { if ($gb::budget_running == 0) { $gb::budget_running = 1; $gb::budget_running = &Alarm::budget_watcher(); } }); if ($device eq 'mobile') { my $sms = Mojo::IOLoop->recurring($gb::timeouts->{'sms'} => sub() { my $returner = &subs::sms_list_check(); }); } my $backups = Mojo::IOLoop->recurring($gb::timeouts->{'backups'} => sub() { my ($db,$database,$sql) = &subs::database_grabber(); if ($db) { my $c = app->build_controller; my $suds = &subs::suds_grabber(); $c->session('suds' => $suds); $c->param('reason' => 'backup'); if ($suds ne '') { &subs::backup_now($c); } } }); my $clothes = Mojo::IOLoop->recurring($gb::timeouts->{'clothesline'} => sub() { if ($gb::clothesline_running == 0) { $gb::clothesline_running = 1; &subs::hang_to_dry(); $gb::clothesline_running = 0; } }); my $tasks = Mojo::IOLoop->recurring($gb::timeouts->{'tasks'} => sub() { if ($gb::tasks_running == 0) { $gb::tasks_running = 1; $gb::tasks_running = &Alarm::task_checker(); } }); my $sync = Mojo::IOLoop->recurring($gb::timeouts->{'remote_machine_sync'} => sub() { if ($gb::syncing == 0) { $gb::syncing = 1; my $gimme; my $hour = localtime( &subs::rightNow() / 1000 )->strftime( "%H"); if ($hour eq 4) { $gimme = '1d'; } &subs::remote_machine_negotiator({ gimme => $gimme }); $gb::syncing = 0; } }); my $house = Mojo::IOLoop->recurring($gb::timeouts->{'housekeeping'} => sub() { if ($gb::housekeeping_running == 0) { $gb::housekeeping_running = 1; $gb::housekeeping_running = &Alarm::housekeeping(); } }); Mojo::IOLoop->start; while (1) { sleep 1; } END { print "quitting now!\n"; print "They dead\n"; # `./scripts/manager_killer.pl`; } } &manager_starter(); sub home() { my ($inhabitant) = @_; my $com = 'echo $HOME'; my $cwd = `$com`; chomp $cwd; $inhabitant =~ s/~/$cwd/; return $inhabitant; } sub device_setter() { my $device = 'computer'; if ($config->{'device'}) { $device = $config->{'device'}; } else { my $uname = `uname -a`; if ($uname =~ /Android/gi) { $device = 'mobile'; } elsif ($uname =~ /Debian/gi) { $device = 'server'; } } return $device; }