Implemented file sending during BINKP and EMSI sessions
This commit is contained in:
@@ -4,8 +4,11 @@ namespace App\Classes\File;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use League\Flysystem\UnreadableFileEncountered;
|
||||
|
||||
use App\Models\File;
|
||||
|
||||
/**
|
||||
* A file we are sending or receiving
|
||||
*
|
||||
@@ -35,6 +38,7 @@ class Item
|
||||
protected int $file_mtime = 0;
|
||||
protected int $file_type = 0;
|
||||
protected int $action = 0;
|
||||
protected File $filemodel;
|
||||
|
||||
public bool $sent = FALSE;
|
||||
public bool $received = FALSE;
|
||||
@@ -51,19 +55,27 @@ class Item
|
||||
|
||||
switch ($action) {
|
||||
case self::I_SEND:
|
||||
if (! is_string($file))
|
||||
throw new Exception('Invalid object creation - file should be a string');
|
||||
if ($file instanceof File) {
|
||||
$this->filemodel = $file;
|
||||
// @todo We should catch any exceptions if the default storage is s3 (it is) and we cannot find the file, or the s3 call fails
|
||||
$this->file_size = Storage::size($file->full_storage_path);
|
||||
$this->file_mtime = Storage::lastModified($file->full_storage_path);
|
||||
|
||||
if (! file_exists($file))
|
||||
throw new FileNotFoundException('Item doesnt exist: '.$file);
|
||||
} else {
|
||||
if (! is_string($file))
|
||||
throw new Exception('Invalid object creation - file should be a string');
|
||||
|
||||
if (! is_readable($file))
|
||||
throw new UnreadableFileEncountered('Item cannot be read: '.$file);
|
||||
if (! file_exists($file))
|
||||
throw new FileNotFoundException('Item doesnt exist: '.$file);
|
||||
|
||||
$this->file_name = $file;
|
||||
$x = stat($file);
|
||||
$this->file_size = $x['size'];
|
||||
$this->file_mtime = $x['mtime'];
|
||||
if (! is_readable($file))
|
||||
throw new UnreadableFileEncountered('Item cannot be read: '.$file);
|
||||
|
||||
$this->file_name = $file;
|
||||
$x = stat($file);
|
||||
$this->file_size = $x['size'];
|
||||
$this->file_mtime = $x['mtime'];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -104,7 +116,7 @@ class Item
|
||||
return $this->file_name;
|
||||
|
||||
case 'sendas':
|
||||
return basename($this->file_name);
|
||||
return $this->file_name ? basename($this->file_name) : $this->filemodel->file;
|
||||
|
||||
default:
|
||||
throw new Exception('Unknown key: '.$key);
|
||||
|
@@ -6,6 +6,7 @@ use Exception;
|
||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use League\Flysystem\UnreadableFileEncountered;
|
||||
|
||||
use App\Models\Address;
|
||||
@@ -52,12 +53,12 @@ final class Send extends Item
|
||||
|
||||
case 'file_count':
|
||||
return $this->list
|
||||
->filter(function($item) { return $item->isType(self::IS_FILE); })
|
||||
->filter(function($item) { return $item->isType(self::IS_FILE|self::IS_TIC); })
|
||||
->count();
|
||||
|
||||
case 'file_size':
|
||||
return $this->list
|
||||
->filter(function($item) { return $item->isType(self::IS_FILE); })
|
||||
->filter(function($item) { return $item->isType(self::IS_FILE|self::IS_TIC); })
|
||||
->sum(function($item) { return $item->file_size; });
|
||||
|
||||
case 'filepos':
|
||||
@@ -162,7 +163,8 @@ final class Send extends Item
|
||||
Log::debug(sprintf('%s: - Closing [%s], sent in [%d]',self::LOGKEY,$this->sending->file_name,$end));
|
||||
}
|
||||
|
||||
if (! $this->sending instanceof Mail)
|
||||
// @todo This should be done better isType == file?
|
||||
if ((! $this->sending instanceof Mail) && (! $this->sending->isType(self::IS_TIC)))
|
||||
fclose($this->f);
|
||||
|
||||
$this->sending = NULL;
|
||||
@@ -177,7 +179,44 @@ final class Send extends Item
|
||||
*/
|
||||
public function feof(): bool
|
||||
{
|
||||
return ($this->sending instanceof Mail) ? ($this->file_pos == $this->size) : feof($this->f);
|
||||
return (($this->sending instanceof Mail) || ($this->sending->isType(self::IS_TIC)))
|
||||
? ($this->file_pos == $this->size)
|
||||
: feof($this->f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add our mail to the send queue
|
||||
*
|
||||
* @param Address $ao
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
* @todo We need to make this into a transaction, incase the transfer fails.
|
||||
*/
|
||||
public function files(Address $ao): bool
|
||||
{
|
||||
$file = FALSE;
|
||||
|
||||
// If the node is marked as hold - dont send any files.
|
||||
if ($ao->system->hold) {
|
||||
Log::info(sprintf('%s: - System [%d] is marked as hold - not checking for files.',self::LOGKEY,$ao->system_id));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Files
|
||||
if (($x=$ao->getFiles())->count()) {
|
||||
Log::debug(sprintf('%s:- [%d] Files(s) added for sending to [%s]',self::LOGKEY,$x->count(),$ao->ftn));
|
||||
|
||||
// Add Files
|
||||
foreach ($x as $xx) {
|
||||
$this->list->push(new Item($xx,self::I_SEND));
|
||||
$this->list->push(new Tic($ao,$xx,self::I_SEND));
|
||||
}
|
||||
|
||||
$file = TRUE;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,14 +251,27 @@ final class Send extends Item
|
||||
$this->file_pos = 0;
|
||||
$this->start = time();
|
||||
|
||||
$this->f = fopen($this->sending->file_name,'rb');
|
||||
if (! $this->f) {
|
||||
Log::error(sprintf('%s:! Unable to open file [%s] for reading',self::LOGKEY,$this->sending->file_name));
|
||||
return FALSE;
|
||||
// If sending->file is a string, then we dont need to actually open anything
|
||||
if ($this->sending->isType(self::IS_TIC)) {
|
||||
$this->f = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Log::info(sprintf('%s:= open - File [%s] opened with size [%d]',self::LOGKEY,$this->sending->file_name,$this->sending->file_size));
|
||||
return TRUE;
|
||||
// If sending file is a File::class, then our file is s3
|
||||
if (! $this->sending->file_name && $this->sending->filemodel) {
|
||||
$this->f = Storage::readStream($this->sending->filemodel->full_storage_path);
|
||||
return TRUE;
|
||||
|
||||
} else {
|
||||
$this->f = fopen($this->sending->file_name,'rb');
|
||||
if (! $this->f) {
|
||||
Log::error(sprintf('%s:! Unable to open file [%s] for reading',self::LOGKEY,$this->sending->file_name));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Log::info(sprintf('%s:= open - File [%s] opened with size [%d]',self::LOGKEY,$this->sending->file_name,$this->sending->file_size));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,7 +288,7 @@ final class Send extends Item
|
||||
|
||||
// If the node is marked as hold - dont send any mail.
|
||||
if ($ao->system->hold) {
|
||||
Log::info(sprintf('%s: - System [%d] mail is marked as hold - not checking for mail.',self::LOGKEY,$ao->system_id));
|
||||
Log::info(sprintf('%s: - System [%d] is marked as hold - not checking for mail.',self::LOGKEY,$ao->system_id));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -276,6 +328,11 @@ final class Send extends Item
|
||||
// We are sending mail
|
||||
if ($this->sending instanceof Mail) {
|
||||
$data = $this->sending->read($this->file_pos,$length);
|
||||
|
||||
// We are sending a tic file
|
||||
} else if ($this->sending->isType(self::IS_TIC)) {
|
||||
$data = $this->sending->read($this->file_pos,$length);
|
||||
|
||||
} else {
|
||||
$data = fread($this->f,$length);
|
||||
}
|
||||
@@ -303,7 +360,7 @@ final class Send extends Item
|
||||
if (! $this->f)
|
||||
throw new Exception('No file open for seek');
|
||||
|
||||
if ($this->sending instanceof Mail) {
|
||||
if (($this->sending instanceof Mail) || $this->sending->isType(self::IS_TIC)) {
|
||||
$pos = ($pos < $this->size) ? $pos : $this->size;
|
||||
$rc = TRUE;
|
||||
|
||||
|
38
app/Classes/File/Tic.php
Normal file
38
app/Classes/File/Tic.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\File;
|
||||
|
||||
use App\Classes\FTN\Tic as FTNTic;
|
||||
use App\Models\{Address,File};
|
||||
|
||||
class Tic extends Item
|
||||
{
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct(Address $ao,File $fo,int $action)
|
||||
{
|
||||
$this->action |= $action;
|
||||
|
||||
$tic = new FTNTic;
|
||||
|
||||
switch ($action) {
|
||||
case self::I_SEND:
|
||||
$this->file = $tic->generate($ao,$fo);
|
||||
$this->file_type = self::IS_TIC;
|
||||
$this->file_name = sprintf('%s.tic',sprintf('%08x',$fo->id));
|
||||
$this->file_size = strlen($this->file);
|
||||
$this->file_mtime = $fo->created_at->timestamp;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception('Unknown action: '.$action);
|
||||
}
|
||||
}
|
||||
|
||||
public function read(int $start,int $length): string
|
||||
{
|
||||
return substr($this->file,$start,$length);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user