0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-05 23:04:22 +08:00
discourse/app/controllers/gifs_controller.rb
2026-07-08 17:18:42 +04:00

88 lines
2.2 KiB
Ruby
Vendored

# frozen_string_literal: true
class GifsController < ApplicationController
requires_login
KLIPY_CATEGORIES_URL = "https://api.klipy.com/v2/categories"
KLIPY_SEARCH_URL = "https://api.klipy.com/v2/search"
PAGE_SIZE = 24
MAX_QUERY_LENGTH = 100
MAX_REQUESTS_PER_10_SECONDS = 20
before_action :ensure_gifs_enabled
before_action :ensure_klipy_api_key
before_action :rate_limit
def categories
proxy_klipy_request(
KLIPY_CATEGORIES_URL,
{
"type" => "featured",
"country" => SiteSetting.klipy_country,
"locale" => SiteSetting.klipy_locale,
"contentfilter" => SiteSetting.klipy_content_filter,
},
)
end
def search
query = params.require(:q)
if !query.is_a?(String) || query.length > MAX_QUERY_LENGTH
raise Discourse::InvalidParameters.new(:q)
end
proxy_klipy_request(
KLIPY_SEARCH_URL,
{
"q" => query,
"country" => SiteSetting.klipy_country,
"locale" => SiteSetting.klipy_locale,
"contentfilter" => SiteSetting.klipy_content_filter,
"media_filter" => SiteSetting.klipy_file_detail,
"limit" => PAGE_SIZE,
"pos" => params[:pos].presence || "0",
},
)
end
private
def ensure_gifs_enabled
raise Discourse::NotFound if !SiteSetting.enable_gifs?
end
def ensure_klipy_api_key
head :forbidden if SiteSetting.klipy_api_key.blank?
end
def rate_limit
RateLimiter.new(current_user, "gif-search", MAX_REQUESTS_PER_10_SECONDS, 10.seconds).performed!
end
def proxy_klipy_request(url, query)
response =
Excon.get(
url,
headers: {
"Accept" => "application/json",
},
query: query.merge("key" => SiteSetting.klipy_api_key),
connect_timeout: 5,
read_timeout: 5,
)
render plain: redact_api_key(response.body.to_s),
status: response.status,
content_type: "application/json"
rescue Excon::Error
head :bad_gateway
end
def redact_api_key(body)
api_key = SiteSetting.klipy_api_key
return body if api_key.blank?
[api_key, CGI.escape(api_key)].uniq
.reduce(body) { |redacted_body, value| redacted_body.gsub(value, "[FILTERED]") }
end
end