blib/lib/Search/Circa.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 35 | 108 | 32.4 |
branch | 2 | 40 | 5.0 |
condition | 2 | 32 | 6.2 |
subroutine | 10 | 24 | 41.6 |
pod | 7 | 15 | 46.6 |
total | 56 | 219 | 25.5 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Search::Circa; | ||||||
2 | |||||||
3 | # module Circa: provide general method for Circa | ||||||
4 | # Copyright 2000 A.Barbet alian@alianwebserver.com. All rights reserved. | ||||||
5 | # $Date: 2003/01/02 12:10:25 $ | ||||||
6 | |||||||
7 | 11 | 11 | 9908 | use DBI; | |||
11 | 22271 | ||||||
11 | 1062 | ||||||
8 | 11 | 11 | 19836 | use DBI::DBD; | |||
11 | 44232 | ||||||
11 | 931 | ||||||
9 | 11 | 11 | 7518 | use CircaConf; | |||
11 | 39 | ||||||
11 | 512 | ||||||
10 | 11 | 11 | 8386 | use Search::Circa::Categorie; | |||
11 | 40 | ||||||
11 | 595 | ||||||
11 | 11 | 11 | 9092 | use Search::Circa::Url; | |||
11 | 46 | ||||||
11 | 805 | ||||||
12 | 11 | 11 | 259 | use strict; | |||
11 | 25 | ||||||
11 | 538 | ||||||
13 | 11 | 11 | 99 | use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); | |||
11 | 22 | ||||||
11 | 1051 | ||||||
14 | 11 | 11 | 1728 | use Carp qw/cluck/; | |||
11 | 23 | ||||||
11 | 24244 | ||||||
15 | |||||||
16 | require Exporter; | ||||||
17 | |||||||
18 | @ISA = qw(Exporter); | ||||||
19 | @EXPORT = qw(); | ||||||
20 | $VERSION = ('$Revision: 1.18 $ ' =~ /(\d+\.\d+)/)[0]; | ||||||
21 | |||||||
22 | #------------------------------------------------------------------------------ | ||||||
23 | # new | ||||||
24 | #------------------------------------------------------------------------------ | ||||||
25 | sub new { | ||||||
26 | 1 | 1 | 0 | 3 | my $class = shift; | ||
27 | 1 | 5 | my $self = {}; | ||||
28 | 1 | 3 | bless $self, $class; | ||||
29 | 1 | 10 | $self->{DBH} = undef; | ||||
30 | 1 | 3 | $self->{PREFIX_TABLE} = 'circa_'; | ||||
31 | 1 | 4 | $self->{SERVER_PORT} ="3306"; # Port de mysql par default | ||||
32 | 1 | 3 | $self->{DEBUG} = 0; | ||||
33 | 1 | 4 | return $self; | ||||
34 | } | ||||||
35 | |||||||
36 | 0 | 0 | 0 | sub DESTROY { $_[0]->close(); } | |||
37 | |||||||
38 | |||||||
39 | #------------------------------------------------------------------------------ | ||||||
40 | # port_mysql | ||||||
41 | #------------------------------------------------------------------------------ | ||||||
42 | sub port_mysql { | ||||||
43 | 0 | 0 | 0 | 0 | my $self = shift; | ||
44 | 0 | 0 | 0 | if (@_) {$self->{SERVER_PORT}=shift;} | |||
0 | 0 | ||||||
45 | 0 | 0 | return $self->{SERVER_PORT}; | ||||
46 | } | ||||||
47 | |||||||
48 | #------------------------------------------------------------------------------ | ||||||
49 | # pre_tbl | ||||||
50 | #------------------------------------------------------------------------------ | ||||||
51 | sub pre_tbl { | ||||||
52 | 0 | 0 | 1 | 0 | my $self = shift; | ||
53 | 0 | 0 | 0 | if (@_) {$self->{PREFIX_TABLE}=shift;} | |||
0 | 0 | ||||||
54 | 0 | 0 | return $self->{PREFIX_TABLE}; | ||||
55 | } | ||||||
56 | |||||||
57 | #------------------------------------------------------------------------------ | ||||||
58 | # connect | ||||||
59 | #------------------------------------------------------------------------------ | ||||||
60 | sub connect { | ||||||
61 | 0 | 0 | 1 | 0 | my ($this,$user,$password,$db,$server)=@_; | ||
62 | 0 | 0 | 0 | 0 | if (!$user and !$password and !$db and !$server) { | ||
0 | |||||||
0 | |||||||
63 | 0 | 0 | 0 | $user = $this->{_USER} || $CircaConf::User; | |||
64 | 0 | 0 | 0 | $password = $this->{_PASSWORD} || $CircaConf::Password; | |||
65 | 0 | 0 | 0 | $db = $this->{_DB} || $CircaConf::Database; | |||
66 | 0 | 0 | 0 | $server = $this->{_HOST} || $CircaConf::Host; | |||
67 | } | ||||||
68 | 0 | 0 | 0 | $server = '127.0.0.1' if (!$server); | |||
69 | 0 | 0 | my $driver = "DBI:mysql:database=$db;host=$server;port=".$this->port_mysql; | ||||
70 | 0 | 0 | $this->{_DB}=$db; $this->{_PASSWORD}=$password; $this->{_USER}=$user; | ||||
0 | 0 | ||||||
0 | 0 | ||||||
71 | 0 | 0 | $this->{_HOST}=$server; | ||||
72 | 0 | 0 | 0 | $this->{DBH} = DBI->connect($driver,$user,$password,{ PrintError => 0 }) | |||
73 | || return 0; | ||||||
74 | 0 | 0 | return 1; | ||||
75 | } | ||||||
76 | |||||||
77 | #------------------------------------------------------------------------------ | ||||||
78 | # close | ||||||
79 | #------------------------------------------------------------------------------ | ||||||
80 | 0 | 0 | 0 | 1 | 0 | sub close {$_[0]->{DBH}->disconnect if ($_[0]->{DBH}); } | |
81 | |||||||
82 | #------------------------------------------------------------------------------ | ||||||
83 | # dbh | ||||||
84 | #------------------------------------------------------------------------------ | ||||||
85 | 0 | 0 | 0 | 0 | sub dbh { return $_[0]->{DBH};} | ||
86 | |||||||
87 | #------------------------------------------------------------------------------ | ||||||
88 | # categorie | ||||||
89 | #------------------------------------------------------------------------------ | ||||||
90 | 0 | 0 | 0 | 0 | sub categorie {return new Search::Circa::Categorie($_[0]);} | ||
91 | |||||||
92 | #------------------------------------------------------------------------------ | ||||||
93 | # URL | ||||||
94 | #------------------------------------------------------------------------------ | ||||||
95 | 0 | 0 | 0 | 0 | sub URL {return new Search::Circa::Url($_[0]);} | ||
96 | |||||||
97 | #------------------------------------------------------------------------------ | ||||||
98 | # start_classic_html | ||||||
99 | #------------------------------------------------------------------------------ | ||||||
100 | sub start_classic_html | ||||||
101 | { | ||||||
102 | 0 | 0 | 0 | 0 | my ($self,$cgi)=@_; | ||
103 | 0 | 0 | return $cgi->start_html | ||||
104 | ( -'title' => 'Circa', | ||||||
105 | -'author' => 'alian@alianwebserver.com', | ||||||
106 | -'meta' => {'keywords' => 'circa,recherche,annuaire,moteur', | ||||||
107 | -'copyright'=> 'copyright 1997-2000 AlianWebServer'}, | ||||||
108 | -'style' => {'src' => "circa.css"}, | ||||||
109 | -'dtd' => '-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd')."\n"; | ||||||
110 | } | ||||||
111 | |||||||
112 | #------------------------------------------------------------------------------ | ||||||
113 | # trace | ||||||
114 | #------------------------------------------------------------------------------ | ||||||
115 | sub trace { | ||||||
116 | 13 | 13 | 1 | 23 | my ($self, $level, $msg)=@_; | ||
117 | 13 | 50 | 66 | 34 | cluck if ($level >= 5 and $self->{DEBUG} >= $level); | ||
118 | |||||||
119 | 13 | 50 | 44 | if ($self->{DEBUG} >= $level) { | |||
120 | 0 | $msg= (' 'x(2*$level)).$msg; | |||||
121 | 0 | 0 | if ($msg) { | ||||
122 | 0 | 0 | if ($ENV{SERVER_NAME}) { | ||||
123 | 0 | print STDERR $msg,"\n"; } | |||||
124 | 0 | else { print $msg,"\n"; } | |||||
125 | } | ||||||
126 | } | ||||||
127 | } | ||||||
128 | |||||||
129 | #------------------------------------------------------------------------------ | ||||||
130 | # header | ||||||
131 | #------------------------------------------------------------------------------ | ||||||
132 | 0 | 0 | 0 | sub header {return "Content-Type: text/html\n\n";} | |||
133 | |||||||
134 | |||||||
135 | #------------------------------------------------------------------------------ | ||||||
136 | # fill_template | ||||||
137 | #------------------------------------------------------------------------------ | ||||||
138 | sub fill_template | ||||||
139 | { | ||||||
140 | 0 | 0 | 1 | my ($self,$masque,$vars)=@_; | |||
141 | 0 | 0 | open(FILE,$masque) || die "Can't read $masque "; |
||||
142 | 0 | my @buf= |
|||||
143 | 0 | CORE::close(FILE); | |||||
144 | 0 | while (my ($n,$v)=each(%$vars)) | |||||
145 | { | ||||||
146 | 0 | 0 | if ($v) {map {s/<\? \$$n \?>/$v/gm} @buf;} | ||||
0 | |||||||
0 | |||||||
0 | |||||||
147 | 0 | else {map {s/<\? \$$n \?>//gm} @buf;} | |||||
148 | } | ||||||
149 | 0 | return join('',@buf); | |||||
150 | } | ||||||
151 | |||||||
152 | #------------------------------------------------------------------------------ | ||||||
153 | # fetch_first | ||||||
154 | #------------------------------------------------------------------------------ | ||||||
155 | sub fetch_first | ||||||
156 | { | ||||||
157 | 0 | 0 | 1 | my ($self,$requete)=@_; | |||
158 | 0 | my $sth = $self->{DBH}->prepare($requete); | |||||
159 | 0 | my @row; | |||||
160 | 0 | 0 | if ($sth->execute) { | ||||
161 | # Pour chaque categorie | ||||||
162 | 0 | @row = $sth->fetchrow_array; | |||||
163 | 0 | $sth->finish; | |||||
164 | 0 | } else { $self->trace(1,"Erreur:$requete:$DBI::errstr "); } |
|||||
165 | 0 | 0 | if (wantarray()) { return @row; } | ||||
0 | |||||||
166 | 0 | else { return $row[0]; } | |||||
167 | } | ||||||
168 | |||||||
169 | #------------------------------------------------------------------------------ | ||||||
170 | # appartient | ||||||
171 | #------------------------------------------------------------------------------ | ||||||
172 | sub appartient | ||||||
173 | { | ||||||
174 | 0 | 0 | 0 | my ($self,$elem,@liste)=@_; | |||
175 | 0 | 0 | return 0 unless $elem; | ||||
176 | 0 | 0 | 0 | foreach (@liste) {return 1 if ($_ and $_ eq $elem);} | |||
0 | |||||||
177 | 0 | return 0; | |||||
178 | } | ||||||
179 | |||||||
180 | #------------------------------------------------------------------------------ | ||||||
181 | # prompt | ||||||
182 | #------------------------------------------------------------------------------ | ||||||
183 | sub prompt | ||||||
184 | { | ||||||
185 | 0 | 0 | 1 | my($self,$mess,$def)=@_; | |||
186 | 0 | 0 | my $ISA_TTY = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ; | ||||
187 | 0 | 0 | Carp::confess("prompt function called without an argument") | ||||
188 | unless defined $mess; | ||||||
189 | 0 | 0 | my $dispdef = defined $def ? "[$def] " : " "; | ||||
190 | 0 | 0 | $def = defined $def ? $def : ""; | ||||
191 | 0 | my $ans; | |||||
192 | 0 | local $|=1; | |||||
193 | 0 | print "$mess $dispdef"; | |||||
194 | 0 | 0 | if ($ISA_TTY) { chomp($ans = |
||||
0 | |||||||
195 | 0 | else { print "$def\n"; } | |||||
196 | 0 | 0 | return ($ans ne '') ? $ans : $def; | ||||
197 | } | ||||||
198 | |||||||
199 | #------------------------------------------------------------------------------ | ||||||
200 | # POD DOCUMENTATION | ||||||
201 | #------------------------------------------------------------------------------ | ||||||
202 | |||||||
203 | =head1 NAME | ||||||
204 | |||||||
205 | Search::Circa - a Search Engine / Indexer running with Mysql | ||||||
206 | |||||||
207 | =head1 DESCRIPTION | ||||||
208 | |||||||
209 | This is Search::Circa, a module who provide functions to | ||||||
210 | perform search on Circa, a www search engine running with | ||||||
211 | Mysql. Circa is for your Web site, or for a list of sites. | ||||||
212 | It indexes like Altavista does. It can read, add and | ||||||
213 | parse all url's found in a page. It add url and word | ||||||
214 | to MySQL for use it at search. | ||||||
215 | |||||||
216 | Circa can be used for index 100 to 100 000 url | ||||||
217 | |||||||
218 | Notes: | ||||||
219 | |||||||
220 | =over | ||||||
221 | |||||||
222 | =item * | ||||||
223 | |||||||
224 | Accents are removed on search and when indexed | ||||||
225 | |||||||
226 | =item * | ||||||
227 | |||||||
228 | Search are case unsensitive (mmmh what my english ? ;-) | ||||||
229 | |||||||
230 | =back | ||||||
231 | |||||||
232 | Search::Circa::Search work with Search::Circa::Indexer result. | ||||||
233 | Search::Circa::Search is a Perl interface, but it's exist on | ||||||
234 | this package a PHP client too. | ||||||
235 | |||||||
236 | Search::Circa is root class for Search::Circa::Indexer and | ||||||
237 | Search::Circa::Search. | ||||||
238 | |||||||
239 | =head1 SYNOPSIS | ||||||
240 | |||||||
241 | See L |
||||||
242 | |||||||
243 | =head1 FEATURES | ||||||
244 | |||||||
245 | =over | ||||||
246 | |||||||
247 | =item * | ||||||
248 | |||||||
249 | Search Features | ||||||
250 | |||||||
251 | =over | ||||||
252 | |||||||
253 | =item * | ||||||
254 | |||||||
255 | Boolean query language support : or (default) and ("+") not ("-"). Ex perl + faq -cgi : | ||||||
256 | Documents with faq, eventually perl and not cgi. | ||||||
257 | |||||||
258 | =item * | ||||||
259 | |||||||
260 | Client Perl or PHP | ||||||
261 | |||||||
262 | =item * | ||||||
263 | |||||||
264 | Can browse site by directory / rubrique. | ||||||
265 | |||||||
266 | =item * | ||||||
267 | |||||||
268 | Search for different criteria: news, last modified date, language, URL / site. | ||||||
269 | |||||||
270 | =back | ||||||
271 | |||||||
272 | =item * | ||||||
273 | |||||||
274 | Full text indexing | ||||||
275 | |||||||
276 | =item * | ||||||
277 | |||||||
278 | Different weights for title, keywords, description and rest of page HTML read can be given in configuration | ||||||
279 | |||||||
280 | =item * | ||||||
281 | |||||||
282 | Herite from features of LWP suite: | ||||||
283 | |||||||
284 | =over | ||||||
285 | |||||||
286 | =item * | ||||||
287 | |||||||
288 | Support protocol HTTP://,FTP://, FILE:// (Can do indexation of filesystem without talk to Web Server) | ||||||
289 | |||||||
290 | =item * | ||||||
291 | |||||||
292 | Full support of standard robots exclusion (robots.txt). Identification with | ||||||
293 | CircaIndexer/0.1, mail alian@alianwebserver.com. Delay requests to | ||||||
294 | the same server for 8 secondes. "It's not a bug, it's a feature!" Basic | ||||||
295 | rule for HTTP serveur load. | ||||||
296 | |||||||
297 | =item * | ||||||
298 | |||||||
299 | Support proxy HTTP. | ||||||
300 | |||||||
301 | =back | ||||||
302 | |||||||
303 | =item * | ||||||
304 | |||||||
305 | Make index in MySQL | ||||||
306 | |||||||
307 | =item * | ||||||
308 | |||||||
309 | Read HTML and full text plain | ||||||
310 | |||||||
311 | =item * | ||||||
312 | |||||||
313 | Several kinds of indexing : full, incremental, only on a particular server. | ||||||
314 | |||||||
315 | =item * | ||||||
316 | |||||||
317 | Documents not updated are not reindexed. | ||||||
318 | |||||||
319 | =item * | ||||||
320 | |||||||
321 | All requests for a file are made first with a head http request, for information | ||||||
322 | such as validate, last update, size, etc.Size of documents read can be | ||||||
323 | restricted (Ex: don't get all documents > 5 MB). For use with low-bandwidth | ||||||
324 | connections, or computers which do not have much memory. | ||||||
325 | |||||||
326 | =item * | ||||||
327 | |||||||
328 | HTML template can be easily customized for your needs. | ||||||
329 | |||||||
330 | =item * | ||||||
331 | |||||||
332 | Admin functions available by browser interface or command-line. | ||||||
333 | |||||||
334 | =item * | ||||||
335 | |||||||
336 | Index the different links found in a CGI (all after name_of_file?) | ||||||
337 | |||||||
338 | =back | ||||||
339 | |||||||
340 | =head1 FREQUENTLY ASKED QUESTIONS | ||||||
341 | |||||||
342 | Q: Where are clients for example ? | ||||||
343 | |||||||
344 | A: See in demo directory. For command line, see circa_admin and circa_search,, | ||||||
345 | for CGI, take a look in cgi-bin/circa, they are installed with make cgi. | ||||||
346 | |||||||
347 | Q: Where are global parameters to connect to Circa ? | ||||||
348 | |||||||
349 | A: Use lib/CircaConf.pm file | ||||||
350 | |||||||
351 | Q : What is an account for Circa ? | ||||||
352 | |||||||
353 | A: It's like a project, or a databse. A namespace for what you want. | ||||||
354 | |||||||
355 | Q : How I begin with indexer ? | ||||||
356 | |||||||
357 | A: See man page of L |
||||||
358 | |||||||
359 | Q : Did you succed to use Circa with mod_perl ? | ||||||
360 | |||||||
361 | A: Yes | ||||||
362 | |||||||
363 | =head1 Public interface | ||||||
364 | |||||||
365 | You use this method behind Search::Circa::Indexer and | ||||||
366 | Search::Circa::Search object | ||||||
367 | |||||||
368 | =over | ||||||
369 | |||||||
370 | =item B |
||||||
371 | |||||||
372 | Connect Circa to MySQL. Return 1 on succes, 0 else | ||||||
373 | |||||||
374 | =over | ||||||
375 | |||||||
376 | =item * | ||||||
377 | |||||||
378 | user : Utilisateur MySQL | ||||||
379 | |||||||
380 | =item * | ||||||
381 | |||||||
382 | password : Mot de passe MySQL | ||||||
383 | |||||||
384 | =item * | ||||||
385 | |||||||
386 | db : Database MySQL | ||||||
387 | |||||||
388 | =item * | ||||||
389 | |||||||
390 | bost : Adr IP du serveur MySQL | ||||||
391 | |||||||
392 | =back | ||||||
393 | |||||||
394 | Connect Circa to MySQL. Return 1 on succes, 0 else | ||||||
395 | |||||||
396 | =item B |
||||||
397 | |||||||
398 | Close connection to MySQL. This method is called with DESTROY method of this | ||||||
399 | class. | ||||||
400 | |||||||
401 | =item B |
||||||
402 | |||||||
403 | Get or set the prefix for table name for use Circa with more than one | ||||||
404 | time on a same database | ||||||
405 | |||||||
406 | =item B |
||||||
407 | |||||||
408 | =over | ||||||
409 | |||||||
410 | =item * | ||||||
411 | |||||||
412 | masque : Path of template | ||||||
413 | |||||||
414 | =item * | ||||||
415 | |||||||
416 | vars : hash ref with keys/val to substitue | ||||||
417 | |||||||
418 | =back | ||||||
419 | |||||||
420 | Give template with remplaced variables | ||||||
421 | Ex: | ||||||
422 | |||||||
423 | $circa->fill_template('A $age ?> ans', ('age' => '12 ans')); | ||||||
424 | |||||||
425 | Will return: | ||||||
426 | |||||||
427 | J'ai 12 ans, | ||||||
428 | |||||||
429 | =item B |
||||||
430 | |||||||
431 | Execute request SQL on db and return first row. In list context, retun full | ||||||
432 | row, else return just first column. | ||||||
433 | |||||||
434 | =item B |
||||||
435 | |||||||
436 | Print message I |
||||||
437 | is upper than I |
||||||
438 | |||||||
439 | =item B |
||||||
440 | |||||||
441 | Ask in STDIN for a parameter with message and default_value and return value | ||||||
442 | |||||||
443 | =back | ||||||
444 | |||||||
445 | =head1 SEE ALSO | ||||||
446 | |||||||
447 | L |
||||||
448 | |||||||
449 | L |
||||||
450 | |||||||
451 | L |
||||||
452 | |||||||
453 | L |
||||||
454 | |||||||
455 | L |
||||||
456 | |||||||
457 | =head1 VERSION | ||||||
458 | |||||||
459 | $Revision: 1.18 $ | ||||||
460 | |||||||
461 | =head1 AUTHOR | ||||||
462 | |||||||
463 | Alain BARBET alian@alianwebserver.com | ||||||
464 | |||||||
465 | =cut | ||||||
466 | |||||||
467 | 1; |