source: spip-zone/_plugins_/_stable_/yagloo/inc/prepare_recherche.php @ 26526

Last change on this file since 26526 was 26526, checked in by fil@…, 11 years ago

plugin Yagloo 0.1 : utiliser les API de recherche JSON de Yahoo ou de Google en lieu et place du moteur de recherche standard de SPIP

File size: 7.0 KB
Line 
1<?php
2
3
4@define('_DELAI_CACHE_RECHERCHES',600);
5
6// Preparer les listes id_article IN (...) pour les parties WHERE
7// et points =  des requetes du moteur de recherche
8function inc_prepare_recherche($recherche, $table='articles', $cond=false, $serveur='') {
9        static $cache = array();
10
11        // Liste des services de recherche connus
12        $services = array('boss', 'google');
13
14        // Si on n'est pas configure, revenir a la recherche normale
15        if (!$config = lire_config('yagloo')
16        OR !in_array($config['service'], $services)) {
17                include_once _DIR_RESTREINT.'inc/prepare_recherche.php';
18                return inc_prepare_recherche_dist($recherche, $table, $cond, $serveur);
19        }
20
21        // si recherche n'est pas dans le contexte, on va prendre en globals
22        // ca permet de faire des inclure simple.
23        $recherche = trim($recherche);
24        if (!strlen($recherche) AND isset($GLOBALS['recherche']))
25                $recherche = trim($GLOBALS['recherche']);
26
27        // traiter le cas {recherche?}
28        if ($cond AND !strlen($recherche))
29                return array("''" /* as points */, /* where */ '1');
30
31        // si on n'a pas encore traite les donnees
32        if (!isset($cache[$recherche])) {
33
34                spip_timer('recherche '.$config['service']);
35
36                // Ici il faut indiquer toutes les tables potentiellement {recherche}
37                $liste_index_tables = array(
38                        'articles' => 'id_article',
39                        'auteurs' => 'id_auteur',
40                        'breves' => 'id_breve',
41                        'mots' => 'id_mot',
42                        'rubriques' => 'id_rubrique'
43                );
44
45                // tester/nettoyer le cache de cette recherche
46                $hashes = array();
47                foreach ($liste_index_tables as $type => $_id) {
48                        $table_abreg = $type;
49                        $hash = substr(md5($recherche . $table_abreg),0,16);
50                        $cache[$recherche][$table_abreg] = array("resultats.points as points","recherche='$hash'");
51                        $hashes[] = $hash;
52                }
53
54                if (!$row = sql_fetsel('UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(maj) AS fraicheur','spip_resultats',
55                sql_in('recherche', $hashes),'','fraicheur DESC','0,1','',$serveur)
56                OR $row['fraicheur'] > _DELAI_CACHE_RECHERCHES) {
57
58                        $tab_couples = array();
59
60
61                        $domains = preg_replace(',^https?://,', '', $GLOBALS['meta']['adresse_site']);
62
63                        $yagloo = 'Yagloo_recherche_'.$config['service'];
64                        $results = $yagloo($recherche, $domains);
65
66                        $urls = array();
67                        $preg = ',^http://'.preg_quote($domains).'(/.+?)(\.html)?$,S';
68                        foreach($results as $i => $url) {
69                                if (preg_match($preg, $url, $regs)
70                                AND !isset($urls[$regs[1]])) {
71                                        $urls[$regs[1]] = 1.8*count($results)-$i;
72                                }
73                        }
74
75                        // rechercher le contexte correspondant
76                        spip_connect();
77                        if (!$f = generer_url_entite())
78                                $f = 'recuperer_parametres_url';
79
80                        $save = $GLOBALS['contexte'];
81                        $points = array();
82                        foreach($urls as $url => $score) {
83                                $f($fond, $url);
84                                foreach ($liste_index_tables as $type => $_id) {
85                                        if (isset($GLOBALS['contexte'][$_id])) {
86                                                $id = $GLOBALS['contexte'][$_id];
87                                                $points[$type][$id] = $score;
88                                        }
89                                }
90                        }
91
92                        /* modification des points pour les articles selon leur age */
93                        if (is_array($points['articles'])) {
94                                $s = sql_select('id_article,date_redac', 'spip_articles',
95                                        sql_in('id_article', array_keys($points['articles'])));
96                                while ($t = sql_fetch($s)) {
97                                        $points['articles'][$t['id_article']] *= (strtotime($t['date_redac']) - strtotime('1990-01')) / 100000000;
98                                }
99                        }
100
101
102                        foreach ($points as $type => $scores) {
103                                $ttable = 'spip_'.$type;
104                                $table_abreg = $type;
105                                $hash = substr(md5($recherche . $table_abreg),0,16);
106
107                                if (!count($scores)) {
108                                        $cache[$recherche][$ttable] = array("''", '0');
109                                } else {
110                                        foreach ($scores as $id => $score)
111                                                $tab_couples[] = array(
112                                                        'recherche' => $hash,
113                                                        'id' => $id,
114                                                        'points' => $score
115                                                );
116                                }
117                        }
118
119                        // Aucune reponse : le noter
120                        if (!count($tab_couples))
121                                $tab_couples[] = array(
122                                        'recherche' => $hashes[0],
123                                        'id' => 0,
124                                        'points' => 0
125                                );
126
127
128                        // supprimer les anciens resultats de cette recherche
129                        // et les resultats trop vieux avec une marge
130                        sql_delete('spip_resultats',
131                        '(maj<DATE_SUB(NOW(), INTERVAL '.(_DELAI_CACHE_RECHERCHES+100)." SECOND)) OR ". sql_in('recherche', $hashes),
132                        $serveur);
133
134                        // Inserer les reponses
135                        sql_insertq_multi('spip_resultats', $tab_couples, array(),$serveur);
136
137                        spip_log("recherche ".$config['service']." ($recherche) ".spip_timer("recherche ".$config['service']), 'indexation');
138                }
139        }
140
141        if ($val = $cache[$recherche][$table])
142                return $val;
143        return array("0 as points", '0=1');
144}
145
146function Yagloo_boss_decode($r) {
147        if ($r = json_decode($r)
148        AND $r = $r->ysearchresponse
149        AND $r->totalhits > 0
150        AND $r->responsecode == 200) {
151                foreach($r->resultset_web AS $item) {
152                        $results[] = $item->url;
153                };
154                return array($r->totalhits, $results);
155        }
156        return array(0,array());
157}
158function Yagloo_google_decode($r) {
159        if ($r = json_decode($r)
160        AND $r->responseStatus == 200
161        AND $r = $r->responseData
162        AND $r->cursor->estimatedResultCount > 0
163        ) {
164                foreach($r->results AS $item) {
165                        $results[] = $item->url;
166                };
167                return array($r->cursor->estimatedResultCount, $results);
168        }
169        return array(0,array());
170}
171
172function Yagloo_recherche_api($urlapi, $page, $maxpages, $json_decode) {
173        list($total, $results) = $json_decode(recuperer_page($urlapi));
174
175        if ($total > count($results)) {
176                $ping = min($maxpages, ceil(($total - count($results)) / $page));
177                $urls = array();
178                for ($i=1; $i<= $ping; $i++)
179                        $urls[] = $urlapi . '&start=' . ($i * $page);
180
181                foreach(Yagloo_recuperer_pages($urls) as $r) {
182                        list(,$z) = $json_decode($r);
183                        $results = array_merge($results, $z);
184                }
185        }
186
187        return $results;
188}
189
190function Yagloo_recherche_boss($recherche, $domains='') {
191        $appid = '';
192        $api = 'http://boss.yahooapis.com/ysearch/web/v1/';
193        $page = 50;
194        $urlapi = $api . urlencode($recherche) . '?appid=' . $appid
195                . '&format=json&sites=' . urlencode($domains) . '&count=' . $page;
196
197        return Yagloo_recherche_api($urlapi, $page, 14, 'Yagloo_boss_decode');
198}
199
200function Yagloo_recherche_google($recherche, $domains='') {
201        $apikey = '';
202        $api = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&rsz=large';
203        $urlapi = $api . '&q=site:' . urlencode($domains) . '+' . urlencode($recherche);
204        if ($apikey)
205                $urlapi .= '&key='.urlencode($apikey);
206        if (strlen($GLOBALS['spip_lang']))
207                $urlapi .= '&hl=' . $GLOBALS['spip_lang'];
208
209        return Yagloo_recherche_api($urlapi, 8, 8, 'Yagloo_google_decode');
210}
211
212// Charge plusieurs URLs en parallele
213function Yagloo_recuperer_pages($urls = array()) {
214        $ch = $res = array();
215        $mh = curl_multi_init();
216
217        foreach($urls as $url) {
218                $ch[$url] = curl_init();
219                curl_setopt($ch[$url], CURLOPT_URL, $url);
220                curl_setopt($ch[$url], CURLOPT_HEADER, 0);
221                curl_setopt($ch[$url], CURLOPT_RETURNTRANSFER, true);
222                curl_setopt($ch[$url], CURLOPT_REFERER,
223                $GLOBALS['meta']['adresse_site'].'/');
224                curl_setopt($ch[$url], CURLOPT_USERAGENT,
225                "SPIP-".$GLOBALS['spip_version_affichee']." (http://www.spip.net/)");
226                curl_multi_add_handle($mh, $ch[$url]);
227                spip_log('Recuperer '.$url);
228        }
229 
230        $running=null;
231        do {
232                curl_multi_exec($mh,$running);
233        } while ($running > 0);
234
235        foreach($ch as $url => $c) {
236                $res[$url] = curl_multi_getcontent($c);
237                curl_multi_remove_handle($mh, $c);
238        }
239        curl_multi_close($mh);
240
241        return $res;
242}
243
Note: See TracBrowser for help on using the repository browser.