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, *a) ⇒ 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.
598 599 600 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 |
# File 'lib/ihelp.rb', line 598 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.
585 586 587 |
# File 'lib/ihelp.rb', line 585 def reindex_when_needed @reindex_when_needed end |
Instance Attribute Details
#index ⇒ Object
The search index, is a Ferret::Index::Index
589 590 591 |
# File 'lib/ihelp.rb', line 589 def index @index end |
#log_level ⇒ Object
Returns the value of attribute log_level.
591 592 593 |
# File 'lib/ihelp.rb', line 591 def log_level @log_level end |
Instance Method Details
#all_names ⇒ Object
681 682 683 |
# File 'lib/ihelp.rb', line 681 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
667 668 669 |
# File 'lib/ihelp.rb', line 667 def already_indexed? full_name @index[full_name] end |
#display ⇒ Object
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 |
# File 'lib/ihelp.rb', line 739 def display return @display if @display @display = RI::Options.instance.displayer.clone 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
671 672 673 674 675 676 677 678 679 |
# File 'lib/ihelp.rb', line 671 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
773 774 775 |
# File 'lib/ihelp.rb', line 773 def init_display display end |
#log(str, level = 1) ⇒ Object
650 651 652 |
# File 'lib/ihelp.rb', line 650 def log str, level = 1 STDERR.puts str if level >= @log_level end |
#need_reindexing? ⇒ Boolean
685 686 687 |
# File 'lib/ihelp.rb', line 685 def need_reindexing? all_names.size > @index.size end |
#page(*a, &b) ⇒ Object
756 757 758 |
# File 'lib/ihelp.rb', line 756 def page(*a,&b) display.page(*a,&b) end |
#path ⇒ Object
654 655 656 |
# File 'lib/ihelp.rb', line 654 def path @index_path end |
#reindex! ⇒ Object
Reindexes any non-indexed help documents.
691 692 693 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 |
# File 'lib/ihelp.rb', line 691 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, *a) ⇒ Object
Searches for the terms in query and prints out first ten hits
See Ferret::QueryParser for query string format.
781 782 783 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 |
# File 'lib/ihelp.rb', line 781 def search(query, *a) result = @index.search(query, *a) 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 10" if result.total_hits > 10} ".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
658 659 660 661 662 663 |
# File 'lib/ihelp.rb', line 658 def time t = Time.now rv = yield log "Took #{Time.now - t}" rv end |
#wrap(str) ⇒ Object
760 761 762 |
# File 'lib/ihelp.rb', line 760 def wrap(str) display.formatter.wrap(str) end |
#wrap_str(str) ⇒ Object
764 765 766 767 768 769 770 771 |
# File 'lib/ihelp.rb', line 764 def wrap_str(str) $stdout = StringIO.new wrap(str) $stdout.rewind s = $stdout.read $stdout = STDOUT s end |