diff --git a/app/Classes/FTN/Process/Netmail/Robot/Areafix/Area.php b/app/Classes/FTN/Process/Netmail/Robot/Areafix/Area.php index 9596a56..99b39ef 100644 --- a/app/Classes/FTN/Process/Netmail/Robot/Areafix/Area.php +++ b/app/Classes/FTN/Process/Netmail/Robot/Areafix/Area.php @@ -56,6 +56,7 @@ class Area extends Base // Drop the area from the arguments, the rest are options array_shift($this->arguments); + // Area exists if ($ea=$this->mo->fftn->domain->echoareas->where('name',$area)->pop()) { // If already subscribed if ($nea=$this->mo->fftn->echoareas->where('name',$area)->pop()) { diff --git a/app/Classes/FTN/Process/Netmail/Robot/Areafix/Help.php b/app/Classes/FTN/Process/Netmail/Robot/Areafix/Help.php index daac1db..28b398a 100644 --- a/app/Classes/FTN/Process/Netmail/Robot/Areafix/Help.php +++ b/app/Classes/FTN/Process/Netmail/Robot/Areafix/Help.php @@ -30,11 +30,15 @@ class Help extends Base $result = collect(); foreach (preg_grep('/^([^.])/',scandir(self::areafix_classes)) as $file) { - if ($file === 'Base.php') + if (($file === 'Base.php') || (! str_ends_with(strtolower($file),'.php'))) continue; $class = Areafix::areafix_commands.preg_replace('/\.php$/','',$file); - $result = $result->merge($class::help()); + if ($result->count()) + $result->push(''); + + $result = $result + ->merge($class::help()); } Notification::route('netmail',$this->mo->fftn)->notify(new HelpNotification($this->mo,$result)); diff --git a/app/Classes/FTN/Process/Netmail/Robot/Areafix/Scan.php b/app/Classes/FTN/Process/Netmail/Robot/Areafix/Scan.php new file mode 100644 index 0000000..8d188e0 --- /dev/null +++ b/app/Classes/FTN/Process/Netmail/Robot/Areafix/Scan.php @@ -0,0 +1,60 @@ +<?php + +namespace App\Classes\FTN\Process\Netmail\Robot\Areafix; + +use Illuminate\Support\Facades\Log; + +use App\Jobs\AreafixRescan; + +// SCAN - Send unsent echomail +class Scan extends Base +{ + private const LOGKEY = 'AFS'; + private const command = '%SCAN'; + + public static function help(): array + { + return [ + self::command.' [-|+]<ECHOAREA> [<DAYS>]', + ' Use the scan command to resend mail that you havent received yet from an', + ' echoarea. This is useful if you are rejoining an echoarea, and only want', + ' to get mail that you dont already have.', + ' Arguments:', + ' - ECHOAREA (required) name of area to subscribe or unsubscribe', + ' - DAYS (optional) number of days to resend mail from this area that you', + ' If DAYS is omitted, the default is 30', + ]; + } + + public function process(): string + { + Log::debug(sprintf('%s:- Areafix [%s] for [%s] for [%s]',self::LOGKEY,self::command,$this->mo->fftn->ftn,join('|',$this->arguments))); + + $command = self::command.' '.join(' ',$this->arguments); + + if (! is_numeric($this->arguments[1])) + return sprintf('%-25s <-- INVALID, DAYS [%s] NOT NUMERIC',$command,$this->arguments[1]); + + // Area exists + if ($ea=$this->mo->fftn->domain->echoareas->where('name',$this->arguments[0])->pop()) { + // If already subscribed + if ($this->mo->fftn->echoareas->pluck('name')->contains($this->arguments[0])) { + AreafixRescan::dispatch($this->mo->fftn,$ea,$this->arguments[1]) + ->onQueue('mail'); + + return sprintf('%-25s <-- SCAN [%d] DAYS queued',$command,$this->arguments[1]); + + // If not subscribed + } else { + Log::debug(sprintf('%s:- FTN [%s] is NOT subscribed to [%s], NO ACTION taken',self::LOGKEY,$this->mo->fftn->ftn,$this->arguments[0])); + + return sprintf('%-25s <-- NOT subscribed, NO ACTION taken',$command); + } + + } else { + Log::debug(sprintf('%s:- FTN [%s] area UNKNOWN [%s], NO ACTION taken',self::LOGKEY,$this->mo->fftn->ftn,$this->arguments[0])); + + return sprintf('%-25s <-- AREA UNKNOWN, NO ACTION TAKEN',$command); + } + } +} \ No newline at end of file diff --git a/app/Jobs/AreafixRescan.php b/app/Jobs/AreafixRescan.php index d88cab4..2674b8f 100644 --- a/app/Jobs/AreafixRescan.php +++ b/app/Jobs/AreafixRescan.php @@ -10,8 +10,10 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\Skip; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Notification; use App\Models\{Address,Echoarea,Echomail}; +use App\Notifications\Netmails\Areafix\Scan; class AreafixRescan implements ShouldQueue { @@ -78,6 +80,10 @@ class AreafixRescan implements ShouldQueue { $c = 0; $s = 0; + + $earliest = NULL; + $latest = NULL; + foreach (Echomail::select(['id','datetime']) ->where('echoarea_id',$this->eao->id) ->where('datetime','>=', @@ -93,6 +99,12 @@ class AreafixRescan implements ShouldQueue $eo->seenby()->attach($this->ao->id,['export_at'=>Carbon::now()]); $c++; + if (($eo->datetime < $earliest) || (! $earliest)) + $earliest = $eo->datetime; + + if (($latest < $eo->datetime) || (! $latest)) + $latest = $eo->datetime; + Log::debug(sprintf('Exported [%d] MSG (%s) dated (%s) to [%s]',$eo->id,$eo->msgid ?: '*NO MSGID*',$eo->datetime->format('Y-m-d H:i:s'),$this->ao->ftn3d)); } else { @@ -109,6 +121,12 @@ class AreafixRescan implements ShouldQueue $eo->seenby()->updateExistingPivot($this->ao,['export_at'=>Carbon::now(),'sent_at'=>NULL]); $c++; + if (($eo->datetime < $earliest) || (! $earliest)) + $earliest = $eo->datetime; + + if (($latest < $eo->datetime) || (! $latest)) + $latest = $eo->datetime; + Log::debug(sprintf('Re-exported [%d] MSG (%s) dated (%s) to [%s]',$eo->id,$eo->msgid ?: '*NO MSGID*',$eo->datetime,$this->ao->ftn3d)); } else { @@ -126,12 +144,26 @@ class AreafixRescan implements ShouldQueue $eo->seenby()->attach($this->ao,['export_at'=>Carbon::now(),'sent_at'=>NULL,'sent_pkt'=>NULL]); $c++; + if (($eo->datetime < $earliest) || (! $earliest)) + $earliest = $eo->datetime; + + if (($latest < $eo->datetime) || (! $latest)) + $latest = $eo->datetime; + Log::debug(sprintf('Exported [%d] to [%s]',$eo->id,$this->ao->ftn3d)); } } } - // @todo Send a netmail to the node about the rescan + Notification::route('netmail',$this->ao) + ->notify(new Scan(collect([ + 'area'=>$this->eao->name, + 'queued'=>$c, + 'skipped'=>$s, + 'earliest'=>$earliest, + 'latest'=>$latest, + ]))); + Log::info(sprintf('%s:= Queued [%d], Skipped [%d] echomails for [%s] in [%s]',self::LOGKEY,$c,$s,$this->ao->ftn,$this->eao->name)); } } \ No newline at end of file diff --git a/app/Notifications/Netmails/Areafix/Help.php b/app/Notifications/Netmails/Areafix/Help.php index 08b648c..16eb3c5 100644 --- a/app/Notifications/Netmails/Areafix/Help.php +++ b/app/Notifications/Netmails/Areafix/Help.php @@ -53,8 +53,6 @@ class Help extends Netmails $msg->addText("$command\r"); } - $msg->addText("\r"); - $o->msg = $msg->render(); $o->set_tagline = 'Why did the robot cross the road? The chicken programmed it.'; diff --git a/app/Notifications/Netmails/Areafix/Scan.php b/app/Notifications/Netmails/Areafix/Scan.php new file mode 100644 index 0000000..e156387 --- /dev/null +++ b/app/Notifications/Netmails/Areafix/Scan.php @@ -0,0 +1,68 @@ +<?php + +namespace App\Notifications\Netmails\Areafix; + +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Log; + +use App\Notifications\Netmails; +use App\Models\Netmail; +use App\Traits\{MessagePath,PageTemplate}; + +class Scan extends Netmails +{ + use MessagePath,PageTemplate; + + private const LOGKEY = 'ACS'; + + /** + * Reply to a areafix, commands unknown. + * + * @param Collection $result + */ + public function __construct(private Collection $result) + { + parent::__construct(); + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return Netmail + * @throws \Exception + */ + public function toNetmail(object $notifiable): Netmail + { + $o = $this->setupNetmail($notifiable); + $ao = $notifiable->routeNotificationFor(static::via); + + Log::info(sprintf('%s:+ Responding to areafix for a node [%s] scan processed',self::LOGKEY,$ao->ftn)); + + $o->subject = 'Areafix - Scan Results'; + + // Message + $msg = $this->page(FALSE,'Areafix'); + + $msg->addText("An areafix (re)Scan has completed:\r\r"); + + $msg->addText(sprintf("Area: %s, Queued: %d, Skipped: %d\r\r", + $this->result->get('area'), + $this->result->get('queued'), + $this->result->get('skipped'), + )); + + if ($x=$this->result->get('earliest')) + $msg->addText(sprintf("The earliest message being sent: %s.\r",$x)); + + if (($x=$this->result->get('latest')) && ($this->result->get('earliest') !== $x)) + $msg->addText(sprintf("The latest message being sent: %s.\r",$x)); + + $o->msg = $msg->render(); + $o->set_tagline = 'Why did the robot cross the road? The chicken programmed it.'; + + $o->save(); + + return $o; + } +} \ No newline at end of file