Module: SL
- Includes:
- URL
- Defined in:
- lib/searchlink/url.rb,
lib/searchlink/help.rb,
lib/searchlink/util.rb,
lib/searchlink/parse.rb,
lib/searchlink/config.rb,
lib/searchlink/config.rb,
lib/searchlink/output.rb,
lib/searchlink/output.rb,
lib/searchlink/search.rb,
lib/searchlink/semver.rb,
lib/searchlink/string.rb,
lib/searchlink/version.rb,
lib/searchlink/version.rb,
lib/searchlink/searches.rb,
lib/searchlink/exceptions.rb,
lib/searchlink/script_plugin.rb,
lib/searchlink/searches/hook.rb,
lib/searchlink/searches/isgd.rb,
lib/searchlink/searches/tmdb.rb,
lib/searchlink/searches/bitly.rb,
lib/searchlink/searches/amazon.rb,
lib/searchlink/searches/github.rb,
lib/searchlink/searches/google.rb,
lib/searchlink/searches/itunes.rb,
lib/searchlink/searches/lastfm.rb,
lib/searchlink/searches/lyrics.rb,
lib/searchlink/searches/social.rb,
lib/searchlink/searches/history.rb,
lib/searchlink/searches/twitter.rb,
lib/searchlink/searches/youtube.rb,
lib/searchlink/searches/linkding.rb,
lib/searchlink/searches/pinboard.rb,
lib/searchlink/searches/software.rb,
lib/searchlink/searches/spelling.rb,
lib/searchlink/searches/spotlight.rb,
lib/searchlink/searches/wikipedia.rb,
lib/searchlink/searches/applemusic.rb,
lib/searchlink/searches/definition.rb,
lib/searchlink/searches/duckduckgo.rb,
lib/searchlink/searches/duckduckgo.rb,
lib/searchlink/searches/stackoverflow.rb,
lib/searchlink/searches/helpers/safari.rb,
lib/searchlink/searches/helpers/firefox.rb,
lib/searchlink/searches/helpers/chromium.rb
Overview
Chromium (Chrome, Arc, Brave, Edge) search methods
Defined Under Namespace
Modules: Searches, URL, Util Classes: AmazonSearch, AppleMusicSearch, BitlySearch, DefinitionSearch, DuckDuckGoSearch, GitHubSearch, GoogleSearch, HistorySearch, HookSearch, ITunesSearch, IsgdSearch, LastFMSearch, LinkdingSearch, LyricsSearch, PinboardSearch, PluginError, ScriptSearch, SearchLink, SemVer, SocialSearch, SoftwareSearch, SpellSearch, SpotlightSearch, StackOverflowSearch, TMDBSearch, TwitterSearch, VersionError, WikipediaSearch, YouTubeSearch
Constant Summary collapse
- VERSION =
'2.3.80'
Class Attribute Summary collapse
-
.clipboard ⇒ Object
Whether or not to copy results to clipbpard.
- .config ⇒ Object
-
.errors ⇒ Object
Stores generated errors.
-
.footer ⇒ Object
Stores the footer with reference links and footnotes.
-
.line_num ⇒ Object
Tracks the line number of each link match for debug output.
-
.match_column ⇒ Object
Tracks the column of each link match for debug output.
-
.match_length ⇒ Object
Tracks the length of each link match for debug output.
-
.originput ⇒ Object
Stores the original input.
-
.output ⇒ Object
Stores the generated output.
- .prev_config ⇒ Object
-
.printout ⇒ Object
Whether or not to echo results to STDOUT as they’re created.
-
.report ⇒ Object
Stores the generated debug report.
-
.titleize ⇒ Object
Whether or not to add a title to the output.
Class Method Summary collapse
-
.add_error(type, str) ⇒ nil
Adds the given string to the errors.
-
.add_footer(str) ⇒ nil
Adds the given string to the footer.
-
.add_output(str) ⇒ nil
Adds the given string to the output.
-
.add_report(str) ⇒ nil
Adds the given string to the report.
-
.ddg(search_terms, link_text = nil, timeout: , google: true, image: false) ⇒ SL::Searches::Result
Performs a DuckDuckGo search with the given search terms and link text.
- .first_image(url) ⇒ Object
-
.google(search_terms, link_text = nil, timeout: , image: false) ⇒ Object
Performs a Google search if API key is available, otherwise defaults to DuckDuckGo.
-
.make_link(type, text, url, title: false, force_title: false) ⇒ String
Creates a link of the specified type with the given text, url, and title.
-
.new_version? ⇒ Boolean
Check for a newer version than local copy using GitHub release tag.
-
.notify(title, subtitle) ⇒ Object
Posts macOS notifications.
-
.print_errors(type = "Errors") ⇒ String
Prints the errors.
-
.print_footer ⇒ String
Prints the footer.
-
.print_or_copy(text) ⇒ nil
Prints or copies the given text.
-
.print_report ⇒ String
Prints the report.
-
.site_search(site, search_terms, link_text) ⇒ Object
Perform a site-specific search.
- .spell(phrase) ⇒ Object
- .update_searchlink ⇒ Object
- .version_check ⇒ Object
Methods included from URL
amazon_affiliatize, only_url?, ref_title_for_url, title, url?, url_to_link, valid_link?
Class Attribute Details
.clipboard ⇒ Object
Whether or not to copy results to clipbpard
14 15 16 |
# File 'lib/searchlink/output.rb', line 14 def clipboard @clipboard ||= false end |
.config ⇒ Object
7 8 9 |
# File 'lib/searchlink/config.rb', line 7 def config @config ||= SL::SearchLink.new({ echo: true }) end |
.errors ⇒ Object
Stores generated errors
59 60 61 |
# File 'lib/searchlink/output.rb', line 59 def errors @errors ||= {} end |
.footer ⇒ Object
Stores the footer with reference links and footnotes
34 35 36 |
# File 'lib/searchlink/output.rb', line 34 def @footer ||= [] end |
.line_num ⇒ Object
Tracks the line number of each link match for debug output
39 40 41 |
# File 'lib/searchlink/output.rb', line 39 def line_num @line_num ||= 0 end |
.match_column ⇒ Object
Tracks the column of each link match for debug output
44 45 46 |
# File 'lib/searchlink/output.rb', line 44 def match_column @match_column ||= 0 end |
.match_length ⇒ Object
Tracks the length of each link match for debug output
49 50 51 |
# File 'lib/searchlink/output.rb', line 49 def match_length @match_length ||= 0 end |
.originput ⇒ Object
Stores the original input
54 55 56 |
# File 'lib/searchlink/output.rb', line 54 def originput @originput ||= "" end |
.output ⇒ Object
Stores the generated output
24 25 26 |
# File 'lib/searchlink/output.rb', line 24 def output @output ||= [] end |
.prev_config ⇒ Object
11 12 13 |
# File 'lib/searchlink/config.rb', line 11 def prev_config @prev_config ||= {} end |
.printout ⇒ Object
Whether or not to echo results to STDOUT as they’re created
19 20 21 |
# File 'lib/searchlink/output.rb', line 19 def printout @printout ||= false end |
.report ⇒ Object
Stores the generated debug report
29 30 31 |
# File 'lib/searchlink/output.rb', line 29 def report @report ||= [] end |
.titleize ⇒ Object
Whether or not to add a title to the output
9 10 11 |
# File 'lib/searchlink/output.rb', line 9 def titleize @titleize ||= false end |
Class Method Details
.add_error(type, str) ⇒ nil
Adds the given string to the errors.
193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/searchlink/output.rb', line 193 def add_error(type, str) return unless SL.config["debug"] unless SL.line_num.nil? position = "#{SL.line_num}:" position += SL.match_column.nil? ? "0:" : "#{SL.match_column}:" position += SL.match_length.nil? ? "0" : SL.match_length.to_s end SL.errors[type] ||= [] SL.errors[type].push("(#{position}): #{str}") end |
.add_footer(str) ⇒ nil
Adds the given string to the footer.
133 134 135 136 |
# File 'lib/searchlink/output.rb', line 133 def (str) SL. ||= [] SL..push(str.strip) end |
.add_output(str) ⇒ nil
Adds the given string to the output.
122 123 124 125 |
# File 'lib/searchlink/output.rb', line 122 def add_output(str) print str if SL.printout && !SL.clipboard SL.output << str end |
.add_report(str) ⇒ nil
Adds the given string to the report.
174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/searchlink/output.rb', line 174 def add_report(str) return unless SL.config["report"] unless SL.line_num.nil? position = "#{SL.line_num}:" position += SL.match_column.nil? ? "0:" : "#{SL.match_column}:" position += SL.match_length.nil? ? "0" : SL.match_length.to_s end SL.report.push("(#{position}): #{str}") warn "(#{position}): #{str}" unless SILENT end |
.ddg(search_terms, link_text = nil, timeout: , google: true, image: false) ⇒ SL::Searches::Result
Performs a DuckDuckGo search with the given search terms and link text. If link text is not provided, the first result will be returned. The search will timeout after the given number of seconds.
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/searchlink/searches/duckduckgo.rb', line 151 def ddg(search_terms, link_text = nil, timeout: SL.config["timeout"], google: true, image: false) if google && SL::GoogleSearch.api_key? s_class = "google" s_type = image ? "img" : "gg" else s_class = "duckduckgo" s_type = image ? "ddgimg" : "g" end search = proc { SL::Searches.plugins[:search][s_class][:class].search(s_type, search_terms, link_text) } SL::Util.search_with_timeout(search, timeout) end |
.first_image(url) ⇒ Object
175 176 177 178 |
# File 'lib/searchlink/searches/duckduckgo.rb', line 175 def first_image(url) images = Curl::Html.new(url).images images.filter { |img| img[:type] == "img" }.first[:src] end |
.google(search_terms, link_text = nil, timeout: , image: false) ⇒ Object
Performs a Google search if API key is available, otherwise defaults to DuckDuckGo
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/searchlink/searches/duckduckgo.rb', line 128 def google(search_terms, link_text = nil, timeout: SL.config["timeout"], image: false) if SL::GoogleSearch.api_key? s_class = "google" s_type = image ? "img" : "gg" else s_class = "duckduckgo" s_type = image ? "ddgimg" : "g" end search = proc { SL::Searches.plugins[:search][s_class][:class].search(s_type, search_terms, link_text) } SL::Util.search_with_timeout(search, timeout) end |
.make_link(type, text, url, title: false, force_title: false) ⇒ String
Creates a link of the specified type with the given text, url, and title.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/searchlink/output.rb', line 97 def make_link(type, text, url, title: false, force_title: false) title = title.gsub(/\P{Print}|\p{Cf}/, "") if title text = title || SL::URL.title(url) if SL.titleize && (!text || text.strip.empty?) text = text ? text.strip : title title = title && (SL.config["include_titles"] || force_title) ? %( "#{title.clean}") : "" title = title.gsub(/[ \t]+/, " ") case type.to_sym when :ref_title %(\n[#{text}]: #{url}#{title}) when :ref_link %([#{text}][#{url}]) when :inline image = url =~ /\.(gif|jpe?g|png|webp)$/ ? "!" : "" %(#{image}[#{text}](#{url}#{title})) end end |
.new_version? ⇒ Boolean
Check for a newer version than local copy using GitHub release tag
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/searchlink/version.rb', line 42 def new_version? headers = { "Accept" => "application/vnd.github+json", "X-GitHub-Api-Version" => "2022-11-28", } headers["Authorization"] = "Bearer #{Secrets::GH_AUTH_TOKEN}" if defined? Secrets::GH_AUTH_TOKEN url = "https://api.github.com/repos/ttscoff/searchlink/releases/latest" page = Curl::Json.new(url, headers: headers) result = page.json if result latest_tag = result["tag_name"] return false unless latest_tag return false if latest_tag =~ /^#{Regexp.escape(SL::VERSION)}$/ latest = SemVer.new(latest_tag) current = SemVer.new(SL::VERSION) return latest_tag if current.older_than(latest) else warn "Check for new version failed." end false end |
.notify(title, subtitle) ⇒ Object
Posts macOS notifications
68 69 70 71 72 73 74 75 |
# File 'lib/searchlink/output.rb', line 68 def notify(title, subtitle) return unless SL.config["notifications"] title = title.gsub(/"/, '\\"') subtitle = subtitle.gsub(/"/, '\\"') `osascript -e 'display notification "SearchLink" with title "#{title}" subtitle "#{subtitle}"'` end |
.print_errors(type = "Errors") ⇒ String
Prints the errors.
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/searchlink/output.rb', line 224 def print_errors(type = "Errors") return if SL.errors.empty? out = "" inline = if SL.originput.split(/\n/).length > 1 false else SL.config["inline"] || SL.originput.split(/\n/).length == 1 end SL.errors.each do |k, v| next if v.empty? v.each_with_index do |err, i| out += "(#{k}) #{err}" out += if inline i == v.length - 1 ? " | " : ", " else "\n" end end end unless out == "" sep = inline ? " " : "\n" out.sub!(/\| /, "") out = "#{sep}<!-- #{type}:#{sep}#{out}-->#{sep}" end if SL.clipboard warn out else add_output out end end |
.print_footer ⇒ String
Prints the footer.
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/searchlink/output.rb', line 142 def unless SL..empty? footnotes = [] SL..delete_if do |note| note.strip! case note when /^\[\^.+?\]/ footnotes.push(note) true when /^\s*$/ true else false end end output = SL..sort.join("\n").strip output += "\n\n" if !output.empty? && !footnotes.empty? output += footnotes.join("\n\n") unless footnotes.empty? return output.gsub(/\n{3,}/, "\n\n") end "" end |
.print_or_copy(text) ⇒ nil
Prints or copies the given text.
265 266 267 268 269 270 271 272 273 |
# File 'lib/searchlink/output.rb', line 265 def print_or_copy(text) # Process.exit unless text if SL.clipboard `echo #{Shellwords.escape(text)}|tr -d "\n"|pbcopy` print SL.originput else print text end end |
.print_report ⇒ String
Prints the report.
209 210 211 212 213 214 215 216 |
# File 'lib/searchlink/output.rb', line 209 def print_report return if (SL.config["inline"] && SL.originput.split(/\n/).length == 1) || SL.clipboard return if SL.report.empty? out = "\n<!-- Report:\n#{SL.report.join("\n")}\n-->\n" add_output out end |
.site_search(site, search_terms, link_text) ⇒ Object
Perform a site-specific search
171 172 173 |
# File 'lib/searchlink/searches/duckduckgo.rb', line 171 def site_search(site, search_terms, link_text) ddg("site:#{site} #{search_terms}", link_text) end |
.spell(phrase) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/searchlink/searches/spelling.rb', line 28 def spell(phrase) aspell = if File.exist?("/usr/local/bin/aspell") "/usr/local/bin/aspell" elsif File.exist?("/opt/homebrew/bin/aspell") "/opt/homebrew/bin/aspell" else `which aspell`.strip end if aspell.nil? || aspell.empty? SL.add_error("Missing aspell", "Install aspell in to allow spelling corrections") return false end words = phrase.split(/\b/) output = "" words.each do |w| if w =~ /[A-Za-z]+/ spell_res = `echo "#{w}" | #{aspell} --sug-mode=bad-spellers -C pipe | head -n 2 | tail -n 1` if spell_res.strip == "\*" output += w else spell_res.sub!(/.*?: /, "") results = spell_res.split(/, /).delete_if { |word| phrase =~ /^[a-z]/ && word =~ /[A-Z]/ } output += results[0] end else output += w end end output end |
.update_searchlink ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/searchlink/version.rb', line 71 def update_searchlink if `uname`.strip !~ /Darwin/ add_output("Auto updating only available on macOS") return end new_version = SL.new_version? if new_version folder = File.("~/Downloads") services = File.("~/Library/Services") dl = File.join(folder, "SearchLink.zip") curl = TTY::Which.which("curl") `#{curl} -SsL -o "#{dl}" https://github.com/ttscoff/searchlink/releases/latest/download/SearchLink.zip` Dir.chdir(folder) `unzip -qo #{dl} -d #{folder}` FileUtils.rm(dl) ["SearchLink", "SearchLink File", "Jump to SearchLink Error"].each do |workflow| wflow = "#{workflow}.workflow" src = File.join(folder, "SearchLink Services", wflow) dest = File.join(services, wflow) if File.exist?(src) && File.exist?(dest) FileUtils.rm_rf(dest) FileUtils.mv(src, dest, force: true) end end add_output("Installed SearchLink #{new_version}") FileUtils.rm_rf("SearchLink Services") else add_output("Already up to date.") end end |
.version_check ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/searchlink/version.rb', line 10 def version_check cachefile = File.("~/.config/searchlink/cache/update.txt") FileUtils.mkdir_p(File.dirname(cachefile)) unless File.directory?(File.dirname(cachefile)) if File.exist?(cachefile) last_check, latest_tag = IO.read(cachefile).strip.split(/\|/) last_time = Time.parse(last_check) else latest_tag = new_version? last_time = Time.now end if last_time + (24 * 60 * 60) < Time.now latest_tag = new_version? last_time = Time.now end latest_tag ||= SL::VERSION latest = SemVer.new(latest_tag) current = SemVer.new(SL::VERSION) File.open(cachefile, "w") { |f| f.puts("#{last_time.strftime("%c")}|#{latest}") } return "SearchLink v#{current}, #{latest} available. Run \"update\" to download." if latest_tag && current.older_than(latest) "SearchLink v#{current}" end |