query = build_query opts
offset = 0
while true
- results = @index_mutex.synchronize { @index.search query, :sort => "date DESC", :limit => EACH_BY_DATE_NUM, :offset => offset }
+ limit = (opts[:limit])? [EACH_BY_DATE_NUM, opts[:limit] - offset].min : EACH_BY_DATE_NUM
+ results = @index_mutex.synchronize { @index.search query, :sort => "date DESC", :limit => limit, :offset => offset }
Redwood::log "got #{results.total_hits} results for query (offset #{offset}) #{query.inspect}"
results.hits.each do |hit|
yield @index_mutex.synchronize { @index[hit.doc][:message_id] }, lambda { build_message hit.doc }
end
- break if offset >= results.total_hits - EACH_BY_DATE_NUM
- offset += EACH_BY_DATE_NUM
+ break if opts[:limit] and offset >= opts[:limit] - limit
+ break if offset >= results.total_hits - limit
+ offset += limit
end
end
## builds a message object from a ferret result
def build_message docid
- doc = @index_mutex.synchronize { @index[docid] }
- source = @source_mutex.synchronize { @sources[doc[:source_id].to_i] }
- #puts "building message #{doc[:message_id]} (#{source}##{doc[:source_info]})"
- raise "invalid source #{doc[:source_id]}" unless source
-
- fake_header = {
- "date" => Time.at(doc[:date].to_i),
- "subject" => unwrap_subj(doc[:subject]),
- "from" => doc[:from],
- "to" => doc[:to].split(/\s+/).join(", "), # reformat
- "message-id" => doc[:message_id],
- "references" => doc[:refs].split(/\s+/).map { |x| "<#{x}>" }.join(" "),
- }
+ @index_mutex.synchronize do
+ doc = @index[docid]
+
+ source = @source_mutex.synchronize { @sources[doc[:source_id].to_i] }
+ raise "invalid source #{doc[:source_id]}" unless source
- Message.new :source => source, :source_info => doc[:source_info].to_i,
- :labels => doc[:label].split(" ").map { |s| s.intern },
- :snippet => doc[:snippet], :header => fake_header
+ #puts "building message #{doc[:message_id]} (#{source}##{doc[:source_info]})"
+
+ fake_header = {
+ "date" => Time.at(doc[:date].to_i),
+ "subject" => unwrap_subj(doc[:subject]),
+ "from" => doc[:from],
+ "to" => doc[:to].split(/\s+/).join(", "), # reformat
+ "message-id" => doc[:message_id],
+ "references" => doc[:refs].split(/\s+/).map { |x| "<#{x}>" }.join(" "),
+ }
+
+ Message.new :source => source, :source_info => doc[:source_info].to_i,
+ :labels => doc[:label].split(" ").map { |s| s.intern },
+ :snippet => doc[:snippet], :header => fake_header
+ end
end
def fresh_thread_id; @next_thread_id += 1; end
def drop_entry docno; @index_mutex.synchronize { @index.delete docno } end
def load_entry_for_id mid
- results = @index_mutex.synchronize { @index.search Ferret::Search::TermQuery.new(:message_id, mid) }
- return if results.total_hits == 0
- docid = results.hits[0].doc
- [docid, @index_mutex.synchronize { @index[docid] } ]
+ @index_mutex.synchronize do
+ results = @index.search Ferret::Search::TermQuery.new(:message_id, mid)
+ return if results.total_hits == 0
+ docid = results.hits[0].doc
+ entry = @index[docid]
+ entry_dup = entry.fields.inject({}) { |h, f| h[f] = entry[f]; h }
+ [docid, entry_dup]
+ end
end
def load_contacts emails, h={}
q = Ferret::Search::BooleanQuery.new
q.add_query Ferret::Search::TermQuery.new("source_id", source.id.to_s), :must
q.add_query Ferret::Search::TermQuery.new("label", label.to_s), :must
- @index_mutex.synchronize { index.search(q, :limit => 1).total_hits > 0 }
+ @index_mutex.synchronize { @index.search(q, :limit => 1).total_hits > 0 }
end
protected
end
subs = nil if chronic_failure
end
+
+ ## limit:42 restrict the search to 42 results
+ subs = subs.gsub(/\blimit:(\S+)\b/) do
+ lim = $1
+ if lim =~ /^\d+$/
+ extraopts[:limit] = lim.to_i
+ ''
+ else
+ BufferManager.flash "Can't understand limit #{lim.inspect}!"
+ subs = nil
+ end
+ end
if subs
[@qparser.parse(subs), extraopts]