source: spip-zone/_plugins_/indexer/trunk/spip-cli/SphinxGenererAutocomplete.php @ 93505

Last change on this file since 93505 was 93505, checked in by rastapopoulos@…, 5 years ago

Ajout du découpage du dictionnaire dans plein de dossiers, rangés dans IMG/indexer_autoxomplete (copie de M-fil)

File size: 3.8 KB
Line 
1<?php
2
3use Symfony\Component\Console\Command\Command;
4use Symfony\Component\Console\Input\InputArgument;
5use Symfony\Component\Console\Input\InputInterface;
6use Symfony\Component\Console\Input\InputOption;
7use Symfony\Component\Console\Output\OutputInterface;
8use Symfony\Component\Console\Helper\ProgressHelper;
9
10class SphinxGenererAutocomplete extends Command {
11        protected function configure() {
12                $this
13                        ->setName('sphinx:generer_autocomplete')
14                        ->setDescription('Générer le dictionnaire nécessaire à l’autocomplétion. DOIT être lancée en sudo pour lire les dossiers de Sphinx.')
15                        ->addOption(
16                                'index',
17                                'i',
18                                InputOption::VALUE_OPTIONAL,
19                                'Nom de l’index Sphinx dont on veut générer le dictionnaire',
20                                'spip'
21                        )
22                        ->addOption(
23                                'dossier-data',
24                                null,
25                                InputOption::VALUE_OPTIONAL,
26                                'Nom de l’index Sphinx dont on veut générer le dictionnaire',
27                                '/var/lib/sphinxsearch/data/'
28                        )
29                ;
30        }
31
32        protected function execute(InputInterface $input, OutputInterface $output) {
33                include_spip('inc/flock');
34                include_spip('inc/indexer');
35               
36                // On récupère les options
37                $index = $input->getOption('index');
38                $dossier_data = $input->getOption('dossier-data');
39               
40                // On se fait un dossier temporaire pour enregistrer le dictionnaire complet
41                $dossier_tmp = sous_repertoire(_DIR_TMP . 'sphinx/');
42                $dict_tmp = $dossier_tmp . $index . '.dict.txt';
43               
44                // On se fait un dossier final
45                $dossier_autocomplete = sous_repertoire(_DIR_IMG . 'indexer_autocomplete');
46               
47                $sphinxql = new \Sphinx\SphinxQL\SphinxQL(SPHINX_SERVER_HOST, SPHINX_SERVER_PORT);
48               
49                // On fait produire les bons fichiers pour le RT
50                $sphinxql->query("FLUSH RAMCHUNK $index");
51               
52                // On récupère le chemin du premier fichier SPI trouvé dans le dossier Sphinx
53                if ($spis = glob($dossier_data . $index . '.*.spi') and $spi = $spis[0]) {
54                        if (function_exists('passthru')) {
55                                passthru("indextool --dumpdict {$spi} > {$dict_tmp}");
56                               
57                                // Si on a bien le dictionnaire voulu à la fin
58                                if (file_exists($dict_tmp)) {
59                                        $output->writeln("<info>Dictionnaire correctement créé dans {$dict_tmp}</info>");
60                                       
61                                        $this->analyser_dictionnaire(
62                                                $dossier_autocomplete,
63                                                $dict_tmp,
64                                                find_in_path('autocomplete/exceptions.txt')
65                                        );
66                                }
67                        }
68                        else {
69                                $output->writeln('<error>Votre installation de PHP doit pouvoir exécuter des commandes externes avec la fonction passthru().</error>');
70                        }
71                }
72                else {
73                        $output->writeln("<error>Pas trouvé de fichier data/$index.*.spi</error>");
74                }
75        }
76       
77        protected function analyser_dictionnaire($rep, $dict, $exceptions) {
78                include_spip('inc/charsets');
79                $ab = '';
80               
81                $exceptions = array_map('trim', file($exceptions));
82               
83                foreach(file($dict) as $k => $l) {
84                        list($keyword,$docs,$hits,$offset) = explode(',', $l);
85                       
86                        // Quand le tableau mots-fréquences commence, on démarre
87                        if ($keyword === 'keyword' and $docs === 'docs') {
88                                $start = true;
89                        }
90                       
91                        if ($start AND ord($l) != 2) {
92                                if (!in_array($keyword, $exceptions)) {
93                                        $_ab = strtolower(translitteration(mb_substr($keyword, 0, 2)));
94                                        if ($_ab !== $ab) {
95                                                $this->save($ab, $mots, $rep);
96                                                $ab = $_ab;
97                                                $mots = [];
98                                        }
99                                        // conserver les mots ayant un nombre suffisant d'occurrences
100                                        if ($hits >= 3) {
101                                                $mots[$keyword] = $hits;
102                                        }
103                                }
104                        }
105                }
106               
107                $this->save($ab, $mots, $rep);
108        }
109       
110        // enregistrer la liste ab - triée par hits décroissants
111        protected function save($ab, $mots, $rep) {
112                if (empty($mots)) return;
113                if (!preg_match(',[a-z][a-z],S', $ab)) return;
114               
115                arsort($mots);
116                $dump = join("\n", array_keys($mots));
117                $a = mb_substr($ab, 0,1);
118                if (!is_dir($rep.'/'.$a)) mkdir ($rep.'/'.$a);
119                $res = ($fp = fopen($rep.'/'.$a.'/'.$ab.'.txt', 'w'))
120                && fwrite ($fp, $dump)
121                && fclose ($fp);
122                spip_log("autocomplete dict $ab " . count($mots) . " ($res)");
123                return $res;
124        }
125}
Note: See TracBrowser for help on using the repository browser.