femslash-city/app/search.rb

83 lines
2.6 KiB
Ruby
Raw Permalink Normal View History

# frozen_string_literal: true
SEARCH_URL = $config['search_url']
SEARCH_CONNECT_TIMEOUT = $config['search_connect_timeout']
SEARCH_WRITE_TIMEOUT = $config['search_write_timeout']
SEARCH_READ_TIMEOUT = $config['search_read_timeout']
post '/search/?' do
query = params[:q].to_s.strip
redirect query.blank? ? '/search' : "/search?#{Rack::Utils.build_query(q: query)}"
end
get '/search/?' do
@query = params[:q].to_s.strip
@title = @query.blank? ? 'Neocities Search' : 'Site Search'
@description = 'Search websites hosted on Neocities.'
if !@query.blank?
@start = params[:start].to_i
@start = 0 if @start < 0
@items = []
@total_results = 0
begin
@resp = JSON.parse HTTP.timeout(connect: SEARCH_CONNECT_TIMEOUT, write: SEARCH_WRITE_TIMEOUT, read: SEARCH_READ_TIMEOUT).get(SEARCH_URL, params: {
num: 100,
start: @start,
q: Rack::Utils.escape(@query) + ' -filetype:pdf -filetype:txt site:*.neocities.org'
}).to_s
rescue HTTP::Error, JSON::ParserError
@resp = {}
end
if @resp.is_a?(Hash) && @resp['error'].nil? && @resp.dig('searchInformation', 'totalResults').to_i != 0
@total_results = @resp['searchInformation']['totalResults'].to_i
@resp['items'].each do |item|
link = Addressable::URI.parse(item['link'])
path = link.path || '/'
unencoded_path = begin
Rack::Utils.unescape(Rack::Utils.unescape(path)) # Yes, it needs to be decoded twice
rescue ArgumentError
path # Fall back when the path includes invalid %-encoding
end
item['unencoded_link'] = unencoded_path == '/' ? link.host : link.host+unencoded_path
item['link'] = link
next if link.host == 'neocities.org'
username = link.host.split('.').first
site = Site[username: username]
next if site.nil? || site.is_deleted || site.is_nsfw
item['username'] = username if site.profile_enabled
screenshot_path = unencoded_path
screenshot_path << 'index' if screenshot_path[-1] == '/'
if ENV['RACK_ENV'] == 'development'
screenshot_path += '.html'
screenshot_found = true
else
['.html', '.htm'].each do |ext|
if site.screenshot_exists?(screenshot_path + ext, '540x405')
screenshot_path += ext
screenshot_found = true
break
end
end
end
item['screenshot_url'] = site.screenshot_url(screenshot_path, '540x405')
@items << item if screenshot_found
end
end
else
@items = nil
@total_results = 0
end
erb :'search'
end