83 lines
2.6 KiB
Ruby
83 lines
2.6 KiB
Ruby
|
|
# 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
|