Passed
Push — master ( 9623d2...497244 )
by Daimona
01:54
created

Bot   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 154
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 83
dl 0
loc 154
rs 10
c 0
b 0
f 0
wmc 15

7 Methods

Rating   Name   Duplication   Size   Complexity  
A runInternal() 0 21 4
A run() 0 15 4
A initialize() 0 12 1
A initConfig() 0 9 2
A createMainLogger() 0 23 2
A __construct() 0 3 1
A createWikiGroup() 0 17 1
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
20
/**
21
 * Higher-level class. It only wraps tasks executions, and contains generic data
22
 */
23
class Bot {
24
	/** @var LoggerInterface */
25
	private $mainLogger;
26
	/** @var WikiGroup */
27
	private $wikiGroup;
28
	/** @var MessageProvider */
29
	private $messageProvider;
30
	/** @var PageBotList */
31
	private $pageBotList;
32
	/** @var CLI */
33
	private $cli;
34
35
	/**
36
	 * @param CLI $cli
37
	 */
38
	public function __construct( CLI $cli ) {
39
		$this->cli = $cli;
40
		$this->initialize();
41
	}
42
43
	/**
44
	 * Initialize all members.
45
	 */
46
	private function initialize() : void {
47
		$simpleLogger = new SimpleLogger();
48
		$this->wikiGroup = $this->createWikiGroup( $simpleLogger );
49
		$this->messageProvider = new MessageProvider(
50
			$this->wikiGroup->getMainWiki(),
51
			$this->cli->getOpt( 'msg-title' )
1 ignored issue
show
Bug introduced by
It seems like $this->cli->getOpt('msg-title') can also be of type null; however, parameter $msgTitle of BotRiconferme\MessageProvider::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

51
			/** @scrutinizer ignore-type */ $this->cli->getOpt( 'msg-title' )
Loading history...
52
		);
53
		$this->initConfig();
54
		$this->mainLogger = $this->createMainLogger( $simpleLogger );
55
		$this->pageBotList = PageBotList::get(
56
			$this->wikiGroup->getMainWiki(),
57
			$this->cli->getOpt( 'list-title' )
58
		);
59
	}
60
61
	/**
62
	 * Main entry point
63
	 */
64
	public function run() : void {
65
		$taskOpt = $this->cli->getTaskOpt();
66
		$type = current( array_keys( $taskOpt ) );
67
		try {
68
			if ( $type === 'task' ) {
69
				$this->runInternal( TaskManager::MODE_TASK, $taskOpt['task'] );
70
			} elseif ( $type === 'subtask' ) {
71
				$this->runInternal( TaskManager::MODE_SUBTASK, $taskOpt['subtask'] );
72
			} else {
73
				$this->runInternal();
74
			}
75
		} catch ( \Throwable $e ) {
76
			$this->mainLogger->error( $e->__toString() );
77
		} finally {
78
			$this->mainLogger->flush();
0 ignored issues
show
Bug introduced by
The method flush() does not exist on Psr\Log\LoggerInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Phan\Library\StderrLogger or Psr\Log\AbstractLogger or Symfony\Component\Console\Logger\ConsoleLogger or Psr\Log\NullLogger. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

78
			$this->mainLogger->/** @scrutinizer ignore-call */ 
79
                      flush();
Loading history...
79
		}
80
	}
81
82
	/**
83
	 * @param LoggerInterface $baseLogger
84
	 * @return WikiGroup
85
	 */
86
	private function createWikiGroup( LoggerInterface $baseLogger ) : WikiGroup {
87
		// FIXME Hardcoded
88
		$url = $this->cli->getURL() ?? 'https://it.wikipedia.org/w/api.php';
89
		$localUserIdentifier = '@itwiki';
90
		$centralURL = 'https://meta.wikimedia.org/w/api.php';
91
92
		$loginInfo = new LoginInfo(
93
			$this->cli->getOpt( 'username' ),
1 ignored issue
show
Bug introduced by
It seems like $this->cli->getOpt('username') can also be of type null; however, parameter $username of BotRiconferme\Wiki\LoginInfo::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
			/** @scrutinizer ignore-type */ $this->cli->getOpt( 'username' ),
Loading history...
94
			$this->cli->getOpt( 'password' )
1 ignored issue
show
Bug introduced by
It seems like $this->cli->getOpt('password') can also be of type null; however, parameter $password of BotRiconferme\Wiki\LoginInfo::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
			/** @scrutinizer ignore-type */ $this->cli->getOpt( 'password' )
Loading history...
95
		);
96
97
		$rf = new RequestFactory( $url );
98
		$wiki = new Wiki( $loginInfo, $baseLogger, $rf );
99
		$centralRF = new RequestFactory( $centralURL );
100
		$centralWiki = new Wiki( $loginInfo, $baseLogger, $centralRF );
101
		$centralWiki->setLocalUserIdentifier( $localUserIdentifier );
102
		return new WikiGroup( $wiki, $centralWiki );
103
	}
104
105
	/**
106
	 * FIXME SO MUCH DEPENDENCY HELL
107
	 *
108
	 * @param IFlushingAwareLogger $baseLogger
109
	 * @return IFlushingAwareLogger
110
	 */
111
	private function createMainLogger( IFlushingAwareLogger $baseLogger ) : IFlushingAwareLogger {
112
		$mainWiki = $this->wikiGroup->getMainWiki();
113
		$mp = $this->messageProvider;
114
		$errTitle = $this->cli->getOpt( 'error-title' );
115
		if ( $errTitle !== null ) {
116
			// Use a different Wiki with higher min level.
117
			$wikiLoggerLogger = new SimpleLogger( LogLevel::ERROR );
118
			$wikiLoggerWiki = new Wiki(
119
				$mainWiki->getLoginInfo(),
120
				$wikiLoggerLogger,
121
				$mainWiki->getRequestFactory()
122
			);
123
			$errPage = new Page( $errTitle, $wikiLoggerWiki );
124
			$wikiLogger = new WikiLogger(
125
				$errPage,
126
				$mp->getMessage( 'error-page-summary' )->text(),
127
				LogLevel::ERROR
128
			);
129
			$mainLogger = new MultiLogger( $baseLogger, $wikiLogger );
130
		} else {
131
			$mainLogger = $baseLogger;
132
		}
133
		return $mainLogger;
134
	}
135
136
	/**
137
	 * Create the Config
138
	 */
139
	private function initConfig() : void {
140
		$wiki = $this->wikiGroup->getMainWiki();
141
		try {
142
			$confValues = json_decode( $wiki->getPageContent( $this->cli->getOpt( 'config-title' ) ), true );
1 ignored issue
show
Bug introduced by
It seems like $this->cli->getOpt('config-title') can also be of type null; however, parameter $title of BotRiconferme\Wiki\Wiki::getPageContent() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

142
			$confValues = json_decode( $wiki->getPageContent( /** @scrutinizer ignore-type */ $this->cli->getOpt( 'config-title' ) ), true );
Loading history...
143
		} catch ( MissingPageException $_ ) {
144
			exit( 'Please create a config page.' );
145
		}
146
147
		Config::init( $confValues );
148
	}
149
150
	/**
151
	 * Internal call to TaskManager
152
	 *
153
	 * @param string $mode
154
	 * @param string|null $name
155
	 */
156
	private function runInternal(
157
		string $mode = TaskManager::MODE_COMPLETE,
158
		string $name = null
159
	) : void {
160
		$activity = $mode === TaskManager::MODE_COMPLETE ? TaskManager::MODE_COMPLETE : "$mode $name";
161
		$this->mainLogger->info( "Running $activity" );
162
		$manager = new TaskManager(
163
			$this->mainLogger,
164
			$this->wikiGroup,
165
			$this->messageProvider,
166
			$this->pageBotList
167
		);
168
		$res = $manager->run( $mode, $name );
169
		$base = "Execution of $activity";
170
		if ( $res->isOK() ) {
171
			$msg = $res->getStatus() === TaskResult::STATUS_NOTHING ?
172
				': nothing to do' :
173
				' completed successfully';
174
			$this->mainLogger->info( $base . $msg );
175
		} else {
176
			$this->mainLogger->error( "$base failed.\n$res" );
177
		}
178
	}
179
}
180