Passed
Push — master ( 1601e8...0a41a5 )
by Dispositif
05:46
created

CompleteProcess   B

Complexity

Total Complexity 48

Size/Duplication

Total Lines 275
Duplicated Lines 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
eloc 136
c 7
b 0
f 0
dl 0
loc 275
rs 8.5599
wmc 48

8 Methods

Rating   Name   Duplication   Size   Complexity  
A skipGoogle() 0 11 5
A __construct() 0 4 1
F onlineIsbnSearch() 0 65 21
A getNewRaw() 0 9 2
B run() 0 64 9
A completeOuvrage() 0 20 5
A sendCompleted() 0 22 4
A serializeFinalOpti() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like CompleteProcess often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CompleteProcess, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * This file is part of dispositif/wikibot application
4
 * 2019 : 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\Examples;
11
12
use App\Application\Bot;
13
use App\Application\Memory;
14
use App\Application\QueueInterface;
15
use App\Domain\Models\Wiki\OuvrageTemplate;
16
use App\Domain\OuvrageComplete;
17
use App\Domain\OuvrageFactory;
18
use App\Domain\OuvrageOptimize;
19
use App\Domain\Publisher\Wikidata2Ouvrage;
20
use App\Domain\Utils\TemplateParser;
21
use Normalizer;
22
use Throwable;
23
24
/**
25
 * Class CompleteProcess
26
 */
27
class CompleteProcess
28
{
29
    /**
30
     * @var bool
31
     */
32
    public $verbose = false;
33
34
    /**
35
     * @var QueueInterface
36
     */
37
    private $queueAdapter;
38
    /**
39
     * @var string
40
     */
41
    private $raw = '';
42
    private $log = [];
43
    private $notCosmetic = false;
44
    private $major = false;
45
    /**
46
     * @var OuvrageTemplate
47
     */
48
    private $ouvrage;
49
50
    public function __construct(QueueInterface $queueAdapter, ?bool $verbose = false)
51
    {
52
        $this->queueAdapter = $queueAdapter;
53
        $this->verbose = (bool)$verbose;
54
    }
55
56
    public function run(?int $limit = 10000)
57
    {
58
        $memory = new Memory();
59
        while ($limit > 0) {
60
            $limit--;
61
            sleep(1);
62
            $this->raw = $this->getNewRaw();
63
64
            echo sprintf(
65
                "-------------------------------\n%s [%s]\n\n%s\n",
66
                date("Y-m-d H:i:s"),
67
                Bot::getGitVersion() ?? '',
68
                $this->raw
69
            );
70
            if ($this->verbose) {
71
                $memory->echoMemory(true);
72
            }
73
74
            // initialise variables
75
            $this->log = [];
76
            $this->ouvrage = null;
77
            $this->notCosmetic = false;
78
            $this->major = false;
79
80
81
            try {
82
                $parse = TemplateParser::parseAllTemplateByName('ouvrage', $this->raw);
83
                $origin = $parse['ouvrage'][0]['model'] ?? null;
84
            } catch (Throwable $e) {
85
                echo sprintf("*** ERREUR impossible de transformer en modèle %s \n", $this->raw);
86
                continue;
87
            }
88
89
            if (!$origin instanceof OuvrageTemplate) {
90
                echo sprintf("*** ERREUR impossible de transformer en modèle %s \n", $this->raw);
91
                continue;
92
            }
93
94
            // Final optimizing (with online predictions)
95
            $optimizer = new OuvrageOptimize($origin, null);
96
            $optimizer->doTasks();
97
            $this->ouvrage = $optimizer->getOuvrage();
98
            $this->log = array_merge($this->log, $optimizer->getLog());
99
            $this->notCosmetic = ($optimizer->notCosmetic || $this->notCosmetic);
100
101
            /**
102
             * RECHERCHE ONLINE
103
             */
104
            $isbn = $origin->getParam('isbn') ?? null; // avant mise en forme EAN>ISBN
105
            $isbn10 = $origin->getParam('isbn2') ?? $origin->getParam('isbn10') ?? null;
106
            if (!empty($isbn)
107
                && empty($origin->getParam('isbn invalide'))
108
                && empty($origin->getParam('isbn erroné'))
109
            ) {
110
                $this->onlineIsbnSearch($isbn, $isbn10);
111
            }
112
113
            $this->sendCompleted();
114
            unset($optimizer);
115
            unset($parse);
116
            unset($origin);
117
        } // END WHILE
118
119
        return true;
120
    }
121
122
    /**
123
     * Get raw string to complete from AMQP queue, SQL Select or file reading.
124
     *
125
     * @return string|null
126
     * @throws \Exception
127
     */
128
    private function getNewRaw(): ?string
129
    {
130
        $raw = $this->queueAdapter->getNewRaw();
131
        if (!$raw) {
132
            echo "STOP: no more queue to process \n";
133
            throw new \Exception('no more queue to process');
134
        }
135
136
        return $raw;
137
    }
138
139
    private function onlineIsbnSearch(string $isbn, ?string $isbn10 = null)
140
    {
141
        online:
142
        if ($this->verbose) {
143
            echo "sleep 10...\n";
144
        }
145
        sleep(10);
146
147
        try {
148
            if ($this->verbose) {
149
                dump('BIBLIO NAT FRANCE...');
150
            }
151
            // BnF sait pas trouver un vieux livre (10) d'après ISBN-13... FACEPALM !
152
            if ($isbn10) {
153
                $bnfOuvrage = OuvrageFactory::BnfFromIsbn($isbn10);
154
                sleep(2);
155
            }
156
            if (!$isbn10 || empty($bnfOuvrage) || empty($bnfOuvrage->getParam('titre'))) {
157
                $bnfOuvrage = OuvrageFactory::BnfFromIsbn($isbn);
158
            }
159
            if (isset($bnfOuvrage) and $bnfOuvrage instanceof OuvrageTemplate) {
160
                $this->completeOuvrage($bnfOuvrage);
161
162
                // Wikidata requests from $infos (ISBN/ISNI)
163
                if (!empty($bnfOuvrage->getInfos())) {
164
                    if ($this->verbose) {
165
                        dump('WIKIDATA...');
166
                    }
167
                    $wdComplete = new Wikidata2Ouvrage(clone $bnfOuvrage);
168
                    $this->completeOuvrage($wdComplete->getOuvrage());
169
                }
170
            }
171
        } catch (Throwable $e) {
172
            echo sprintf(
173
                "*** ERREUR BnF Isbn Search %s %s %s \n",
174
                $e->getMessage(),
175
                $e->getFile(),
176
                $e->getLine()
177
            );
178
        }
179
180
        if (!isset($bnfOuvrage) || !$this->skipGoogle($bnfOuvrage)) {
181
            try {
182
                if ($this->verbose) {
183
                    dump('GOOGLE...');
184
                }
185
                $googleOuvrage = OuvrageFactory::GoogleFromIsbn($isbn);
186
                $this->completeOuvrage($googleOuvrage);
187
            } catch (Throwable $e) {
188
                echo "*** ERREUR GOOGLE Isbn Search ***".$e->getMessage()."\n";
189
                throw $e;
190
            }
191
        }
192
193
        if (!isset($bnfOuvrage) && !isset($googleOuvrage)) {
194
            try {
195
                if ($this->verbose) {
196
                    dump('OpenLibrary...');
197
                }
198
                $openLibraryOuvrage = OuvrageFactory::OpenLibraryFromIsbn($isbn);
199
                if (!empty($openLibraryOuvrage)) {
200
                    $this->completeOuvrage($openLibraryOuvrage);
201
                }
202
            } catch (Throwable $e) {
203
                echo '**** ERREUR OpenLibrary Isbn Search';
204
            }
205
        }
206
    }
207
208
    //    private function onlineQuerySearch(string $query)
209
    //    {
210
    //        echo "sleep 40...";
211
    //        sleep(20);
212
    //        onlineQuerySearch:
213
    //
214
    //        try {
215
    //            dump('GOOGLE SEARCH...');
216
    //            //            $googleOuvrage = OuvrageFactory::GoogleFromIsbn($isbn);
217
    //            $adapter = new GoogleBooksAdapter();
218
    //            $data = $adapter->search('blabla');
219
    //            dump($data);
220
    //            //die;
221
    //            //            return $import->getOuvrage();
222
    //            //            $this->completeOuvrage($googleOuvrage);
223
    //        } catch (Throwable $e) {
224
    //            echo "*** ERREUR GOOGLE QuerySearch *** ".$e->getMessage()."\n";
225
    //            echo "sleep 30min";
226
    //            sleep(60 * 30);
227
    //            echo "Wake up\n";
228
    //            goto onlineQuerySearch;
229
    //        }
230
    //    }
231
232
    private function completeOuvrage(OuvrageTemplate $onlineOuvrage)
233
    {
234
        if ($this->verbose) {
235
            dump($onlineOuvrage->serialize(true));
236
        }
237
        $optimizer = new OuvrageOptimize($onlineOuvrage);
238
        $onlineOptimized = ($optimizer)->doTasks()->getOuvrage();
239
240
        $completer = new OuvrageComplete($this->ouvrage, $onlineOptimized);
241
        $this->ouvrage = $completer->getResult();
242
        if ($this->verbose) {
243
            dump($completer->getLog());
244
        }
245
        if ($completer->major) {
246
            $this->major = true;
247
        }
248
        $this->notCosmetic = ($completer->notCosmetic || $this->notCosmetic);
249
        $this->log = array_merge($this->log, $completer->getLog());
250
        unset($optimizer);
251
        unset($completer);
252
    }
253
254
    private function sendCompleted()
255
    {
256
        $isbn13 = $this->ouvrage->getParam('isbn') ?? null;
257
258
        $finalData = [
259
            //    'page' =>
260
            'raw' => $this->raw,
261
            'opti' => $this->serializeFinalOpti(),
262
            'optidate' => date("Y-m-d H:i:s"),
263
            'modifs' => mb_substr(implode(',', $this->log), 0, 250),
264
            'notcosmetic' => ($this->notCosmetic) ? 1 : 0,
265
            'major' => ($this->major) ? 1 : 0,
266
            'isbn' => substr($isbn13, 0, 20),
267
            'version' => Bot::getGitVersion() ?? null,
268
        ];
269
        if ($this->verbose) {
270
            dump($finalData);
271
        }
272
        // Json ?
273
        $result = $this->queueAdapter->sendCompletedData($finalData);
274
275
        dump($result); // bool
276
    }
277
278
    /**
279
     * Final serialization of the completed OuvrageTemplate.
280
     *
281
     * @return string
282
     */
283
    private function serializeFinalOpti(): string
284
    {
285
        $finalOpti = $this->ouvrage->serialize(true);
286
        $finalOpti = Normalizer::normalize($finalOpti);
287
288
        return $finalOpti;
289
    }
290
291
    private function skipGoogle($bnfOuvrage): bool
292
    {
293
        if ($bnfOuvrage instanceOf OuvrageTemplate
294
            && !empty($bnfOuvrage->getParam('titre'))
295
            && (!empty($this->ouvrage->getParam('lire en ligne'))
296
                || !empty($this->ouvrage->getParam('présentation en ligne')))
297
        ) {
298
            return true;
299
        }
300
301
        return false;
302
    }
303
}
304