Completed
Push — master ( bb7259...dc298a )
by Sam
03:00
created

TvheadendStatusManagerCommand   B

Complexity

Total Complexity 5

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Test Coverage

Coverage 0%

Importance

Changes 25
Bugs 2 Features 6
Metric Value
wmc 5
c 25
b 2
f 6
lcom 1
cbo 16
dl 0
loc 135
ccs 0
cts 78
cp 0
rs 8.4614

4 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 8 1
A execute() 0 50 1
A configureLogger() 0 17 2
B configurePropel() 0 26 1
1
<?php
2
3
namespace Jalle19\StatusManager\Console\Commands;
4
5
use Auryn\Injector;
6
use Bramus\Monolog\Formatter\ColoredLineFormatter;
7
use Jalle19\StatusManager\Configuration\Configuration;
8
use Jalle19\StatusManager\Configuration\Parser as ConfigurationParser;
9
use Jalle19\StatusManager\Configuration\Reader\YamlReader;
10
use Jalle19\StatusManager\Event\Events;
11
use Monolog\Handler\StreamHandler;
12
use Monolog\Logger;
13
use Monolog\Processor\PsrLogMessageProcessor;
14
use Propel\Runtime\Connection\ConnectionManagerSingle;
15
use Propel\Runtime\Propel;
16
use Propel\Runtime\ServiceContainer\StandardServiceContainer;
17
use Psr\Log\LoggerInterface;
18
use React\EventLoop\Factory as EventLoopFactory;
19
use Symfony\Bridge\Monolog\Handler\ConsoleHandler;
20
use Symfony\Component\Console\Command\Command;
21
use Symfony\Component\Console\Input\InputArgument;
22
use Symfony\Component\Console\Input\InputInterface;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Symfony\Component\EventDispatcher\EventDispatcher;
25
26
/**
27
 * Class TvheadendStatusManagerCommand
28
 * @package   Jalle19\StatusManager\Console\Command
29
 * @copyright Copyright &copy; Sam Stenvall 2015-
30
 * @license   https://www.gnu.org/licenses/gpl.html The GNU General Public License v2.0
31
 */
32
class TvheadendStatusManagerCommand extends Command
33
{
34
35
	const COMMAND_NAME = 'tvheadend-status-manager';
36
37
38
	/**
39
	 * @inheritdoc
40
	 */
41
	protected function configure()
42
	{
43
		$this->setName(self::COMMAND_NAME);
44
		$this->setDescription('Aggregating status manager for tvheadend instances');
45
46
		// Add arguments
47
		$this->addArgument('configFile', InputArgument::REQUIRED, 'The path to the configuration file');
48
	}
49
50
51
	/**
52
	 * @inheritdoc
53
	 */
54
	protected function execute(InputInterface $input, OutputInterface $output)
55
	{
56
		// Parse the configuration
57
		$configFile    = $input->getArgument('configFile');
58
		$configuration = ConfigurationParser::parseConfiguration(new YamlReader($configFile));
59
60
		// Configure Propel and the logger
61
		$logger = $this->configureLogger($output, $configuration);
62
		$this->configurePropel($configuration, $logger);
63
64
		$injector = new Injector();
65
66
		// Configure shared instances
67
		$eventLoop       = EventLoopFactory::create();
68
		$eventDispatcher = new EventDispatcher();
69
		$aliases         = [':logger' => $logger, ':loop' => $eventLoop];
70
71
		$injector->share($configuration)
72
		         ->share($logger)
73
		         ->share($eventDispatcher)
74
		         ->share($eventLoop);
75
76
		// Create managers
77
		$statusManager        = $injector->make('Jalle19\StatusManager\Manager\StatusManager', $aliases);
78
		$instanceStateManager = $injector->make('Jalle19\StatusManager\Manager\InstanceStateManager', $aliases);
79
		$webSocketManager     = $injector->make('Jalle19\StatusManager\Manager\WebSocketManager', $aliases);
80
		$persistenceManager   = $injector->make('Jalle19\StatusManager\Manager\PersistenceManager', $aliases);
81
		$statisticsManager    = $injector->make('Jalle19\StatusManager\Manager\StatisticsManager', $aliases);
82
		$inputErrorManager    = $injector->make('Jalle19\StatusManager\Manager\InputErrorManager', $aliases);
83
84
		// Wire the event dispatcher
85
		$webSocketManager->registerMessageHandler($statisticsManager);
86
		$webSocketManager->registerMessageHandler($webSocketManager);
87
		
88
		$eventDispatcher->addSubscriber($statusManager);
89
		$eventDispatcher->addSubscriber($instanceStateManager);
90
		$eventDispatcher->addSubscriber($webSocketManager);
91
		$eventDispatcher->addSubscriber($persistenceManager);
92
		$eventDispatcher->addSubscriber($inputErrorManager);
93
94
		// Configure the event loop and start the application
95
		$eventLoop->addPeriodicTimer($configuration->getUpdateInterval(), function () use ($eventDispatcher)
96
		{
97
			// Emit an event on each tick
98
			$eventDispatcher->dispatch(Events::MAIN_LOOP_TICK);
99
		});
100
101
		$eventDispatcher->dispatch(Events::MAIN_LOOP_STARTING);
102
		$eventLoop->run();
103
	}
104
105
106
	/**
107
	 * Configures and returns the logger instance
108
	 *
109
	 * @param OutputInterface $output
110
	 * @param Configuration   $configuration
111
	 *
112
	 * @return Logger
113
	 */
114
	private function configureLogger(OutputInterface $output, Configuration $configuration)
115
	{
116
		$consoleHandler = new ConsoleHandler($output);
117
		$consoleHandler->setFormatter(new ColoredLineFormatter(null, "[%datetime%] %level_name%: %message%\n"));
118
119
		$logger = new Logger(self::COMMAND_NAME);
120
		$logger->pushHandler($consoleHandler);
121
		$logger->pushProcessor(new PsrLogMessageProcessor());
122
123
		if ($configuration->getLogPath() !== null)
124
		{
125
			$fileHandler = new StreamHandler($configuration->getLogPath());
126
			$logger->pushHandler($fileHandler);
127
		}
128
129
		return $logger;
130
	}
131
132
133
	/**
134
	 * Configures the database
135
	 *
136
	 * @param Configuration   $configuration
137
	 * @param LoggerInterface $logger
138
	 */
139
	private function configurePropel(Configuration $configuration, LoggerInterface $logger)
140
	{
141
		/* @var StandardServiceContainer $serviceContainer */
142
		$serviceContainer = Propel::getServiceContainer();
143
		$serviceContainer->checkVersion('2.0.0-dev');
144
		$serviceContainer->setAdapterClass('tvheadend_status_manager', 'sqlite');
145
		$manager = new ConnectionManagerSingle();
146
		$manager->setConfiguration([
147
			'classname'  => 'Propel\\Runtime\\Connection\\ConnectionWrapper',
148
			'dsn'        => 'sqlite:' . $configuration->getDatabasePath(),
149
			'user'       => null,
150
			'password'   => '',
151
			'attributes' => [
152
				'ATTR_EMULATE_PREPARES' => false,
153
			],
154
			'settings'   => [
155
				'charset' => 'utf8',
156
				'queries' => [],
157
			],
158
		]);
159
		$manager->setName('tvheadend_status_manager');
160
		$serviceContainer->setConnectionManager('tvheadend_status_manager', $manager);
161
		$serviceContainer->setDefaultDatasource('tvheadend_status_manager');
162
163
		$serviceContainer->setLogger(self::COMMAND_NAME, $logger);
164
	}
165
166
}
167