module CachySearch
Constants
- BASE_URL
- DEFAULT_LIMIT
- MAX_DESCRIPTION_LENGTH
- MAX_QUERY_LENGTH
- MIN_QUERY_LENGTH
- SEARCH_JSON
- USER_AGENT
Public Instance Methods
Source
# File lib/cachy_search.rb, line 50 def browse_url(query) "#{BASE_URL}/?search=#{CGI.escape(query.to_s.strip)}" end
Source
# File lib/cachy_search.rb, line 74 def dedupe_items(items) seen = {} items.filter do |item| key = [item[:name], item[:repo], item[:arch]] next false if seen[key] seen[key] = true true end end
Source
# File lib/cachy_search.rb, line 129 def default_fetch lambda do |url| RabbotHttp.fetch(url, user_agent: USER_AGENT) end end
Source
# File lib/cachy_search.rb, line 99 def fetch_json(url, fetch: nil) body = (fetch || default_fetch).call(url) JSON.parse(body) end
Source
# File lib/cachy_search.rb, line 122 def lookup(query, fetch: nil, limit: DEFAULT_LIMIT) SearchLookup.format( search(query, fetch: fetch, limit: limit), report: CachyReport ) end
Source
# File lib/cachy_search.rb, line 46 def package_url(repo:, arch:, name:) "#{BASE_URL}/package/#{repo}/#{arch}/#{name}/" end
Source
# File lib/cachy_search.rb, line 58 def parse_package(entry) name = entry["pkg_name"].to_s.strip repo = entry["repo_name"].to_s.strip arch = entry["pkg_arch"].to_s.strip return nil if name.empty? || repo.empty? || arch.empty? { name: name, version: entry["pkg_version"].to_s.strip, description: truncate_text(entry["pkg_desc"]), repo: repo, arch: arch, url: package_url(repo: repo, arch: arch, name: name) } end
Source
# File lib/cachy_search.rb, line 33 def parse_query(text) parsed = SearchQuery.parse(text, max_length: MAX_QUERY_LENGTH) return parsed.merge(too_short: false) if parsed[:empty] return { query: nil, empty: true, too_short: true } if parsed[:query].length < MIN_QUERY_LENGTH parsed.merge(too_short: false) end
Source
# File lib/cachy_search.rb, line 85 def parse_results(payload) data = payload.is_a?(String) ? JSON.parse(payload) : payload return { error: :fetch } unless data.is_a?(Hash) && data.key?("packages") entries = Array(data["exact_match"]) + Array(data["packages"]) results = dedupe_items(entries.filter_map { |entry| parse_package(entry) }) total = data["total_packages"].to_i total = results.length if total.zero? && results.any? { total: total, items: results } rescue StandardError { error: :fetch } end
Source
# File lib/cachy_search.rb, line 104 def search(query, fetch: nil, limit: DEFAULT_LIMIT) parsed = parse_query(query) return { error: :usage } if parsed[:empty] || parsed[:too_short] url = search_url(parsed[:query], limit: limit) payload = fetch_json(url, fetch: fetch) results = parse_results(payload) return { error: :fetch, query: parsed[:query] } if results[:error] { query: parsed[:query], total: results[:total], items: results[:items].first(limit) } rescue StandardError { error: :fetch, query: parsed&.dig(:query) || query.to_s.strip } end
Source
# File lib/cachy_search.rb, line 41 def search_url(query, limit: DEFAULT_LIMIT) keyword = CGI.escape(query.to_s.strip) "#{SEARCH_JSON}?search=#{keyword}&limit=#{limit}" end
Source
# File lib/cachy_search.rb, line 54 def truncate_text(text, max_length = MAX_DESCRIPTION_LENGTH) TextUtil.truncate(text, max_length) end
Source
# File lib/cachy_search.rb, line 29 def usage_message "Usage: !cachy <package name or keyword> — search CachyOS repositories (min 2 chars)" end