-
Notifications
You must be signed in to change notification settings - Fork 5
/
blockrollback.php
225 lines (199 loc) · 6.8 KB
/
blockrollback.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
<pre><?php
require_once './bin/globals.php';
require_once 'WikiAphpi/main.php';
/**
* Classe responsável pela notificação de incidentes relacionados aos reversores da Wikipédia
* em português que porventura realizaram bloqueios fora dos parâmetros autorizados pela
* política local.
*/
class BadRollback extends WikiAphpiLogged
{
/**
* Levanta lista de reversores
* @return array Lista de IDs de usuários reversores
*/
private function getRollbackers()
{
$params = [
'action' => 'query',
'format' => 'php',
'list' => 'allusers',
'augroup' => 'rollbacker',
'aulimit' => 'max'
];
$rollbackers_API = $this->see($params)['query']['allusers'];
$rollbackers_IDs = array();
foreach ($rollbackers_API as $user) {
$rollbackers_IDs[] = $user['userid'];
}
return $rollbackers_IDs;
}
/**
* Levanta lista de bloqueios ocorridos nos últimos minutos
* @return array Lista de eventos e seus detalhes
*/
public function getRecentBlocks()
{
$params = [
'action' => 'query',
'format' => 'php',
'list' => 'logevents',
'leprop' => 'userid|details|ids|title|user|type|timestamp',
'letype' => 'block',
'lelimit' => 'max',
'ledir' => 'older',
'leend' => gmdate('Y-m-d\TH:i:s\Z', strtotime('-180 minutes'))
];
$result = $this->see($params)['query']['logevents'];
return $result;
}
/**
* Verifica se usuário é autoconfirmado
* @param string $username Nome do usuário
* @return bool Verdadeiro se for autoconfirmado, falso caso contrário ou caso seja IP
*/
private function isUserAutoConfirmed($username)
{
$params = [
'action' => 'query',
'format' => 'php',
'list' => 'users',
'usprop' => 'rights',
'ususers' => $username
];
$result = $this->see($params)['query']['users'][0]['rights'] ?? [false];
return in_array('editsemiprotected', $result);
}
/**
* Recupera nome do usuário de acordo com o nome de sua página de usuário
* @param string $pagename Página do usuário
* @return string Nome do usuário
*/
private function getNameFromUserPage($pagename)
{
$name = explode(':', $pagename, 2);
return $name["1"];
}
/**
* Verifica parâmetros do log de bloqueio
* @param array $log Parâmetros de log
* @return mixed String com erro detectado ou falso caso contrário
*/
private function verifyLog($log)
{
//Verifica se alvo é autoconfirmado
$target = $this->getNameFromUserPage($log['title']);
if ($this->isUserAutoConfirmed($target)) {
return "autoconfirmado";
}
//Ignora desbloqueios de não-autoconfirmados
if ($log["action"] == "unblock") {
return false;
}
//Verifica se bloqueio foi infinito
if (!isset($log['params']['expiry'])) {
return "infinito";
}
//Verifica se bloqueio é superior a 24 horas
$lenght = strtotime($log['params']['expiry']) - strtotime($log['timestamp']);
if ($lenght > 86401) {
return ($lenght/3600) . ' horas';
}
//Fallback
return false;
}
/**
* Recupera lista de incidentes já notificados
* @return array IDs de log
*/
private function getNotified()
{
$list = $this->get('User:BloqBot/rev');
$list = explode("\n", $list);
return $list;
}
/**
* Compila array com incidentes a serem notificados
* @param array $logs Lista de arrays dos parâmetros de cada bloqueio
* @param array $rollbackersIDs Lista de IDs dos usuários reversores
* @param array $notified Lista de IDs dos incidentes já lançados
* @return array Incidentes a serem lançados
*/
private function compileNotifications($logs, $rollbackersIDs, $notified)
{
$notify = [];
//Processa cada registro de bloqueio
foreach ($logs as $log) {
// Exibe mensagem de processamento do log
echo "Processando log {$log["logid"]}\n";
//Verifica se incidente já foi lançado
if (in_array($log['logid'], $notified)) {
continue;
}
//Verifica se autor não é reversor
if (!in_array($log['userid'], $rollbackersIDs)) {
continue;
}
//Verifica parâmetros do registro
$verify = $this->verifyLog($log);
//Insere registro na array
if ($verify !== false) {
$logid = $log['logid'];
$target = $this->getNameFromUserPage($log['title']);
$incident = "\n{{subst:Incidente/Bloqbot|{$log['user']}|$verify|$target|$logid}}\n";
$notify[$logid] = $incident;
}
}
return $notify;
}
/**
* Salva os incidentes na página de notificação de incidentes.
* @param array $notifications Array contendo as notificações dos incidentes.
*/
private function saveIncidents($notifications)
{
$notifications = implode('', $notifications);
$this->edit(
$notifications,
'append',
false,
"bot: Inserindo notificação de incidente envolvendo reversor",
"Wikipédia:Pedidos/Notificação de incidentes"
);
}
/**
* Salva os números dos logs dos incidentes.
* @param array $notifications Array contendo as notificações dos incidentes.
*/
private function saveIncidentLogs($notifications)
{
$logs = implode("\n", array_keys($notifications));
$this->edit(
"\n$logs",
'append',
true,
"bot: Lançando ID de incidente",
"Usuário(a):BloqBot/rev"
);
}
/**
* Executa o processo de compilação de notificações e salva no log e na página de incidentes.
* Este método é responsável por compilar notificações de incidentes envolvendo reversores na Wikipédia e salvar
* esses incidentes em duas páginas: a página de incidentes e a página de log para evitar duplicidade.
* Para isso, a função chama as funções auxiliares `compileNotifications()`, `saveIncidentLogs()` e `saveIncidents()`.
* @return void
*/
public function run()
{
$notifications = $this->compileNotifications(
$this->getRecentBlocks(),
$this->getRollbackers(),
$this->getNotified()
);
$this->saveIncidentLogs($notifications);
$this->saveIncidents($notifications);
}
}
//Executa script
$badRollback = new BadRollback('https://pt.wikipedia.org/w/api.php', $usernameBQ, $passwordBQ);
$badRollback->run();