Compare commits

...

2 Commits

Author SHA1 Message Date
7c70c1f12d Added %SCAN command, to send unsent mail from an area
All checks were successful
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 30s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 1m34s
Create Docker Image / Final Docker Image Manifest (push) Successful in 8s
2024-11-01 10:04:12 +11:00
247d30505e Show %AREA in area commands back to user 2024-11-01 08:15:32 +11:00
6 changed files with 180 additions and 15 deletions

View File

@ -35,6 +35,8 @@ class Area extends Base
public function process(): string public function process(): string
{ {
$command = self::command.' '.join(' ',$this->arguments);
// If command starts with '-', its to unsubscribe // If command starts with '-', its to unsubscribe
if (str_starts_with($this->arguments[0],'-')) { if (str_starts_with($this->arguments[0],'-')) {
$sub = FALSE; $sub = FALSE;
@ -54,6 +56,7 @@ class Area extends Base
// Drop the area from the arguments, the rest are options // Drop the area from the arguments, the rest are options
array_shift($this->arguments); array_shift($this->arguments);
// Area exists
if ($ea=$this->mo->fftn->domain->echoareas->where('name',$area)->pop()) { if ($ea=$this->mo->fftn->domain->echoareas->where('name',$area)->pop()) {
// If already subscribed // If already subscribed
if ($nea=$this->mo->fftn->echoareas->where('name',$area)->pop()) { if ($nea=$this->mo->fftn->echoareas->where('name',$area)->pop()) {
@ -61,7 +64,7 @@ class Area extends Base
if ($sub) { if ($sub) {
Log::debug(sprintf('%s:- FTN [%s] ALREADY subscribed to [%s] since [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area,$nea->pivot->subscribed->format('Y-m-d H:i'))); Log::debug(sprintf('%s:- FTN [%s] ALREADY subscribed to [%s] since [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area,$nea->pivot->subscribed->format('Y-m-d H:i')));
return sprintf('%-25s <-- ALREADY subscribed since %s',$area,$nea->pivot->subscribed->format('Y-m-d H:i')); return sprintf('%-25s <-- ALREADY subscribed since %s',$command,$nea->pivot->subscribed->format('Y-m-d H:i'));
// requesting to unsubscribe // requesting to unsubscribe
} else { } else {
@ -80,7 +83,7 @@ class Area extends Base
Log::debug(sprintf('%s:- FTN [%s] UNSUBSCRIBED from [%s] clearing [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area,$x)); Log::debug(sprintf('%s:- FTN [%s] UNSUBSCRIBED from [%s] clearing [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area,$x));
return sprintf('%-25s <-- UNSUBSCRIBED, CLEARED [%d] MSGS from queue',$area,$x); return sprintf('%-25s <-- UNSUBSCRIBED, CLEARED [%d] MSGS from queue',$command,$x);
} }
// If not subscribed // If not subscribed
@ -99,42 +102,42 @@ class Area extends Base
AreafixRescan::dispatch($this->mo->fftn,$ea,$m[2]) AreafixRescan::dispatch($this->mo->fftn,$ea,$m[2])
->onQueue('mail'); ->onQueue('mail');
return sprintf('%-25s <-- AREA SUBSCRIBED, RESCAN [%d] DAYS queued',$area,$m[2]); return sprintf('%-25s <-- SUBSCRIBED, RESCAN [%d] DAYS queued',$command,$m[2]);
// Scan // Scan
case 'R': case 'R':
AreafixRescan::dispatch($this->mo->fftn,$ea,$m[2],TRUE) AreafixRescan::dispatch($this->mo->fftn,$ea,$m[2],TRUE)
->onQueue('mail'); ->onQueue('mail');
return sprintf('%-25s <-- AREA SUBSCRIBED, FORCE RESCAN [%d] DAYS queued',$area,$m[2]); return sprintf('%-25s <-- SUBSCRIBED, FORCE RESCAN [%d] DAYS queued',$command,$m[2]);
} }
} }
return sprintf('%-25s <-- AREA SUBSCRIBED, INVALID OPTIONS',$area); return sprintf('%-25s <-- SUBSCRIBED, INVALID OPTIONS',$command);
} elseif (count($this->arguments) > 1) { } elseif (count($this->arguments) > 1) {
Log::debug(sprintf('%s:- FTN [%s] subscribed to [%s], extra commands [%s] ignored',self::LOGKEY,$this->mo->fftn->ftn,$area,implode('|',$this->arguments))); Log::debug(sprintf('%s:- FTN [%s] subscribed to [%s], extra commands [%s] ignored',self::LOGKEY,$this->mo->fftn->ftn,$area,join('|',$this->arguments)));
return sprintf('%-25s <-- AREA SUBSCRIBED, OPTIONS IGNORED',$area); return sprintf('%-25s <-- SUBSCRIBED, OPTIONS IGNORED',$command);
} else { } else {
Log::debug(sprintf('%s:- FTN [%s] subscribed to [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area)); Log::debug(sprintf('%s:- FTN [%s] subscribed to [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area));
return sprintf('%-25s <-- AREA SUBSCRIBED',$area); return sprintf('%-25s <-- SUBSCRIBED',$command);
} }
// If not subscribed, "you arent subscribed, arguments ignored" // If not subscribed, "you arent subscribed, arguments ignored"
} else { } else {
Log::debug(sprintf('%s:- FTN [%s] is NOT subscribed to [%s], NO ACTION taken',self::LOGKEY,$this->mo->fftn->ftn,$area)); Log::debug(sprintf('%s:- FTN [%s] is NOT subscribed to [%s], NO ACTION taken',self::LOGKEY,$this->mo->fftn->ftn,$area));
return sprintf('%-25s <-- NOT subscribed, NO ACTION taken',$area); return sprintf('%-25s <-- NOT subscribed, NO ACTION taken',$command);
} }
} }
} else { } else {
Log::debug(sprintf('%s:- FTN [%s] area UNKNOWN [%s], NO ACTION taken',self::LOGKEY,$this->mo->fftn->ftn,$area)); Log::debug(sprintf('%s:- FTN [%s] area UNKNOWN [%s], NO ACTION taken',self::LOGKEY,$this->mo->fftn->ftn,$area));
return sprintf('%-25s <-- AREA UNKNOWN, NO ACTION TAKEN',$area); return sprintf('%-25s <-- AREA UNKNOWN, NO ACTION TAKEN',$command);
} }
} }
} }

View File

@ -30,11 +30,15 @@ class Help extends Base
$result = collect(); $result = collect();
foreach (preg_grep('/^([^.])/',scandir(self::areafix_classes)) as $file) { foreach (preg_grep('/^([^.])/',scandir(self::areafix_classes)) as $file) {
if ($file === 'Base.php') if (($file === 'Base.php') || (! str_ends_with(strtolower($file),'.php')))
continue; continue;
$class = Areafix::areafix_commands.preg_replace('/\.php$/','',$file); $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)); Notification::route('netmail',$this->mo->fftn)->notify(new HelpNotification($this->mo,$result));

View File

@ -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);
}
}
}

View File

@ -10,8 +10,10 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Middleware\Skip; use Illuminate\Queue\Middleware\Skip;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use App\Models\{Address,Echoarea,Echomail}; use App\Models\{Address,Echoarea,Echomail};
use App\Notifications\Netmails\Areafix\Scan;
class AreafixRescan implements ShouldQueue class AreafixRescan implements ShouldQueue
{ {
@ -78,6 +80,10 @@ class AreafixRescan implements ShouldQueue
{ {
$c = 0; $c = 0;
$s = 0; $s = 0;
$earliest = NULL;
$latest = NULL;
foreach (Echomail::select(['id','datetime']) foreach (Echomail::select(['id','datetime'])
->where('echoarea_id',$this->eao->id) ->where('echoarea_id',$this->eao->id)
->where('datetime','>=', ->where('datetime','>=',
@ -93,6 +99,12 @@ class AreafixRescan implements ShouldQueue
$eo->seenby()->attach($this->ao->id,['export_at'=>Carbon::now()]); $eo->seenby()->attach($this->ao->id,['export_at'=>Carbon::now()]);
$c++; $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)); 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 { } else {
@ -109,6 +121,12 @@ class AreafixRescan implements ShouldQueue
$eo->seenby()->updateExistingPivot($this->ao,['export_at'=>Carbon::now(),'sent_at'=>NULL]); $eo->seenby()->updateExistingPivot($this->ao,['export_at'=>Carbon::now(),'sent_at'=>NULL]);
$c++; $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)); Log::debug(sprintf('Re-exported [%d] MSG (%s) dated (%s) to [%s]',$eo->id,$eo->msgid ?: '*NO MSGID*',$eo->datetime,$this->ao->ftn3d));
} else { } else {
@ -126,12 +144,26 @@ class AreafixRescan implements ShouldQueue
$eo->seenby()->attach($this->ao,['export_at'=>Carbon::now(),'sent_at'=>NULL,'sent_pkt'=>NULL]); $eo->seenby()->attach($this->ao,['export_at'=>Carbon::now(),'sent_at'=>NULL,'sent_pkt'=>NULL]);
$c++; $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)); 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)); Log::info(sprintf('%s:= Queued [%d], Skipped [%d] echomails for [%s] in [%s]',self::LOGKEY,$c,$s,$this->ao->ftn,$this->eao->name));
} }
} }

View File

@ -53,8 +53,6 @@ class Help extends Netmails
$msg->addText("$command\r"); $msg->addText("$command\r");
} }
$msg->addText("\r");
$o->msg = $msg->render(); $o->msg = $msg->render();
$o->set_tagline = 'Why did the robot cross the road? The chicken programmed it.'; $o->set_tagline = 'Why did the robot cross the road? The chicken programmed it.';

View File

@ -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;
}
}