Passed
Push — master ( 26e53d...a73e13 )
by Dispositif
09:44
created

NotificationWorker::processSpecialActions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 2
rs 10
1
<?php
2
/**
3
 * This file is part of dispositif/wikibot application (@github)
4
 * 2019/2020 © Philippe M. <[email protected]>
5
 * For the full copyright and MIT license information, please view the license file.
6
 */
7
8
declare(strict_types=1);
9
10
namespace App\Application;
11
12
use App\Infrastructure\ServiceFactory;
13
use Mediawiki\Api\MediawikiApi;
14
use Mediawiki\Api\SimpleRequest;
15
use Mediawiki\Api\UsageException;
16
use Mediawiki\DataModel\EditInfo;
17
18
/**
19
 * todo internationalize (enwiki, etc)
20
 * Parsing last notifications to the bot (and set them read).
21
 * Doc API : https://www.mediawiki.org/wiki/Notifications/API
22
 * TYPES :
23
 * edit-user-talk
24
 * mention-summary (alerte)
25
 * mention (Discussion utilisateur:Codaxbot)
26
 * flowusertalk-post-reply (alerte,   "title": {
27
 * "full": "Discussion utilisateur:Ir\u00f8nie",
28
 * "namespace": "Discussion_utilisateur")
29
 * Class NotificationWorker
30
 */
31
class NotificationWorker
32
{
33
    const DEFAULT_WIKIS             = 'frwiki';
34
    const DIFF_URL                  = 'https://fr.wikipedia.org/w/index.php?diff=';
35
    const ARTICLE_ANALYZED_FILENAME = __DIR__.'/resources/article_externRef_edited.txt';
36
    const SUMMARY                   = '⚙ mise à jour notifications (ping [[User:Irønie]])';
37
    const PAGENAME_NOTIFICATION_LOG = 'Utilisateur:CodexBot/Notifications';
38
    const SKIP_BOTPAGES
39
                                    = [
40
            'Utilisateur:CodexBot',
41
            'Discussion utilisateur:CodexBot',
42
            'Utilisateur:ZiziBot',
43
            'Discussion utilisateur:ZiziBot',
44
        ];
45
46
    /**
47
     * @var MediawikiApi
48
     */
49
    private $api;
50
    /**
51
     * @var array
52
     */
53
    private $option;
54
55
    /**
56
     * NotificationWorker constructor.
57
     *
58
     * @throws UsageException
59
     */
60
    public function __construct(?array $option = null)
61
    {
62
        $this->api = ServiceFactory::getMediawikiApi();
63
        $this->option = ($option) ?? [];
64
65
        $this->process();
66
    }
67
68
    private function process()
69
    {
70
        $notifications = $this->requestNotifications();
71
        if (empty($notifications)) {
72
            return;
73
        }
74
75
        krsort($notifications);
76
77
        $wikilog = [];
78
        foreach ($notifications as $notif) {
79
            $title = $notif['title']['full'];
80
81
            // Skip bot pages
82
            if (in_array(
83
                $title,
84
                self::SKIP_BOTPAGES
85
            )
86
            ) {
87
                continue;
88
            }
89
90
            $date = new \DateTime($notif['timestamp']['utciso8601']);
91
92
            if (isset($notif['title']) && in_array($notif['title']['namespace'], ['', 'Discussion'])) {
93
                $icon = '🌼 '; // Article + Discussion
94
            }
95
96
            $wikilog[] = sprintf(
97
                '* %s %s[[%s]] ([%s%s diff]) par %s',
98
                $date->format('d-m-Y H\hi'),
99
                $icon ?? '',
100
                $title,
101
                self::DIFF_URL,
102
                $notif['revid'] ?? '',
103
                $notif['agent']['name'] ?? '???'
104
            );
105
            //            dump($notif);
106
107
            if (!isset($notif['read'])) {
108
                $this->postNotifAsRead($notif['id']);
109
            }
110
111
            $this->processSpecialActions($notif);
112
        }
113
114
        dump($wikilog);
115
116
        echo "sleep 20";
117
        sleep(20);
118
        $this->editWikilog($wikilog);
119
    }
120
121
    private function requestNotifications(): ?array
122
    {
123
        $result = $this->api->getRequest(
124
            new SimpleRequest(
125
                'query', [
126
                    'meta' => 'notifications',
127
                    'notwikis' => self::DEFAULT_WIKIS,
128
                    'notfilter' => '!read', // default: read|!read
129
                    'notlimit' => '30', // max 50
130
                    //                   'notunreadfirst' => '1', // comment for false
131
                    //                   'notgroupbysection' => '1',
132
                    'notsections' => 'alert', // alert|message
133
                    'format' => 'php',
134
                ]
135
            )
136
        );
137
138
        if (empty($result)) {
139
            return [];
140
        }
141
142
        return $result['query']['notifications']['list'];
143
    }
144
145
    private function postNotifAsRead(int $id): bool
146
    {
147
        sleep(2);
148
        try {
149
            $this->api->postRequest(
150
                new SimpleRequest(
151
                    'echomarkread', [
152
                        'list' => $id,
153
                        'token' => $this->api->getToken(),
154
                    ]
155
                )
156
            );
157
        } catch (\Throwable $e) {
158
            return false;
159
        }
160
161
        return true;
162
    }
163
164
    /**
165
     * Write wikilog of notifications on a dedicated page.
166
     *
167
     * @param array $wikilog
168
     *
169
     * @return bool
170
     * @throws UsageException
171
     */
172
    private function editWikilog(array $wikilog): bool
173
    {
174
        if (empty($wikilog)) {
175
            return false;
176
        }
177
        $text = implode("\n", $wikilog)."\n";
178
179
        $wiki = ServiceFactory::wikiApi();
180
        $pageAction = new WikiPageAction($wiki, self::PAGENAME_NOTIFICATION_LOG);
181
182
        $success = $pageAction->addToTopOfThePage(
183
            $text,
184
            new EditInfo(self::SUMMARY, false, false)
185
        );
186
187
        //        dump($success);
188
189
        return $success;
190
    }
191
192
    /**
193
     * Put there the special action to execute with each notification.
194
     *
195
     * @param $notif
196
     */
197
    protected function processSpecialActions($notif)
1 ignored issue
show
Unused Code introduced by
The parameter $notif is not used and could be removed. ( Ignorable by Annotation )

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

197
    protected function processSpecialActions(/** @scrutinizer ignore-unused */ $notif)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
198
    {
199
        // optional for children
200
    }
201
202
}
203