a49c9f8 by Pascal Bleser at 2010-07-29 1
#!/usr/bin/perl
2
# vim: set ai et sw=3 ts=3 nu:
3
#
4
# Queries Solr
5
#
6
# by Pascal Bleser <pascal.bleser@opensuse.org>
7
#
8
#     This library is free software; you can redistribute it and/or modify it
9
#     under the terms of the GNU Lesser General Public License as published by
10
#     the Free Software Foundation; either version 2.1 of the License, or (at
11
#     your option) any later version.
12
#                 
13
#     This library is distributed in the hope that it will be useful, but
14
#     WITHOUT ANY WARRANTY; without even the implied warranty of
15
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
#     Lesser General Public License for more details.
17
#      
18
#     You should have received a copy of the GNU Lesser General Public
19
#     License along with this library; if not, write to the Free Software
20
#     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
21
#     USA.
22
23
use strict;
24
use warnings;
25
use Getopt::Long;
26
use List::Util qw(max);
27
use Text::Wrap;
28
29
my $show_url = undef;
30
my $show_description = undef;
31
my $max_results = 10;
32
my $offset = 0;
33
my $distribution = undef;
34
my $arch = undef;
35
my $repoid = undef;
36
my $log = undef;
37
my $with_devel = undef;
38
my $with_lang = undef;
39
my $with_doc = undef;
40
GetOptions(
41
   'u|url'                  => \$show_url,
42
   'l|length=s'             => \$max_results,
43
   'o|offset=s'             => \$offset,
44
   'log=s'                  => \$log,
45
   'desc|descr|description' => \$show_description,
46
   'd|dist=s'               => \$distribution,
47
   'a|arch=s'               => \$arch,
48
   'r|repo=s'               => \$repoid,
49
   'devel'                  => \$with_devel,
50
   'lang'                   => \$with_lang,
51
   'doc'                    => \$with_doc,
52
);
53
die "must specify a query term" unless scalar(@ARGV) > 0;
54
my $q = join(" ", @ARGV);
55
56
use WebService::Solr;
57
my $solr = WebService::Solr->new("http://localhost:8983/solr", {
58
    autocommit => 0,
59
});
60
61
my @fq = ();
62
push(@fq, '-tag:devel') unless $with_devel;
63
push(@fq, '-tag:lang') unless $with_lang;
64
push(@fq, '-tag:doc') unless $with_doc;
65
push(@fq, '+distversion:'.$distribution) if defined $distribution;
66
push(@fq, '+arch:'.$arch) if defined $arch;
67
push(@fq, '+repoid:'.$repoid) if defined $repoid;
68
69
my $delim_pre  = '{!<';
70
my $delim_post = '>!}';
71
my $result = $solr->search($q, {
72
   'fl'                     => 'name^10.0,file^8.0,file_stopped^8.0,*,score',
73
   'hl'                     => 'true',
74
   'hl.fl'                  => 'name,summary,description,file,file_stopped',
75
   'hl.simple.pre'          => $delim_pre,
76
   'hl.simple.post'         => $delim_post,
77
   'hl.fragsize'            => '50000',
78
   'hl.snippets'            => '3',
79
   'hl.requireFieldMatch'   => 'false',
80
   'hl.usePhraseHighlighter'=> 'false',
81
   'fq'                     => join(' ', @fq),
82
   'rows'                   => $max_results,
83
   'start'                  => $offset,
84
});
85
86
my @docs = $result->docs;
87
if (scalar(@docs) < 1) {
88
   print "No results found for \"$q\"\n";
89
   exit 0;
90
}
91
{
92
   my $p = $result->pager;
93
   my $r1 = (($p->current_page() - 1) * $p->entries_per_page()) + 1;
94
   my $r2 = $r1 + (scalar(@docs) - 1);
95
   print "Showing results ", $r1, " to ", $r2, " out of ", $p->total_entries(), "\n";
96
}
97
sub hl($;$) {
98
   my $s = shift;
99
   my $bg = shift // '';
100
   $s =~ s/\Q$delim_pre\E(.+?)\Q$delim_post\E/\033[33;1m$1\033[0m$bg/g;
101
   return $s;
102
}
103
sub f($$;$) {
104
   my $doc = shift;
105
   my $name = shift;
106
   my $bg = shift // "";
107
   my $value = $doc->value_for($name);
108
   my $id = $doc->value_for('sha');
109
   my $hl = $result->content()->{highlighting};
110
   if (exists $hl->{$id} and exists $hl->{$id}->{$name}) {
111
      $value = hl(join(' ', @{$hl->{$id}->{$name}}));
112
   }
113
   return $value;
114
}
115
sub ff($$;$) {
116
   my $doc = shift;
117
   my $name = shift;
118
   my $bg = shift // "";
119
   my @values = $doc->values_for($name);
120
   my $id = $doc->value_for('sha');
121
   my $hl = $result->content()->{highlighting};
122
   if (exists $hl->{$id} and exists $hl->{$id}->{$name}) {
123
      @values = ();
124
      foreach (@{$hl->{$id}->{$name}}) {
125
         push(@values, hl($_));
126
      }
127
   }
128
   return \@values;
129
}
130
131
#$Text::Wrap::Columns = 100;
132
foreach my $d (@docs) {
133
   print "\033[42m» ",
134
   join("-", map { "\033[1m".$_."\033[0;42m" } map { f($d, $_, "\033[42;1m") } qw(name version release arch)),
135
   "   ", "[", f($d, 'distname'), " ", f($d, 'distversion'), " / ", f($d, 'repoid'), "]",
136
   "\033[K\033[0m",
137
   "\n";
138
   print "  ", "\033[4m", f($d, 'summary', "\033[4m"), "\033[0m", "\n";
139
   if ($show_description) {
140
      my @descr = split(/[\n\r]+/, f($d, 'description'));
141
      print fill("  ", "  ", @descr), "\n";
142
   }
143
   my $files = ff($d, 'file');
144
   print join("\n", map { "  * ".$_ } @$files), "\n" if scalar(@$files) > 0;
145
   print "\n";
146
}
147
148
if ($log) {
149
   open(my $l, '>', $log) or die "failed to create log file \"$log\": $!";
150
   use Data::Dumper;
151
   $Data::Dumper::Indent = 2;
152
   $Data::Dumper::Varname = 'result';
153
   print $l Dumper($result), "\n";
154
   close($l);
155
}
156