- Create PostFiles top-level component managing file display state - Add FileCarousel component for thumbnail navigation - Add DisplayedFile component for content rendering - Add FileDetails component for metadata display - Update props_for_post_files helper to generate HTML content server-side - Replace HTML/JS carousel with prerendered React components - Maintain single file layout compatibility - Add proper TypeScript interfaces and error handling - Register components in application and server bundles Components now handle: - Multiple file carousel display above content - File content switching via React state - Server-side rendered HTML injection - File details metadata display - Responsive thumbnail grid with selection states
146 lines
3.7 KiB
Ruby
146 lines
3.7 KiB
Ruby
# typed: true
|
|
class Scraper::ClientFactory
|
|
extend T::Sig
|
|
|
|
@http_clients = Concurrent::ThreadLocalVar.new() { {} }
|
|
@gallery_dl_clients = Concurrent::ThreadLocalVar.new(nil)
|
|
|
|
# for testing only
|
|
sig { params(mock: T.nilable(Scraper::HttpClient)).void }
|
|
def self.http_client_mock=(mock)
|
|
raise unless Rails.env.test?
|
|
@http_client_mock = mock
|
|
end
|
|
|
|
sig { returns(T.nilable(Scraper::HttpClient)) }
|
|
def self.http_client_mock
|
|
raise unless Rails.env.test?
|
|
@http_client_mock
|
|
end
|
|
|
|
def self.gallery_dl_client_mock=(mock)
|
|
raise unless Rails.env.test?
|
|
@gallery_dl_client_mock = mock
|
|
end
|
|
|
|
# public API
|
|
def self.get_gallery_dl_client
|
|
# TODO - can probably allow development to hit real websites
|
|
if Rails.env.test? || Rails.env.development?
|
|
@gallery_dl_client_mock || raise("no gallery dl mock set")
|
|
else
|
|
_gallery_dl_client_impl
|
|
end
|
|
end
|
|
|
|
def self.get_twitter_http_client
|
|
if Rails.env.test? || Rails.env.development?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(:twitter, Scraper::TwitterHttpClientConfig)
|
|
end
|
|
end
|
|
|
|
def self.get_generic_http_client
|
|
if Rails.env.test?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(:generic, Scraper::GenericHttpClientConfig)
|
|
end
|
|
end
|
|
|
|
def self.get_fa_http_client
|
|
if Rails.env.test?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(:fa, Scraper::FaHttpClientConfig)
|
|
end
|
|
end
|
|
|
|
def self.get_fuzzysearch_http_client
|
|
if Rails.env.test?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(:fuzzysearch, Scraper::FuzzysearchHttpClientConfig)
|
|
end
|
|
end
|
|
|
|
def self.get_sofurry_http_client
|
|
if Rails.env.test?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(:sofurry, Scraper::SofurryHttpClientConfig)
|
|
end
|
|
end
|
|
|
|
def self.get_e621_http_client
|
|
if Rails.env.test?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(:e621, Scraper::E621HttpClientConfig)
|
|
end
|
|
end
|
|
|
|
def self.get_inkbunny_http_client
|
|
if Rails.env.test?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(:inkbunny, Scraper::InkbunnyHttpClientConfig)
|
|
end
|
|
end
|
|
|
|
def self.get_fur_archiver_http_client
|
|
if Rails.env.test?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(:fur_archiver, Scraper::FurArchiverHttpClientConfig)
|
|
end
|
|
end
|
|
|
|
def self.get_tor_http_client
|
|
if Rails.env.test?
|
|
@http_client_mock || raise("no http client mock set")
|
|
else
|
|
_http_client_impl(
|
|
:tor,
|
|
Scraper::TorHttpClientConfig,
|
|
Scraper::TorCurlHttpPerformer,
|
|
)
|
|
end
|
|
end
|
|
|
|
def self._gallery_dl_client_impl
|
|
@gallery_dl_clients.value ||=
|
|
begin
|
|
proxy_config =
|
|
Rails.application.config.x.proxy || raise("no proxy config")
|
|
if proxy_config[:gallery_dl].blank?
|
|
raise(
|
|
"no gallery_dl host defined for proxy config #{proxy_config[:name]}",
|
|
)
|
|
end
|
|
Scraper::GalleryDlClient.new(
|
|
proxy_config[:name],
|
|
proxy_config[:gallery_dl],
|
|
)
|
|
end
|
|
end
|
|
|
|
sig do
|
|
params(
|
|
key: Symbol,
|
|
config_klass: T.class_of(Scraper::HttpClientConfig),
|
|
performer_klass: T.class_of(Scraper::CurlHttpPerformer),
|
|
).returns(Scraper::HttpClient)
|
|
end
|
|
def self._http_client_impl(
|
|
key,
|
|
config_klass,
|
|
performer_klass = Scraper::CurlHttpPerformer
|
|
)
|
|
@http_clients.value[key] ||= begin
|
|
Scraper::HttpClient.new(config_klass.new, performer_klass.new)
|
|
end
|
|
end
|
|
end
|