Files
redux-scraper/app/jobs/domain/user_avatar_job.rb
2025-08-16 05:17:26 +00:00

91 lines
2.4 KiB
Ruby

# typed: strict
# frozen_string_literal: true
class Domain::UserAvatarJob < Scraper::JobBase
queue_as :static_file
discard_on ActiveJob::DeserializationError
sig { override.returns(Symbol) }
def self.http_factory_method
:get_generic_http_client
end
sig { override.params(args: T::Hash[Symbol, T.untyped]).returns(T.untyped) }
def perform(args)
avatar = avatar_from_args!
logger.push_tags(make_arg_tag(avatar))
url_str = avatar.url_str
if url_str.blank?
logger.warn("avatar has no url_str")
return
end
response = http_client.get(url_str)
logger.tagged(make_arg_tag(response.log_entry)) do
self.first_log_entry ||= response.log_entry
avatar.last_log_entry = response.log_entry
return if check_bluesky_force_rescan?(response, avatar)
case response.status_code
when 200
avatar.state = "ok"
avatar.error_message = nil
avatar.downloaded_at = response.log_entry.created_at&.utc
avatar.log_entry = response.log_entry
logger.info("downloaded avatar")
when 404
avatar.state = "file_404"
avatar.error_message = "http #{response.status_code}"
logger.info("avatar 404")
else
avatar.state = "http_error"
avatar.error_message = "http #{response.status_code}"
fatal_error(
"http #{response.status_code}, log entry #{response.log_entry.id}",
)
end
end
ensure
if avatar
avatar.save!
user = avatar.user
user.touch if user
end
end
sig do
params(
response: Scraper::HttpClient::Response,
avatar: Domain::UserAvatar,
).returns(T::Boolean)
end
def check_bluesky_force_rescan?(response, avatar)
return false unless response.status_code == 400
unless avatar.url_str&.starts_with?(
"https://bsky.social/xrpc/com.atproto.sync.getBlob",
)
return false
end
data = JSON.parse(response.body)
# not the right error from bsky
return false unless data["error"] == "RepoDeactivated"
# already enqueued force rescan of user
return false if avatar.error_message == "RepoDeactivated"
logger.warn(format_tags("bsky blob 400, force rescan user"))
avatar.state = "http_error"
avatar.error_message = "RepoDeactivated"
avatar.save!
Domain::Bluesky::Job::ScanUserJob.perform_later(
user: avatar.user,
force_scan: true,
)
true
end
end