219 lines
5.8 KiB
Ruby
219 lines
5.8 KiB
Ruby
# typed: true
|
|
class Domain::Fa::ApiController < ApplicationController
|
|
skip_before_action :authenticate_user!
|
|
before_action :validate_api_token!
|
|
|
|
skip_before_action :verify_authenticity_token,
|
|
only: %i[enqueue_objects object_statuses similar_users]
|
|
|
|
skip_before_action :validate_api_token!,
|
|
only: %i[object_statuses similar_users]
|
|
|
|
def object_statuses
|
|
fa_ids = (params[:fa_ids] || []).reject(&:blank?).map(&:to_i)
|
|
url_names = (params[:url_names] || []).reject(&:blank?)
|
|
|
|
url_name_to_user =
|
|
Domain::User::FaUser
|
|
.where(url_name: url_names)
|
|
.map { |user| [T.must(user.url_name), user] }
|
|
.to_h
|
|
|
|
fa_id_to_post =
|
|
Domain::Post::FaPost
|
|
.includes(:file)
|
|
.where(fa_id: fa_ids)
|
|
.map { |post| [T.must(post.fa_id), post] }
|
|
.to_h
|
|
|
|
posts_response = {}
|
|
users_response = {}
|
|
|
|
fa_ids.each do |fa_id|
|
|
post = fa_id_to_post[fa_id]
|
|
|
|
if post
|
|
post_state =
|
|
if post.file.present?
|
|
"have_file"
|
|
elsif post.scanned_at?
|
|
"scanned_post"
|
|
else
|
|
post.state
|
|
end
|
|
|
|
post_response = {
|
|
state: post_state,
|
|
seen_at: time_ago_or_never(post.created_at),
|
|
object_url: request.base_url + helpers.domain_post_path(post),
|
|
post_scan: {
|
|
last_at: time_ago_or_never(post.scanned_at),
|
|
due_for_scan: !post.scanned_at?,
|
|
},
|
|
file_scan: {
|
|
last_at: time_ago_or_never(post.file&.created_at),
|
|
due_for_scan: !post.file&.created_at?,
|
|
},
|
|
}
|
|
else
|
|
post_response = { state: "not_seen" }
|
|
end
|
|
|
|
posts_response[fa_id] = post_response
|
|
end
|
|
|
|
url_names.each do |url_name|
|
|
user = url_name_to_user[url_name]
|
|
|
|
if user
|
|
user_response = {
|
|
created_at: time_ago_or_never(user.created_at),
|
|
state: user.state,
|
|
object_url: request.base_url + helpers.domain_user_path(user),
|
|
page_scan: {
|
|
last_at: time_ago_or_never(user.scanned_page_at),
|
|
due_for_scan: user.page_scan.due?,
|
|
},
|
|
gallery_scan: {
|
|
last_at: time_ago_or_never(user.gallery_scan.at),
|
|
due_for_scan: user.gallery_scan.due?,
|
|
},
|
|
favs_scan: {
|
|
last_at: time_ago_or_never(user.favs_scan.at),
|
|
due_for_scan: user.favs_scan.due?,
|
|
},
|
|
}
|
|
else
|
|
user_response = { state: "not_seen" }
|
|
end
|
|
users_response[url_name] = user_response
|
|
end
|
|
|
|
render json: { posts: posts_response, users: users_response }
|
|
end
|
|
|
|
def enqueue_objects
|
|
@enqueue_counts ||= Hash.new { |h, k| h[k] = 0 }
|
|
|
|
fa_ids = (params[:fa_ids] || []).map(&:to_i)
|
|
url_names = (params[:url_names] || [])
|
|
url_names_to_enqueue = Set.new(params[:url_names_to_enqueue] || [])
|
|
|
|
fa_id_to_post =
|
|
Domain::Fa::Post
|
|
.includes(:file)
|
|
.where(fa_id: fa_ids)
|
|
.map { |post| [post.fa_id, post] }
|
|
.to_h
|
|
|
|
url_name_to_user =
|
|
Domain::Fa::User
|
|
.where(url_name: url_names)
|
|
.map { |user| [user.url_name, user] }
|
|
.to_h
|
|
|
|
fa_ids.each do |fa_id|
|
|
post = fa_id_to_post[fa_id]
|
|
defer_post_scan(post, fa_id)
|
|
end
|
|
|
|
url_names.each do |url_name|
|
|
user = url_name_to_user[url_name]
|
|
defer_user_scan(user, url_name, url_names_to_enqueue.include?(url_name))
|
|
end
|
|
|
|
enqueue_deferred!
|
|
|
|
render json: {
|
|
post_scans: @enqueue_counts[Domain::Fa::Job::ScanPostJob],
|
|
post_files: @enqueue_counts[Domain::Fa::Job::ScanFileJob],
|
|
user_pages: @enqueue_counts[Domain::Fa::Job::UserPageJob],
|
|
user_galleries: @enqueue_counts[Domain::Fa::Job::UserGalleryJob],
|
|
}
|
|
end
|
|
|
|
private
|
|
|
|
def defer_post_scan(post, fa_id)
|
|
if !post || !post.scanned?
|
|
defer_manual(Domain::Fa::Job::ScanPostJob, { fa_id: fa_id }, -17)
|
|
end
|
|
|
|
if post && post.file_uri && !post.file.present?
|
|
return(
|
|
defer_manual(
|
|
Domain::Fa::Job::ScanFileJob,
|
|
{ post: post },
|
|
-15,
|
|
"static_file",
|
|
)
|
|
)
|
|
end
|
|
end
|
|
|
|
def defer_user_scan(user, url_name, highpri)
|
|
if !user || user.due_for_page_scan?
|
|
defer_manual(
|
|
Domain::Fa::Job::UserPageJob,
|
|
{ url_name: url_name },
|
|
highpri ? -16 : -6,
|
|
)
|
|
return
|
|
end
|
|
|
|
if !user || user.due_for_gallery_scan?
|
|
defer_manual(
|
|
Domain::Fa::Job::UserGalleryJob,
|
|
{ url_name: url_name },
|
|
highpri ? -14 : -4,
|
|
)
|
|
return
|
|
end
|
|
|
|
false
|
|
end
|
|
|
|
def defer_manual(klass, args, priority, queue = "manual")
|
|
@@enqueue_deduper ||= Set.new
|
|
return unless @@enqueue_deduper.add?([klass, args, priority])
|
|
|
|
@deferred_jobs ||= []
|
|
@deferred_jobs << [klass, args, priority, queue]
|
|
@enqueue_counts[klass] += 1
|
|
end
|
|
|
|
def enqueue_deferred!
|
|
GoodJob::Bulk.enqueue do
|
|
while job = (@deferred_jobs || []).shift
|
|
klass, args, priority, queue = job
|
|
klass.set(priority: priority, queue: queue).perform_later(args)
|
|
end
|
|
end
|
|
end
|
|
|
|
def time_ago_or_never(time)
|
|
if time
|
|
helpers.time_ago_in_words(time, include_seconds: true) + " ago"
|
|
else
|
|
"never"
|
|
end
|
|
end
|
|
|
|
API_TOKENS = {
|
|
"a4eb03ac-b33c-439c-9b51-a834d1c5cf48" => "dymk",
|
|
"56cc81fe-8c00-4436-8981-4580eab00e66" => "taargus",
|
|
"9c38727f-f11d-41de-b775-0effd86d520c" => "xjal",
|
|
"e38c568f-a24d-4f26-87f0-dfcd898a359d" => "fyacin",
|
|
"41fa1144-d4cd-11ed-afa1-0242ac120002" => "soft_fox_lad",
|
|
"9b3cf444-5913-4efb-9935-bf26501232ff" => "syfaro",
|
|
}
|
|
|
|
def validate_api_token!
|
|
api_token = request.params[:api_token]
|
|
api_user_name = API_TOKENS[api_token]
|
|
return if api_user_name
|
|
return if VpnOnlyRouteConstraint.new.matches?(request)
|
|
render status: 403, json: { error: "not authenticated" }
|
|
end
|
|
end
|