Completed
Push — master ( 94e04a...7e753b )
by C
05:18
created

onProcessingCompleted()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 41
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 6

Importance

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