]> git.cworth.org Git - sup/blobdiff - lib/sup/index.rb
Merge branch 'master' into next
[sup] / lib / sup / index.rb
index c66a24eac428ab7256ea237db16c42e126189dd7..e403570a74b39774d7ceefa046722d3dae3c12bb 100644 (file)
@@ -226,7 +226,7 @@ EOS
     ## but merge in the labels.
     if entry[:source_id] && entry[:source_info] && entry[:label] &&
       ((entry[:source_id].to_i > source_id) || (entry[:source_info].to_i < m.source_info))
-      labels = (entry[:label].split(/\s+/).map { |l| l.intern } + m.labels).uniq
+      labels = (entry[:label].symbolistize + m.labels).uniq
       #Redwood::log "found updated version of message #{m.id}: #{m.subj}"
       #Redwood::log "previous version was at #{entry[:source_id].inspect}:#{entry[:source_info].inspect}, this version at #{source_id.inspect}:#{m.source_info.inspect}"
       #Redwood::log "merged labels are #{labels.inspect} (index #{entry[:label].inspect}, message #{m.labels.inspect})"
@@ -332,7 +332,7 @@ EOS
 
       q = Ferret::Search::BooleanQuery.new true
       sq = Ferret::Search::PhraseQuery.new(:subject)
-      wrap_subj(Message.normalize_subj(m.subj)).split(/\s+/).each do |t|
+      wrap_subj(Message.normalize_subj(m.subj)).split.each do |t|
         sq.add_term t
       end
       q.add_query sq, :must
@@ -377,7 +377,7 @@ EOS
           unless messages.member?(mid)
             #Redwood::log "got #{mid} as a child of #{id}"
             messages[mid] ||= lambda { build_message docid }
-            refs = @index[docid][:refs].split(" ")
+            refs = @index[docid][:refs].split
             pending += refs.select { |id| !searched[id] }
           end
         end
@@ -388,7 +388,7 @@ EOS
       Redwood::log "thread for #{m.id} is killed, ignoring"
       false
     else
-      Redwood::log "ran #{num_queries} queries to build thread of #{messages.size + 1} messages for #{m.id}: #{m.subj}" if num_queries > 0
+      Redwood::log "ran #{num_queries} queries to build thread of #{messages.size} messages for #{m.id}: #{m.subj}" if num_queries > 0
       messages.each { |mid, builder| yield mid, builder }
       true
     end
@@ -408,13 +408,13 @@ EOS
         "date" => Time.at(doc[:date].to_i),
         "subject" => unwrap_subj(doc[:subject]),
         "from" => doc[:from],
-        "to" => doc[:to].split(/\s+/).join(", "), # reformat
+        "to" => doc[:to].split.join(", "), # reformat
         "message-id" => doc[:message_id],
-        "references" => doc[:refs].split(/\s+/).map { |x| "<#{x}>" }.join(" "),
+        "references" => doc[:refs].split.map { |x| "<#{x}>" }.join(" "),
       }
 
       m = Message.new :source => source, :source_info => doc[:source_info].to_i,
-                  :labels => doc[:label].split(" ").map { |s| s.intern },
+                  :labels => doc[:label].symbolistize,
                   :snippet => doc[:snippet]
       m.parse_header fake_header
       m
@@ -484,10 +484,27 @@ EOS
     @index_mutex.synchronize { @index.search(q, :limit => 1).total_hits > 0 }
   end
 
+  ## takes a user query string and returns the list of docids for messages
+  ## that match the query.
+  ##
+  ## messages can then be loaded from the index with #build_message.
+  ##
+  ## raises a ParseError if the parsing failed.
+  def run_query query
+    qobj, opts = Redwood::Index.parse_user_query_string query
+    query = Redwood::Index.build_query opts.merge(:qobj => qobj)
+    results = @index.search query, :limit => (opts[:limit] || :all)
+    results.hits.map { |hit| hit.doc }
+  end
+
 protected
 
-  ## do any specialized parsing
-  ## returns nil and flashes error message if parsing failed
+  class ParseError < StandardError; end
+
+  ## parse a query string from the user. returns a query object and a set of
+  ## extra flags; both of these are meant to be passed to #build_query.
+  ##
+  ## raises a ParseError if something went wrong.
   def parse_user_query_string s
     extraopts = {}
 
@@ -549,11 +566,9 @@ protected
     end
 
     if $have_chronic
-      chronic_failure = false
       subs = subs.gsub(/\b(before|on|in|during|after):(\((.+?)\)\B|(\S+)\b)/) do
-        break if chronic_failure
         field, datestr = $1, ($3 || $4)
-        realdate = Chronic.parse(datestr, :guess => false, :context => :none)
+        realdate = Chronic.parse datestr, :guess => false, :context => :past
         if realdate
           case field
           when "after"
@@ -567,11 +582,9 @@ protected
             "date:(<= #{sprintf "%012d", realdate.end.to_i}) date:(>= #{sprintf "%012d", realdate.begin.to_i})"
           end
         else
-          BufferManager.flash "Can't understand date #{datestr.inspect}!"
-          chronic_failure = true
+          raise ParseError, "can't understand date #{datestr.inspect}"
         end
       end
-      subs = nil if chronic_failure
     end
 
     ## limit:42 restrict the search to 42 results
@@ -581,15 +594,14 @@ protected
         extraopts[:limit] = lim.to_i
         ''
       else
-        BufferManager.flash "Can't understand limit #{lim.inspect}!"
-        subs = nil
+        raise ParseError, "non-numeric limit #{lim.inspect}"
       end
     end
     
-    if subs
+    begin
       [@qparser.parse(subs), extraopts]
-    else
-      nil
+    rescue Ferret::QueryParser::QueryParseException => e
+      raise ParseError, e.message
     end
   end