AbstractProcessingListener::prepareCommand()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
namespace Tartana\Event\Listener;
3
4
use Joomla\Registry\Registry;
5
use League\Flysystem\Adapter\Local;
6
use League\Flysystem\Config;
7
use Monolog\Logger;
8
use Tartana\Component\Archive\Extract;
9
use Tartana\Component\Command\Command;
10
use Tartana\Component\Command\Runner;
11
use Tartana\Domain\Command\ChangeDownloadState;
12
use Tartana\Entity\Download;
13
use Tartana\Event\CommandEvent;
14
use Tartana\Mixins\LoggerAwareTrait;
15
use Tartana\Util;
16
use Tartana\Event\DownloadsCompletedEvent;
17
use Tartana\Event\ProcessingCompletedEvent;
18
19
/**
20
 * The processing listener handles the download completed events.
21
 * It extracts or convertes them to the destination with the same folder name as
22
 * the files are within.
23
 */
24
abstract class AbstractProcessingListener
25
{
26
27
	use LoggerAwareTrait;
28
29
	private $runner = null;
30
31
	protected $configuration = null;
32
33 34
	public function __construct(Runner $runner, Registry $configuration)
34
	{
35 34
		$this->runner        = $runner;
36 34
		$this->configuration = $configuration;
37 34
	}
38
39
	/**
40
	 * Returns the configuration key which acts as destination.
41
	 *
42
	 * @return string
43
	 */
44
	abstract protected function getConfigurationKey();
45
46
	/**
47
	 * Returns an array of file extensions to process and the corresponding
48
	 * tartana command to execute.
49
	 *
50
	 * @return string[]
51
	 */
52
	abstract protected function getFileExtensionsForCommand();
53
54
	/**
55
	 *
56
	 * @param Command $command
57
	 * @return Command
58
	 */
59 6
	protected function prepareCommand(Command $command)
60
	{
61 6
		return $command;
62
	}
63
64 12
	public function onProcessCompletedDownloads(DownloadsCompletedEvent $event)
65
	{
66 12
		$destination = Util::realPath($this->configuration->get($this->getConfigurationKey()));
67 12
		if (!empty($destination)) {
68 11
			$destination = new Local($destination);
69
		}
70 12
		if (!$event->getDownloads() || !$destination) {
71 1
			return;
72
		}
73
74 11
		$path = $event->getDownloads()[0]->getDestination();
75
76 11
		$this->log('Handling the download completed event of the folder ' . $path, Logger::INFO);
77
78 11
		$dirName = basename($path);
79 11
		$this->log('Checking directory: ' . $destination->getPathPrefix() . ' if it has a folder ' . $dirName);
80
81 11
		$hasSource      = file_exists($path);
82 11
		$hasDestination = $destination->has($dirName);
83 11
		$processed      = false;
84 11
		if (!$hasDestination && $hasSource) {
85 9
			$this->log('No directory found, starting to process files on: ' . $destination->applyPathPrefix($dirName));
86
87
			// Out file doesn't exist, we can start processing it
88 9
			$destination->createDir($dirName, new Config());
89
90 9
			$fs    = new Local(dirname($path));
91 9
			$files = $fs->listContents('', true);
92
93 9
			foreach ($this->getFileExtensionsForCommand() as $fileExtension => $command) {
94 9
				foreach ($files as $file) {
95 9
					if (!Util::endsWith($file['path'], '.' . $fileExtension) && strpos($file['path'], '.' . $fileExtension . '.') === false) {
96 9
						continue;
97
					}
98
99 9
					$this->runCommand($command, $path, $destination->applyPathPrefix($dirName));
100
101 9
					$processed = true;
102 9
					break;
103
				}
104
			}
105
		}
106 11
		foreach ($event->getDownloads() as $download) {
107 11
			if ($hasDestination) {
108 1
				$download->setMessage('TARTANA_EXTRACT_MESSAGE_DESTINATION_EXISTS');
109 1
				$download->setState(Download::STATE_PROCESSING_ERROR);
110 10
			} elseif (!$hasSource) {
111 1
				$download->setMessage('TARTANA_EXTRACT_MESSAGE_SOURCE_NOT_EXIST');
112 1
				$download->setState(Download::STATE_PROCESSING_ERROR);
113 9
			} elseif ($processed) {
114 11
				$download->setState(Download::STATE_PROCESSING_STARTED);
115
			}
116
		}
117 11
		$this->log('Finished handling the download completed event of the folder ' . $path, Logger::INFO);
118 11
	}
119
120
	/**
121
	 * Handles the extract completed event.
122
	 *
123
	 * @param ProcessingCompletedEvent $event
124
	 */
125 3
	public function onProcessingCompleted(ProcessingCompletedEvent $event)
126
	{
127 3
		$destination = $event->getDestination();
128 3
		$this->log('Checking completed processed files at folder: ' . $destination->getPathPrefix(), Logger::INFO);
129
130 3
		if ($event->isSuccess()) {
131 2
			$this->log('Processing was successfully in folder ' . $destination->getPathPrefix(), Logger::INFO);
132
133 2
			$this->log('Searching for more files to process in folder: ' . $destination->getPathPrefix());
134
135
			// Reprocessing processed files
136 2
			$folders = [];
137 2
			foreach ($destination->listContents('', true) as $file) {
138 2
				$dir = dirname($file['path']);
139
140 2
				if (key_exists($dir, $folders)) {
141 1
					continue;
142
				}
143 2
				$folders[$dir] = $dir;
144
145 2
				foreach ($this->getFileExtensionsForCommand() as $fileExtension => $command) {
146 2
					if (!Util::endsWith($file['path'], '.' . $fileExtension)) {
147 1
						continue;
148
					}
149
150 1
					$this->log('Reprocessing folder: ' . $destination->applyPathPrefix($dir));
151
152 2
					$this->runCommand($command, $destination->applyPathPrefix($dir), $destination->applyPathPrefix($dir));
153
				}
154
			}
155
		} else {
156 1
			$this->log('Error processing files in folder ' . $destination->getPathPrefix(), Logger::ERROR);
157
		}
158 3
	}
159
160 19
	public function onChangeDownloadStateAfter(CommandEvent $event)
161
	{
162 19
		if (!$event->getCommand() instanceof ChangeDownloadState) {
163 14
			return;
164
		}
165
166 9
		if ($event->getCommand()->getToState() != Download::STATE_DOWNLOADING_COMPLETED &&
167 9
			$event->getCommand()->getToState() != Download::STATE_DOWNLOADING_NOT_STARTED) {
168 1
			return;
169
		}
170
171 8
		$destination = Util::realPath($this->configuration->get($this->getConfigurationKey()));
172 8
		if (!empty($destination)) {
173 7
			$destination = new Local($destination);
174
		} else {
175 1
			return;
176
		}
177
178 7
		$this->log('Cleaning up the destination ' . $destination->getPathPrefix() . ' for downloads', Logger::INFO);
179
180 7
		foreach ($event->getCommand()->getDownloads() as $download) {
181
			// If we do not process,tart ignore
182 7
			if ($download->getState() != $event->getCommand()->getToState()) {
183 1
				continue;
184
			}
185 6
			$dirName = basename($download->getDestination());
186
187
			// If destination doesn't have the dir, ignore
188 6
			if (!$destination->has($dirName)) {
189 5
				continue;
190
			}
191 2
			$this->log('Deleting the directory ' . $destination->applyPathPrefix($dirName));
192 2
			$destination->deleteDir($dirName);
193
		}
194 7
	}
195
196 10
	protected function runCommand($cmd, $path, $destination)
197
	{
198 10
		$this->log('Starting with ' . $cmd . ' processing of the folder: ' . $path, Logger::INFO);
199
200 10
		$command = Command::getAppCommand($cmd);
201 10
		$command->setCaptureErrorInOutput(true);
202 10
		$command->setAsync($this->configuration->get('async', true));
203 10
		$command->addArgument($path);
204 10
		$command->addArgument($destination);
205
206 10
		$command = $this->prepareCommand($command);
207
208 10
		$this->log('Running command to process the files: ' . $command);
209 10
		$this->runner->execute($command);
210 10
	}
211
}
212