2023-09-13 10:58:22 +00:00
< ? 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 ;
2023-09-22 04:45:44 +00:00
use Illuminate\Support\Facades\Storage ;
use League\Flysystem\UnableToMoveFile ;
2023-09-13 10:58:22 +00:00
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 ));
2023-09-22 04:45:44 +00:00
$fs = Storage :: disk ( config ( 'fido.local_disk' ));
2023-10-04 11:22:01 +00:00
// @todo Catch files that we cannot process, eg: ARJ bundles.
2023-09-13 10:58:22 +00:00
try {
$f = new File ( $this -> file -> full_name );
$processed = FALSE ;
foreach ( $f as $packet ) {
2023-09-20 10:29:23 +00:00
$pkt = Packet :: process ( $packet , Arr :: get ( stream_get_meta_data ( $packet ), 'uri' ), $f -> itemSize (), $this -> ao -> zone -> domain );
2023-09-13 10:58:22 +00:00
// Check the messages are from the uplink
2023-09-14 22:09:42 +00:00
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 ));
2023-09-13 10:58:22 +00:00
break ;
}
// Check the packet password
2023-11-24 22:47:58 +00:00
if ( strtoupper ( $this -> ao -> session ( 'pktpass' )) !== strtoupper ( $pkt -> password )) {
2023-09-14 22:09:42 +00:00
Log :: error ( sprintf ( '%s:! Packet from [%s] with password [%s] is invalid.' , self :: LOGKEY , $this -> ao -> ftn , $pkt -> password ));
2023-09-13 10:58:22 +00:00
2023-09-14 22:09:42 +00:00
Notification :: route ( 'netmail' , $this -> ao ) -> notify ( new PacketPasswordInvalid ( $pkt -> password , $this -> file -> nameas ));
2023-09-13 10:58:22 +00:00
break ;
}
2023-09-14 22:09:42 +00:00
Log :: info ( sprintf ( '%s:- Packet has [%d] messages' , self :: LOGKEY , $pkt -> count ()));
2023-09-13 10:58:22 +00:00
// Queue messages if there are too many in the packet.
2023-09-22 04:45:44 +00:00
if ( $queue = ( $pkt -> count () > config ( 'fido.queue_msgs' )))
2023-09-13 10:58:22 +00:00
Log :: info ( sprintf ( '%s:- Messages will be sent to the queue for processing' , self :: LOGKEY ));
$count = 0 ;
2023-09-14 22:09:42 +00:00
foreach ( $pkt as $msg ) {
2023-09-13 10:58:22 +00:00
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 )
2023-09-14 22:09:42 +00:00
MessageProcess :: dispatch ( $msg , $f -> pktName (), $this -> ao , $pkt -> fftn_o , $this -> rcvd_time );
2023-09-13 10:58:22 +00:00
else
2023-09-14 22:09:42 +00:00
MessageProcess :: dispatchSync ( $msg , $f -> pktName (), $this -> ao , $pkt -> fftn_o , $this -> rcvd_time );
2023-09-13 10:58:22 +00:00
} 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 ++ ;
}
2023-09-14 22:09:42 +00:00
if ( $count === $pkt -> count ())
2023-09-13 10:58:22 +00:00
$processed = TRUE ;
}
if ( ! $processed ) {
Log :: alert ( sprintf ( '%s:- Not deleting packet [%s], it doesnt seem to be processed?' , self :: LOGKEY , $this -> file -> nameas ));
2023-09-22 04:45:44 +00:00
} else {
2023-09-13 10:58:22 +00:00
// If we want to keep the packet, we could do that logic here
2023-09-22 04:45:44 +00:00
if ( config ( 'fido.packet_keep' )) {
2024-05-12 10:50:19 +00:00
$dir = sprintf ( '%s/%s/%s/%s' , config ( 'fido.dir' ),( $x = Carbon :: now ()) -> format ( 'Y' ), $x -> format ( 'm' ), $x -> format ( 'd' ));
2023-09-22 04:45:44 +00:00
Log :: debug ( sprintf ( '%s:- Moving processed packet [%s] to [%s]' , self :: LOGKEY , $this -> file -> rel_name , $dir ));
try {
if ( $fs -> makeDirectory ( $dir )) {
2023-09-23 12:01:18 +00:00
$fs -> move ( $this -> file -> rel_name , $x = sprintf ( '%s/%s' , $dir , $this -> file -> pref_name ));
2023-09-22 04:45:44 +00:00
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 );
}
2023-09-13 10:58:22 +00:00
}
} 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 ()]);
}
}
}