Total Complexity | 34 |
Total Lines | 263 |
Duplicated Lines | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
1 | <?php |
||
23 | class VoteAdmin |
||
24 | { |
||
25 | const SUMMARY = '/* Approbation :*/ 🗳️ 🕊'; |
||
26 | const FILENAME_PHRASES_POUR = __DIR__.'/resources/phrases_voteAdmin_pour.txt'; |
||
27 | const FILENAME_BLACKLIST = __DIR__.'/resources/blacklist.txt'; |
||
28 | const MIN_VALUE_POUR = 0.65; |
||
29 | const MIN_COUNT_POUR = 7; |
||
30 | const MIN_ADMIN_SCORE = 500; |
||
31 | const BOURRAGE_DETECT_REGEX = '#\[\[(?:User|Utilisateur|Utilisatrice):(Irønie|CodexBot|ZiziBot)#i'; |
||
32 | |||
33 | /** |
||
34 | * @var string |
||
35 | */ |
||
36 | private $voteText; |
||
37 | /** |
||
38 | * @var string |
||
39 | */ |
||
40 | private $votePage; |
||
41 | /** |
||
42 | * @var WikiPageAction |
||
43 | */ |
||
44 | private $pageAction; |
||
45 | private $pageText; |
||
46 | /** |
||
47 | * @var string |
||
48 | */ |
||
49 | private $comment = ''; |
||
50 | |||
51 | public function __construct(string $AdminVotePage) |
||
52 | { |
||
53 | $this->votePage = $AdminVotePage; |
||
54 | $this->process(); |
||
55 | } |
||
56 | |||
57 | private function process() |
||
58 | { |
||
59 | if (!$this->checkBlacklist()) { |
||
60 | return false; |
||
61 | } |
||
62 | |||
63 | if (!$this->checkPourContre()) { |
||
64 | echo "check pour/contre => false"; |
||
65 | |||
66 | return false; |
||
67 | } |
||
68 | |||
69 | $adminScore = $this->getAdminScore(); |
||
70 | if ($adminScore && $adminScore < self::MIN_ADMIN_SCORE) { |
||
1 ignored issue
–
show
|
|||
71 | echo "Admin score => false"; |
||
72 | |||
73 | return false; |
||
74 | } |
||
75 | |||
76 | $this->comment .= ' – adminScore: '.$adminScore; |
||
77 | |||
78 | $this->voteText = sprintf("%s ~~~~\n", $this->selectVoteText()); |
||
79 | |||
80 | dump($this->comment); |
||
81 | dump($this->voteText); |
||
82 | sleep(5); |
||
83 | |||
84 | $insertResult = $this->generateVoteInsertionText(); |
||
85 | if (empty($insertResult)) { |
||
86 | echo "insertResult vide\n"; |
||
87 | |||
88 | return false; |
||
89 | } |
||
90 | |||
91 | dump($insertResult); |
||
92 | |||
93 | sleep(20); |
||
94 | |||
95 | return $this->editVote($insertResult); |
||
96 | } |
||
97 | |||
98 | private function selectVoteText(): string |
||
99 | { |
||
100 | $sentences = file(self::FILENAME_PHRASES_POUR, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); |
||
101 | if (!$sentences) { |
||
102 | throw new ConfigException('Pas de phrases disponibles'); |
||
103 | } |
||
104 | |||
105 | return (string)trim($sentences[array_rand($sentences)]); |
||
106 | } |
||
107 | |||
108 | private function generateVoteInsertionText(): ?string |
||
109 | { |
||
110 | $wikiText = $this->getText(); |
||
111 | |||
112 | if (empty($wikiText)) { |
||
113 | echo "Page vide\n"; |
||
114 | |||
115 | return null; |
||
116 | } |
||
117 | |||
118 | if (!$this->isAllowedToVote($wikiText)) { |
||
119 | echo "Not allowed to vote\n"; |
||
120 | |||
121 | return null; |
||
122 | } |
||
123 | |||
124 | // insertion texte {{pour}} |
||
125 | if (!preg_match('/(# \{\{Pour\}\}[^#\n]+\n)\n*==== Opposition ====/im', $wikiText, $matches)) { |
||
126 | return null; |
||
127 | } |
||
128 | |||
129 | if (empty($matches[1])) { |
||
130 | return null; |
||
131 | } |
||
132 | |||
133 | // note : \n déjà inclus |
||
134 | return str_replace($matches[1], $matches[1].$this->voteText, $wikiText); |
||
135 | } |
||
136 | |||
137 | private function getText(): ?string |
||
138 | { |
||
139 | if ($this->pageText) { |
||
140 | // cache |
||
141 | return $this->pageText; |
||
142 | } |
||
143 | |||
144 | $this->pageAction = ServiceFactory::wikiPageAction($this->votePage); |
||
145 | $this->pageText = $this->pageAction->getText(); |
||
146 | |||
147 | return $this->pageText; |
||
148 | } |
||
149 | |||
150 | private function editVote(string $insertVote): bool |
||
151 | { |
||
152 | if (!empty($insertVote)) { |
||
153 | $summary = sprintf( |
||
154 | '%s (%s)', |
||
155 | self::SUMMARY, |
||
156 | $this->comment |
||
157 | ); |
||
158 | |||
159 | return $this->pageAction->editPage($insertVote, new EditInfo($summary, false, false), true); |
||
160 | } |
||
1 ignored issue
–
show
|
|||
161 | } |
||
162 | |||
163 | private function isAllowedToVote(string $wikitext): bool |
||
164 | { |
||
165 | // bourrage d'urne |
||
166 | if (preg_match(self::BOURRAGE_DETECT_REGEX, $wikitext)) { |
||
167 | echo "Bourrage d'urne ! ;) \n"; |
||
168 | |||
169 | return false; |
||
170 | } |
||
171 | if (!preg_match('#\{\{Élection administrateur en cours#i', $wikitext)) { |
||
172 | return false; |
||
173 | } |
||
174 | |||
175 | return true; |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Return true if 15 {{pour}} and 60% {{pour}} |
||
180 | * |
||
181 | * @return bool |
||
182 | */ |
||
183 | private function checkPourContre(): bool |
||
201 | } |
||
202 | |||
203 | private function getBlacklist(): array |
||
204 | { |
||
205 | $list = file(self::FILENAME_BLACKLIST, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); |
||
206 | |||
207 | return $list ?? []; |
||
1 ignored issue
–
show
|
|||
208 | } |
||
209 | |||
210 | /** |
||
211 | * TODO move |
||
212 | * TODO gérer espace "_" |
||
213 | * |
||
214 | * @return bool |
||
215 | * @throws Exception |
||
216 | */ |
||
217 | private function checkBlacklist(): bool |
||
231 | } |
||
232 | |||
233 | private function getUsername() |
||
234 | { |
||
235 | if (!preg_match('#^Wikipédia:(?:Administrateur|Administratrice)/(.+)$#', $this->votePage, $matches)) { |
||
236 | throw new Exception('username not found'); |
||
237 | } |
||
238 | |||
239 | return str_replace('_', ' ', $matches[1]); |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Extract the Xtools "admin score" calculation. |
||
244 | * See https://xtools.wmflabs.org/adminscore |
||
245 | * also : |
||
246 | * https://xtools.wmflabs.org/adminscore/fr.wikipedia.org/Ariel%20Provost |
||
247 | * https://tools.wmflabs.org/supercount/index.php?user=Jennenke&project=fr.wikipedia.org |
||
248 | * https://xtools.wmflabs.org/adminscore/fr.wikipedia.org/Jennenke |
||
249 | * https://github.com/x-tools/xtools/blob/master/src/AppBundle/Controller/AdminScoreController.php |
||
250 | * https://github.com/x-tools/xtools/blob/b39e4b114418784c6adce4a4e892b4711000a847/src/AppBundle/Model/AdminScore.php#L16 |
||
251 | * https://en.wikipedia.org/wiki/Wikipedia:WikiProject_Admin_Nominators/Nomination_checklist |
||
252 | * Copy en JS : https://github.com/enterprisey/AAdminScore/blob/master/js/aadminscore.js |
||
253 | * Class AdminScore |
||
254 | */ |
||
255 | public function getAdminScore(): ?int |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * @return string|null |
||
268 | * @throws Exception |
||
269 | */ |
||
270 | private function getAdminScoreHtml(): ?string |
||
271 | { |
||
272 | $client = new Client( |
||
286 | } |
||
287 | |||
290 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
integer
values, zero is a special case, in particular the following results might be unexpected: