Bot::runInternal()   A
last analyzed

Complexity

Conditions 5
Paths 12

Size

Total Lines 27
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 21
nc 12
nop 2
dl 0
loc 27
rs 9.2728
c 0
b 0
f 0
1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme;
4
5
use BotRiconferme\Exception\MissingPageException;
6
use BotRiconferme\Logger\IFlushingAwareLogger;
7
use BotRiconferme\Logger\MultiLogger;
8
use BotRiconferme\Logger\SimpleLogger;
9
use BotRiconferme\Logger\WikiLogger;
10
use BotRiconferme\Request\RequestFactory;
11
use BotRiconferme\TaskHelper\TaskResult;
12
use BotRiconferme\Wiki\LoginInfo;
13
use BotRiconferme\Wiki\Page\Page;
14
use BotRiconferme\Wiki\Page\PageBotList;
15
use BotRiconferme\Wiki\Wiki;
16
use BotRiconferme\Wiki\WikiGroup;
17
use Psr\Log\LoggerInterface;
18
use Psr\Log\LogLevel;
19
use Throwable;
20
21
/**
22
 * Higher-level class. It only wraps tasks executions, and contains generic data
23
 */
24
class Bot {
25
	/** @var IFlushingAwareLogger */
26
	private $mainLogger;
27
	/** @var WikiGroup */
28
	private $wikiGroup;
29
	/** @var MessageProvider */
30
	private $messageProvider;
31
	/** @var CLI */
32
	private $cli;
33
34
	/**
35
	 * @param CLI $cli
36
	 */
37
	public function __construct( CLI $cli ) {
38
		$this->cli = $cli;
39
		$this->initialize();
40
	}
41
42
	/**
43
	 * Initialize all members.
44
	 */
45
	private function initialize(): void {
46
		$simpleLogger = new SimpleLogger();
47
		$this->createWikiGroup( $simpleLogger );
48
		$this->messageProvider = new MessageProvider(
49
			$this->wikiGroup->getMainWiki(),
50
			$this->cli->getSetOpt( 'msg-title' )
51
		);
52
		$this->initConfig();
53
		$this->createMainLogger( $simpleLogger );
54
	}
55
56
	/**
57
	 * Main entry point
58
	 */
59
	public function run(): void {
60
		$taskOpt = $this->cli->getTaskOpt();
61
		$type = current( array_keys( $taskOpt ) );
62
		try {
63
			if ( $type === 'tasks' ) {
64
				$this->runInternal( TaskManager::MODE_TASK, explode( ',', $taskOpt['tasks'] ) );
65
			} elseif ( $type === 'subtasks' ) {
66
				$this->runInternal( TaskManager::MODE_SUBTASK, explode( ',', $taskOpt['subtasks'] ) );
67
			} else {
68
				$this->runInternal();
69
			}
70
		} catch ( Throwable $e ) {
71
			$this->mainLogger->error( $e->__toString() );
72
		} finally {
73
			$this->mainLogger->flush();
74
		}
75
	}
76
77
	/**
78
	 * @param LoggerInterface $baseLogger
79
	 */
80
	private function createWikiGroup( LoggerInterface $baseLogger ): void {
81
		// FIXME Hardcoded
82
		$url = $this->cli->getURL() ?? 'https://it.wikipedia.org/w/api.php';
83
		$localUserIdentifier = '@itwiki';
84
		$centralPagePrefix = 'meta:';
85
		$centralURL = 'https://meta.wikimedia.org/w/api.php';
86
		$privateURL = 'https://sysop-it.wikipedia.org/w/api.php';
87
		$privatePagePrefix = 'private:';
88
89
		$loginInfo = new LoginInfo(
90
			$this->cli->getSetOpt( 'username' ),
91
			$this->cli->getSetOpt( 'password' )
92
		);
93
94
		$rf = new RequestFactory( $baseLogger, $url );
95
		$wiki = new Wiki( $loginInfo, $baseLogger, $rf );
96
97
		$centralRF = new RequestFactory( $baseLogger, $centralURL );
98
		$centralWiki = new Wiki( $loginInfo, $baseLogger, $centralRF );
99
		$centralWiki->setLocalUserIdentifier( $localUserIdentifier );
100
		$centralWiki->setPagePrefix( $centralPagePrefix );
101
102
		$privateLI = new LoginInfo(
103
			$this->cli->getSetOpt( 'username' ),
104
			$this->cli->getSetOpt( 'private-password' )
105
		);
106
		$privateRF = new RequestFactory( $baseLogger, $privateURL );
107
		$privateWiki = new Wiki( $privateLI, $baseLogger, $privateRF );
108
		$privateWiki->setPagePrefix( $privatePagePrefix );
109
110
		$this->wikiGroup = new WikiGroup( $wiki, $centralWiki, $privateWiki );
111
	}
112
113
	/**
114
	 * FIXME SO MUCH DEPENDENCY HELL
115
	 *
116
	 * @param IFlushingAwareLogger $baseLogger
117
	 */
118
	private function createMainLogger( IFlushingAwareLogger $baseLogger ): void {
119
		$mainWiki = $this->wikiGroup->getMainWiki();
120
		$mp = $this->messageProvider;
121
		$errTitle = $this->cli->getOpt( 'error-title' );
122
		if ( $errTitle !== null ) {
123
			// Use a different Wiki with higher min level.
124
			$wikiLoggerLogger = new SimpleLogger( LogLevel::ERROR );
125
			$wikiLoggerWiki = new Wiki(
126
				$mainWiki->getLoginInfo(),
127
				$wikiLoggerLogger,
128
				$mainWiki->getRequestFactory()
129
			);
130
			$errPage = new Page( $errTitle, $wikiLoggerWiki );
131
			$wikiLogger = new WikiLogger(
132
				$errPage,
133
				$mp->getMessage( 'error-page-summary' )->text(),
134
				LogLevel::ERROR
135
			);
136
			$this->mainLogger = new MultiLogger( $baseLogger, $wikiLogger );
137
		} else {
138
			$this->mainLogger = $baseLogger;
139
		}
140
	}
141
142
	/**
143
	 * Create the Config
144
	 */
145
	private function initConfig(): void {
146
		$wiki = $this->wikiGroup->getMainWiki();
147
		try {
148
			$confValues = json_decode( $wiki->getPageContent( $this->cli->getSetOpt( 'config-title' ) ), true );
149
		} catch ( MissingPageException $_ ) {
150
			exit( 'Please create a config page.' );
151
		}
152
153
		Config::init( $confValues );
154
	}
155
156
	/**
157
	 * Internal call to TaskManager
158
	 *
159
	 * @param string $mode
160
	 * @param string[] $taskNames
161
	 */
162
	private function runInternal(
163
		string $mode = TaskManager::MODE_COMPLETE,
164
		array $taskNames = []
165
	): void {
166
		$activity = $mode === TaskManager::MODE_COMPLETE
167
			? 'full process'
168
			: ( $mode === TaskManager::MODE_TASK ? 'tasks' : 'subtasks' ) . ': ' . implode( ', ', $taskNames );
169
		$this->mainLogger->info( "Running $activity" );
170
		$pbl = PageBotList::get(
171
			$this->wikiGroup->getMainWiki(),
172
			$this->cli->getSetOpt( 'list-title' )
173
		);
174
		$manager = new TaskManager(
175
			$this->mainLogger,
176
			$this->wikiGroup,
177
			$this->messageProvider,
178
			$pbl
179
		);
180
		$res = $manager->run( $mode, $taskNames );
181
		$base = "Execution of $activity";
182
		if ( $res->isOK() ) {
183
			$msg = $res->getStatus() === TaskResult::STATUS_NOTHING ?
184
				': nothing to do' :
185
				' completed successfully';
186
			$this->mainLogger->info( $base . $msg );
187
		} else {
188
			$this->mainLogger->error( "$base failed.\n$res" );
189
		}
190
	}
191
}
192