Class: IHelp::IHelpIndex
Overview
IHelpIndex uses Ferret to index all available RI documentation and lets you do full text searches over the index.
E.g. IHelpIndex.new.search(“domain name lookup”)
See Ferret::QueryParser for query string format.
Constant Summary collapse
- GLOBAL_INDEX_PATH =
Default place to save and load the index from.
File.join(File.dirname(__FILE__), "ihelp.index")
- LOCAL_INDEX_PATH =
File.join(ENV["HOME"], ".ihelp.index")
- DEFAULT_LOG_LEVEL =
2
Class Attribute Summary collapse
-
.reindex_when_needed ⇒ Object
Returns the value of attribute reindex_when_needed.
Instance Attribute Summary collapse
-
#index ⇒ Object
The search index, is a Ferret::Index::Index.
-
#log_level ⇒ Object
Returns the value of attribute log_level.
Instance Method Summary collapse
- #all_names ⇒ Object
-
#already_indexed?(full_name) ⇒ Boolean
Returns true if there already is an object named full_name.
- #display ⇒ Object
- #format_time(t) ⇒ Object
- #init_display ⇒ Object
-
#initialize(use_global_index = (ENV["USER"] == "root")) ⇒ IHelpIndex
constructor
A new instance of IHelpIndex.
- #log(str, level = 1) ⇒ Object
- #need_reindexing? ⇒ Boolean
- #page(*a, &b) ⇒ Object
- #path ⇒ Object
-
#reindex! ⇒ Object
Reindexes any non-indexed help documents.
-
#search(query) ⇒ Object
Searches for the terms in query and prints out first ten hits.
- #time ⇒ Object
- #wrap(str) ⇒ Object
- #wrap_str(str) ⇒ Object
Constructor Details
#initialize(use_global_index = (ENV["USER"] == "root")) ⇒ IHelpIndex
Returns a new instance of IHelpIndex.
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 |
# File 'lib/ihelp.rb', line 601 def initialize(use_global_index = (ENV["USER"] == "root")) @log_level = DEFAULT_LOG_LEVEL if use_global_index @index_path = GLOBAL_INDEX_PATH else @index_path = LOCAL_INDEX_PATH if not File.exist?(@index_path) and File.exist?(GLOBAL_INDEX_PATH) FileUtils.cp_r(GLOBAL_INDEX_PATH, @index_path) rescue nil elsif not File.exist?(@index_path) self.class.reindex_when_needed = true end end analyzer = IHelpAnalyzer.new have_index = File.exist? @index_path if have_index log "Loading existing index from #{@index_path}", 1 @index = Ferret::I.new( :key => :full_name, :path => @index_path, :analyzer => analyzer ) else log "Creating new index in #{@index_path}", 2 field_infos = Ferret::Index::FieldInfos.new(:term_vector => :no) field_infos.add_field(:name, :store => :yes, :index => :yes, :boost => 10.0) field_infos.add_field(:full_name, :store => :yes, :index => :untokenized, :boost => 0.0) field_infos.add_field(:content, :boost => 1.0, :store => :yes, :index => :yes, :term_vector => :with_positions_offsets) @index = Ferret::I.new( :key => :full_name, :field_infos => field_infos, :analyzer => analyzer ) end if self.class.reindex_when_needed and need_reindexing? reindex! end unless have_index @index.persist(@index_path) log "\nSaved index.", 2 end end |
Class Attribute Details
.reindex_when_needed ⇒ Object
Returns the value of attribute reindex_when_needed.
588 589 590 |
# File 'lib/ihelp.rb', line 588 def reindex_when_needed @reindex_when_needed end |
Instance Attribute Details
#index ⇒ Object
The search index, is a Ferret::Index::Index
592 593 594 |
# File 'lib/ihelp.rb', line 592 def index @index end |
#log_level ⇒ Object
Returns the value of attribute log_level.
594 595 596 |
# File 'lib/ihelp.rb', line 594 def log_level @log_level end |
Instance Method Details
#all_names ⇒ Object
684 685 686 |
# File 'lib/ihelp.rb', line 684 def all_names IHelp.ri_driver.ri_reader.all_names.uniq end |
#already_indexed?(full_name) ⇒ Boolean
Returns true if there already is an object named full_name
670 671 672 |
# File 'lib/ihelp.rb', line 670 def already_indexed? full_name @index[full_name] end |
#display ⇒ Object
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
# File 'lib/ihelp.rb', line 742 def display return @display if @display @display = IHelp.ri_driver.display if ENV["PAGER"].to_s.size > 0 unless ENV["PAGER"] =~ /(^|\/)less\b.* -[a-zA-Z]*[rR]/ IHelp.no_colors = true end else ENV["PAGER"] = "less -R" end class << @display public :page attr_accessor :formatter end @display end |
#format_time(t) ⇒ Object
674 675 676 677 678 679 680 681 682 |
# File 'lib/ihelp.rb', line 674 def format_time(t) sec = t % 60 min = (t / 60) % 60 hour = (t / 3600) str = sec.to_i.to_s.rjust(2,'0') str = min.to_i.to_s.rjust(2,'0') + ":" + str str = hour.to_i.to_s.rjust(2,'0') + ":" + str if hour >= 1 str end |
#init_display ⇒ Object
776 777 778 |
# File 'lib/ihelp.rb', line 776 def init_display display end |
#log(str, level = 1) ⇒ Object
653 654 655 |
# File 'lib/ihelp.rb', line 653 def log str, level = 1 STDERR.puts str if level >= @log_level end |
#need_reindexing? ⇒ Boolean
688 689 690 |
# File 'lib/ihelp.rb', line 688 def need_reindexing? all_names.size > @index.size end |
#page(*a, &b) ⇒ Object
759 760 761 |
# File 'lib/ihelp.rb', line 759 def page(*a,&b) display.page(*a,&b) end |
#path ⇒ Object
657 658 659 |
# File 'lib/ihelp.rb', line 657 def path @index_path end |
#reindex! ⇒ Object
Reindexes any non-indexed help documents.
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 |
# File 'lib/ihelp.rb', line 694 def reindex! start_size = @index.size names = all_names log "Indexing...", 2 nsz = names.size.to_s i = 0 names.each{|n| i += 1 next if (start_size > 0) and (already_indexed?(n)) if @log_level == DEFAULT_LOG_LEVEL amt_done = (i.to_f / names.size) pct = ("%.1f" % [100*amt_done]).rjust(5) STDERR.write "\r #{pct}% (#{i.to_s.rjust(nsz.size)}/#{nsz}) #{n}".ljust(80)[0,80] STDERR.flush end hd = if n.include? "#" IHelp.ri_driver.get_info_str(*(n.split("#") + [true])) elsif n.include? "::" IHelp.ri_driver.get_info_str(n) or IHelp.ri_driver.get_info_str(*n.reverse.split("::",2).reverse.map{|r| r.reverse }) else IHelp.ri_driver.get_info_str n end if hd.nil? log "skipping #{n} (not found)" next else log "indexing #{n}" end @index << { :name => hd.full_name, :full_name => n, :content => wrap_str(hd.to_text) } } if @log_level == DEFAULT_LOG_LEVEL amt_done = (i.to_f / names.size) pct = ("%.1f" % [100*amt_done]).rjust(5) STDERR.write "\r #{pct}% (#{i.to_s.rjust(nsz.size)}/#{nsz}) #{names.last}".ljust(80)[0,80] STDERR.flush STDERR.puts end if start_size != @index.size log "Optimizing index... (old size #{start_size}, current size #{@index.size})" @index.optimize end end |
#search(query) ⇒ Object
Searches for the terms in query and prints out first ten hits
See Ferret::QueryParser for query string format.
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 |
# File 'lib/ihelp.rb', line 784 def search(query) result = @index.search(query, :limit => 1000) init_display if IHelp.no_colors or `which less`.strip.empty? pre_tag = "<<" post_tag = ">>" else name_start = "\033[32m" name_end = "\033[0m" pre_tag = "\033[36m" post_tag = "\033[0m" end page do puts puts "=== #{result.total_hits} hits#{", showing first 1000" if result.total_hits > 1000} ".ljust(72,"=") puts result.hits.each_with_index do |hit, i| id, score = hit.doc, hit.score #puts hit.score puts "#{name_start}#{@index[id][:full_name]}#{name_end}" puts puts @index.highlight(query, id, :field => :content, :pre_tag => pre_tag, :post_tag => post_tag, :ellipsis => "...\n").to_s puts display.formatter.draw_line puts end puts "#{result.total_hits} hits" end p result.hits.map{|hit| @index[hit.doc][:full_name] } result end |
#time ⇒ Object
661 662 663 664 665 666 |
# File 'lib/ihelp.rb', line 661 def time t = Time.now rv = yield log "Took #{Time.now - t}" rv end |
#wrap(str) ⇒ Object
763 764 765 |
# File 'lib/ihelp.rb', line 763 def wrap(str) display.formatter.wrap(str) end |
#wrap_str(str) ⇒ Object
767 768 769 770 771 772 773 774 |
# File 'lib/ihelp.rb', line 767 def wrap_str(str) $stdout = StringIO.new wrap(str) $stdout.rewind s = $stdout.read $stdout = STDOUT s end |