168 lines
6.0 KiB
PHP
168 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs;
|
|
|
|
use Carbon\Carbon;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
use Illuminate\Queue\InteractsWithQueue;
|
|
use Illuminate\Queue\SerializesModels;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use League\Flysystem\UnableToMoveFile;
|
|
|
|
use App\Classes\File;
|
|
use App\Classes\File\Item;
|
|
use App\Classes\FTN\{InvalidPacketException,Packet};
|
|
use App\Models\Address;
|
|
use App\Notifications\Netmails\PacketPasswordInvalid;
|
|
|
|
class PacketProcess implements ShouldQueue
|
|
{
|
|
private const LOGKEY = 'JPP';
|
|
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
|
private Item $file;
|
|
private Address $ao;
|
|
private Carbon $rcvd_time;
|
|
|
|
public function __construct(Item $file,Address $ao,Carbon $rcvd_time)
|
|
{
|
|
$this->file = $file;
|
|
$this->ao = $ao;
|
|
$this->rcvd_time = $rcvd_time;
|
|
}
|
|
|
|
public function __get($key): mixed
|
|
{
|
|
switch ($key) {
|
|
case 'subject':
|
|
return $this->file->name;
|
|
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When calling MessageProcess - we assume that the packet is from a valid source, and
|
|
* the destination (netmail/echomail) is also valid
|
|
*/
|
|
public function handle()
|
|
{
|
|
Log::info(sprintf('%s:- Processing mail %s [%s]',self::LOGKEY,$this->file->whatType() === Item::IS_PKT ? 'PACKET' : 'ARCHIVE',$this->file->nameas));
|
|
|
|
$fs = Storage::disk(config('fido.local_disk'));
|
|
|
|
// @todo Catch files that we cannot process, eg: ARJ bundles.
|
|
try {
|
|
$f = new File($this->file->full_name);
|
|
$processed = FALSE;
|
|
|
|
foreach ($f as $packet) {
|
|
$pkt = Packet::process($packet,Arr::get(stream_get_meta_data($packet),'uri'),$f->itemSize(),$this->ao->zone->domain);
|
|
|
|
// Check the messages are from the uplink
|
|
if ($this->ao->system->addresses->search(function($item) use ($pkt) { return $item->id === $pkt->fftn_o->id; }) === FALSE) {
|
|
Log::error(sprintf('%s:! Packet [%s] is not from this link? [%d]',self::LOGKEY,$pkt->fftn_o->ftn,$this->ao->system_id));
|
|
|
|
break;
|
|
}
|
|
|
|
// Check the packet password
|
|
if (strtoupper($this->ao->session('pktpass')) !== strtoupper($pkt->password)) {
|
|
Log::error(sprintf('%s:! Packet from [%s] with password [%s] is invalid.',self::LOGKEY,$this->ao->ftn,$pkt->password));
|
|
|
|
Notification::route('netmail',$this->ao)->notify(new PacketPasswordInvalid($pkt->password,$this->file->nameas));
|
|
break;
|
|
}
|
|
|
|
Log::info(sprintf('%s:- Packet has [%d] messages',self::LOGKEY,$pkt->count()));
|
|
|
|
// Queue messages if there are too many in the packet.
|
|
if ($queue = ($pkt->count() > config('fido.queue_msgs')))
|
|
Log::info(sprintf('%s:- Messages will be sent to the queue for processing',self::LOGKEY));
|
|
|
|
$count = 0;
|
|
foreach ($pkt as $msg) {
|
|
Log::info(sprintf('%s:- Mail from [%s] to [%s]',self::LOGKEY,$msg->fftn,$msg->tftn));
|
|
|
|
// @todo Quick check that the packet should be processed by us.
|
|
// @todo validate that the packet's zone is in the domain.
|
|
|
|
/*
|
|
* // @todo generate exception when echomail for an area that doesnt exist
|
|
* // @todo generate exception when echomail for an area sender cannot post to
|
|
* // @todo generate exception when echomail for an area sender not subscribed to
|
|
* // @todo generate exception when echomail comes from a system not defined here
|
|
* // @todo generate exception when echomail comes from a system doesnt exist
|
|
*
|
|
* // @todo generate exception when netmail to system that doesnt exist (node/point)
|
|
* // @todo generate exception when netmail from system that doesnt exist (node/point)
|
|
* // @todo generate warning when netmail comes from a system not defined here
|
|
*
|
|
* // @todo generate exception when packet has wrong password
|
|
*/
|
|
|
|
try {
|
|
// Dispatch job.
|
|
if ($queue)
|
|
MessageProcess::dispatch($msg,$f->pktName(),$this->ao,$pkt->fftn_o,$this->rcvd_time);
|
|
else
|
|
MessageProcess::dispatchSync($msg,$f->pktName(),$this->ao,$pkt->fftn_o,$this->rcvd_time);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error(sprintf('%s:! Got error dispatching message [%s] (%d:%s-%s).',self::LOGKEY,$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage()));
|
|
}
|
|
|
|
$count++;
|
|
}
|
|
|
|
if ($count === $pkt->count())
|
|
$processed = TRUE;
|
|
}
|
|
|
|
if (! $processed) {
|
|
Log::alert(sprintf('%s:- Not deleting packet [%s], it doesnt seem to be processed?',self::LOGKEY,$this->file->nameas));
|
|
|
|
} else {
|
|
// If we want to keep the packet, we could do that logic here
|
|
if (config('fido.packet_keep')) {
|
|
$dir = sprintf('%s/%d/%d/%d',config('fido.dir'),($x=Carbon::now())->format('Y'),$x->format('m'),$x->format('d'));
|
|
Log::debug(sprintf('%s:- Moving processed packet [%s] to [%s]',self::LOGKEY,$this->file->rel_name,$dir));
|
|
|
|
try {
|
|
if ($fs->makeDirectory($dir)) {
|
|
$fs->move($this->file->rel_name,$x=sprintf('%s/%s',$dir,$this->file->pref_name));
|
|
Log::info(sprintf('%s:- Moved processed packet [%s] to [%s]',self::LOGKEY,$this->file->rel_name,$x));
|
|
|
|
} else
|
|
Log::error(sprintf('%s:! Unable to create dir [%s]',self::LOGKEY,$dir));
|
|
|
|
} catch (UnableToMoveFile $e) {
|
|
Log::error(sprintf('%s:! Unable to move packet [%s] to [%s] (%s)',self::LOGKEY,$this->file->full_name,$dir,$e->getMessage()));
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error(sprintf('%s:! Failed moving packet [%s] to [%s] (%s)',self::LOGKEY,$this->file->full_name,$dir,$e->getMessage()));
|
|
}
|
|
|
|
} else {
|
|
Log::debug(sprintf('%s:- Deleting processed packet [%s]',self::LOGKEY,$this->file->full_name));
|
|
|
|
// @todo Change this to use Storage::disk()
|
|
unlink($this->file->full_name);
|
|
}
|
|
}
|
|
|
|
} catch (InvalidPacketException $e) {
|
|
Log::error(sprintf('%s:- Not deleting packet [%s], as it generated an InvalidPacketException',self::LOGKEY,$this->file->nameas),['e'=>$e->getMessage()]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error(sprintf('%s:- Not deleting packet [%s], as it generated an uncaught exception',self::LOGKEY,$this->file->nameas),['e'=>$e->getMessage()]);
|
|
}
|
|
}
|
|
} |