~ubuntu-branches/ubuntu/precise/apt-xapian-index/precise-security

« back to all changes in this revision

Viewing changes to examples/ruby/axi-searchasyoutype.rb

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2011-06-17 10:51:30 UTC
  • mfrom: (15.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110617105130-zrb03qthrg3l51mv
Tags: 0.43ubuntu1
* Merge from debian unstable.  Remaining changes:
  - when upgrading, ensure the index is fully rebuild (in the
    background) to ensure that we get updated information in
    /var/lib/apt-xapian-index/{index.values} and that the index
    fully utilizes the new plugins (LP: #646018)
  - use ionice for the index building
  - do not crash if the DB is already locked (LP: #590998)
  - data/org.debian.AptXapianIndex.conf: fix policy
  - move to dh_python2
  - update-apt-xapian-index-dbus:
    + fix type of "start-time" for policykit (LP: #675533)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env ruby
 
2
#
 
3
# axi-searchasyoutype - Search-as-you-type demo
 
4
#
 
5
# Copyright (C) 2007  Enrico Zini <enrico@debian.org>
 
6
# Copyright (C) 2008  Daniel Brumbaugh Keeney
 
7
#
 
8
# This program is free software; you can redistribute it and/or modify
 
9
# it under the terms of the GNU General Public License as published by
 
10
# the Free Software Foundation; either version 2 of the License, or
 
11
# (at your option) any later version.
 
12
#
 
13
# This program is distributed in the hope that it will be useful,
 
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
# GNU General Public License for more details.
 
17
#
 
18
# You should have received a copy of the GNU General Public License
 
19
# along with this program; if not, write to the Free Software
 
20
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
#
 
22
#############################
 
23
#
 
24
# INCOMPLETE, does not work
 
25
#
 
26
#############################
 
27
require 'optparse'
 
28
 
 
29
type = nil
 
30
OptionParser.new do |opts|
 
31
 
 
32
  opts.program_name = 'axi-query-pkgtype.rb'
 
33
  opts.version = '0.1'
 
34
  opts.release = '1203587714'
 
35
 
 
36
  opts.banner =
 
37
    "Query the Apt Xapian index.  Command line arguments can be keywords or Debtags tags"
 
38
 
 
39
 
 
40
  opts.on '-t', '--type TYPE', "package type, one of 'game', 'gui', 'cmdline' or 'editor'" do |v|
 
41
    type = v.to_sym
 
42
  end
 
43
 
 
44
  opts.on_tail("-h", "--help", "Show this message") do
 
45
    puts opts
 
46
    exit
 
47
  end
 
48
 
 
49
end.parse! rescue ( puts 'try axi-query-pkgtype.rb --help'; exit 2 )
 
50
 
 
51
args = ARGV.collect do |i| i.dup; end
 
52
 
 
53
 
 
54
# Import the rest here so we don't need dependencies to be installed only to
 
55
# print commandline help
 
56
require 'xapian'
 
57
require 'aptxapianindex'
 
58
require 'curses'
 
59
 
 
60
 
 
61
# Instantiate a xapian.Database object for read only access to the index
 
62
db = Xapian::Database.new(XAPIANDB)
 
63
 
 
64
# Show the results of a query while we type it
 
65
class Results
 
66
 
 
67
  def initialize stdscr
 
68
    maxy, maxx = stdscr.getmaxyx
 
69
    size = maxy-1
 
70
    # splitline = /\s+/
 
71
    win = curses.newwin(size, maxx, 0, 0)
 
72
    win.clear
 
73
  end
 
74
 
 
75
  def noresults(suggestion = "type more")
 
76
    win.clear
 
77
    win.addstr(0, 0, "No results, " + suggestion, curses.A_BOLD)
 
78
    win.refresh
 
79
  end
 
80
 
 
81
  # Show the results of the search done using the given line of text
 
82
  def update(line)
 
83
    line = line.lower.strip
 
84
    if line.length == 0
 
85
      # No text given: abort
 
86
      noresults
 
87
      return nil
 
88
    end
 
89
 
 
90
    # Split the line in words
 
91
    args = splitline.split(line)
 
92
 
 
93
    if args.length == 0
 
94
      # No text given: abort
 
95
      noresults
 
96
      return nil
 
97
    end
 
98
 
 
99
    # To understand the following code, keep in mind that we do
 
100
    # search-as-you-type, so the last word may be partially typed.
 
101
 
 
102
    if args[-1].length == 1
 
103
      # If the last term has only one character, we ignore it waiting for
 
104
      # the user to type more.  A better implementation can set up a
 
105
      # timer to disable this some time after the user stopped typing, to
 
106
      # give meaningful results to searches like "programming in c"
 
107
      args = args[0..-2]
 
108
      if args.length == 0
 
109
        self.noresults
 
110
        return nil
 
111
      end
 
112
    end
 
113
 
 
114
    # Convert the words into terms for the query
 
115
    terms = terms_for_simple_query(args)
 
116
 
 
117
    # Since the last word can be partially typed, we add all words that
 
118
    # begin with the last one.
 
119
    terms.extend(db.allterms(args[-1]).collect do |x| x.term; end)
 
120
 
 
121
    # Build the query
 
122
    query = Xapian::Query.new(Xapian::Query::OP_OR, terms)
 
123
 
 
124
    # Add the simple user filter, if requested.  This is to show that even
 
125
    # when we do search-as-you-type, everything works as usual
 
126
    query = addSimpleFilterToQuery(query, type)
 
127
 
 
128
    # Perform the query
 
129
    enquire = Xapian::Enquire.new(db)
 
130
    enquire.query = query
 
131
 
 
132
    # This does the adaptive cutoff trick on the query results (see
 
133
    # axi-query-adaptivecutoff.py)
 
134
    mset = enquire.mset(0, 1)
 
135
    begin
 
136
      top_weight = mset[0].weight
 
137
    rescue IndexError
 
138
      noresults 'change your query'
 
139
      return nil
 
140
    end
 
141
    enquire.set_cutoff(0, top_weight * 0.7)
 
142
 
 
143
    # Retrieve as many results as we can show
 
144
    mset = enquire.mset(0, self.size - 1)
 
145
 
 
146
    # Redraw the window
 
147
    self.win.clear
 
148
 
 
149
    # Header
 
150
    self.win.addstr(0, 0, "%i results found." % mset.matches_estimated, curses.A_BOLD)
 
151
 
 
152
    # Results
 
153
    mset.each_pair do |y, m|
 
154
      # /var/lib/apt-xapian-index/README tells us that the Xapian document data
 
155
      # is the package name.
 
156
      name = m.document.data
 
157
 
 
158
      # Print the match, together with the short description
 
159
      self.win.addstr(y+1, 0, "%i%% %s - %s" % [m.percent, name, pkg.summary])
 
160
    end
 
161
 
 
162
    self.win.refresh
 
163
  end
 
164
end
 
165
 
 
166
# Build the base query as seen in axi-query-simple.py
 
167
class Input
 
168
 
 
169
  def initialize stdscr, results
 
170
    maxy, maxx = stdscr.getmaxyx
 
171
    results = results
 
172
    win = curses.newwin(1, maxx, maxy-1, 0)
 
173
    win.bkgdset(' ', curses.A_REVERSE)
 
174
    win.clear
 
175
    win.addstr(0, 0, "> ", curses.A_REVERSE)
 
176
    line = ""
 
177
  end
 
178
 
 
179
  def mainloop
 
180
    old = ""
 
181
    loop do
 
182
      c = win.getch
 
183
      break if c == 10 or c == 27
 
184
      if c == 127
 
185
        control = true
 
186
        unless line.empty?
 
187
          line = line[0..-2]
 
188
        end
 
189
      else
 
190
        line << chr(c)
 
191
      end
 
192
      win.clear
 
193
      win.addstr(0, 0, "> " + self.line, curses.A_REVERSE)
 
194
      win.refresh
 
195
      unless line == old
 
196
        results.update(self.line)
 
197
        old = line
 
198
      end
 
199
    end
 
200
  end
 
201
end
 
202
 
 
203
def main(stdscr)
 
204
  results = Results.new(stdscr)
 
205
  input = Input(stdscr, results)
 
206
  stdscr.refresh
 
207
  input.mainloop
 
208
end
 
209
main nil
 
210
# curses.wrapper(main)