list = collect(); $this->f = NULL; } } public function __get($key) { switch ($key) { case 'completed': return $this->list ->filter(function($item) { return $item->complete === TRUE; }); case 'fd': return ! is_null($this->index); case 'files_count': return $this->list ->filter(function($item) { return $item->isType(self::IS_FILE|self::IS_TIC); }) ->count(); case 'files_size': return $this->list ->filter(function($item) { return $item->isType(self::IS_FILE|self::IS_TIC); }) ->sum(function($item) { return $item->size; }); case 'mail_count': return $this->list ->filter(function($item) { return $item->isType(self::IS_ARC|self::IS_PKT); }) ->count(); case 'mail_size': return $this->list ->filter(function($item) { return $item->isType(self::IS_ARC|self::IS_PKT); }) ->sum(function($item) { return $item->size; }); case 'name': case 'nameas': case 'mtime': case 'size': case 'type': return $this->sending->{$key}; case 'pos': return $this->{$key}; case 'sending': return $this->list->get($this->index); case 'togo_count': return $this->list ->filter(function($item) { return $item->complete === FALSE; }) ->count(); case 'total_sent': return $this->completed ->count(); case 'total_sent_bytes': return $this->completed ->sum(function($item) { return $item->size; }); case 'total_size': return $this->list ->sum(function($item) { return $item->size; }); default: throw new Exception('Unknown key: '.$key); } } /** * Close the file descriptor of the file we are sending * * @param bool $successful * @param Node $node * @throws Exception */ public function close(bool $successful,Node $node): void { if (! $this->fd) throw new Exception('No file to close'); if ($successful) { $end = time()-$this->start; Log::info(sprintf('%s:- Closing [%s], sent in [%d] with [%s] items',self::LOGKEY,$this->sending->nameas,$end,$this->sending->dbids->count())); } $this->sending->close($successful,$node); $this->index = NULL; } public function dynamic(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->dynamicWaiting())->count()) { Log::debug(sprintf('%s:- [%d] Dynamic Files(s) added for sending to [%s]',self::LOGKEY,$x->count(),$ao->ftn)); // Add Files foreach ($x as $do) $this->list->push(new Dynamic($do,$ao,self::T_FILE)); $file = TRUE; } return $file; } /* private function compress(string $comp_mode): void { switch ($comp_mode) { case 'BZ2': $this->comp_data = bzcompress($buf); break; case 'GZ': $this->comp_data = gzcompress($buf); break; } } */ /** * Check if we are at the end of the file * * @return bool */ public function feof(): bool { return $this->sending->feof(); } /** * Add our mail to the send queue * * @param Address $ao * @return bool * @throws Exception */ 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->filesWaiting())->count()) { Log::debug(sprintf('%s:- [%d] Files(s) added for sending to [%s]',self::LOGKEY,$x->count(),$ao->ftn)); // Add Files foreach ($x as $fo) { $this->list->push(new File($fo,self::T_FILE)); $this->list->push(new Tic($fo,$ao,self::T_NONE)); } $file = TRUE; } return $file; } /** * Open a file for sending * * @param string $compress * @return bool * @throws Exception */ public function open(string $compress=''): bool { Log::debug(sprintf('%s:+ Opening file to send',self::LOGKEY)); if ((($this->index=$this->list->search(function($item) { return $item->complete === FALSE; })) !== FALSE) && $this->sending->open()) { Log::info(sprintf('%s:- Sending item [%d] (%s)',self::LOGKEY,$this->index,$this->sending->nameas)); $this->pos = 0; $this->start = time(); /* if ($compress) $this->comp_data = $this->compdata($compress); */ return TRUE; } else { throw new Exception('No files to open'); } } /** * Add our mail to the send queue * * @param Address $ao * @param bool $update * @return bool * @throws Exception */ public function mail(Address $ao,bool $update=TRUE): bool { $mail = FALSE; // If the node is marked as hold - dont send any mail. if ($ao->system->hold) { Log::info(sprintf('%s:- System [%d] is marked as hold - not checking for mail.',self::LOGKEY,$ao->system_id)); return FALSE; } // Netmail if ($x=$ao->getNetmail($update)) { Log::debug(sprintf('%s:- Netmail(s) added for sending to [%s]',self::LOGKEY,$ao->ftn)); $this->list->push(new Mail($x,self::T_NETMAIL)); $mail = TRUE; } // Echomail if ($x=$ao->getEchomail($update)) { Log::debug(sprintf('%s:- Echomail(s) added for sending to [%s]',self::LOGKEY,$ao->ftn)); $this->list->push(new Mail($x,self::T_ECHOMAIL)); $mail = TRUE; } return $mail; } /** * Read bytes of the sending file * * @param int $length * @return string|null * @throws UnreadableFileEncountered * @throws Exception */ public function read(int $length): ?string { if (! $this->fd) throw new Exception('No file open for read'); $data = $this->sending->read($length); if ($data === FALSE) throw new UnreadableFileEncountered('Error reading file: '.$this->sending->name); $this->pos += strlen($data); Log::debug(sprintf('%s:- Read [%d] bytes, file pos now [%d]',self::LOGKEY,strlen($data),$this->pos)); return $data; } /** * Seek to a specific position of our file * * @param int $pos * @return bool * @throws Exception */ public function seek(int $pos): bool { if (! $this->fd) throw new Exception('No file open for seek'); if ($this->sending->seek($pos)) { $this->pos = $pos; Log::debug(sprintf('%s:= Seeked to [%d]',self::LOGKEY,$this->pos)); return TRUE; } else { Log::error(sprintf('%s:! Failed to seek to [%d]',self::LOGKEY,$pos)); return FALSE; } } }