Files
redux-scraper/app/controllers/domain/fa/posts_controller.rb
2024-12-25 21:53:47 +00:00

130 lines
3.4 KiB
Ruby

class Domain::Fa::PostsController < ApplicationController
before_action :set_domain_fa_post, only: %i[show scan_post]
skip_before_action :verify_authenticity_token,
only: %i[try_scan_post try_scan_posts]
# GET /domain/fa/posts
def index
if params[:user_url_name]
@user =
Domain::Fa::User.find_by(url_name: params[:user_url_name]) ||
raise(ActiveRecord::RecordNotFound)
end
relation = @user ? @user.posts : Domain::Fa::Post
@posts =
relation
.includes(:creator, :file)
.page(params[:page])
.per(50)
.order(fa_id: :desc)
.without_count
end
# GET /domain/fa/posts/1
def show
end
def scan_post
if try_enqueue_post_scan(@post, @post.fa_id)
redirect_to domain_fa_post_path(@post.fa_id), notice: "Enqueued for scan"
else
redirect_to domain_fa_post_path(@post.fa_id), notice: "Already scanned"
end
end
def try_scan_post
fa_id = params[:fa_id]&.to_i || raise("need fa_id parameter")
post = Domain::Fa::Post.find_by_fa_id(fa_id)
enqueued = try_enqueue_post_scan(post, fa_id)
if post && post.file.present?
state_string =
"downloaded #{helpers.time_ago_in_words(post.file.created_at, include_seconds: true)} ago"
elsif post && post.scanned?
state_string =
"scanned #{helpers.time_ago_in_words(post.scanned_at, include_seconds: true)} ago"
else
state_string = []
!post ? state_string << "not seen" : state_string << "#{post.state}"
state_string << "enqueued" if enqueued
state_string = state_string.join(", ")
end
render json: {
enqueued: enqueued,
title: post&.title,
state: state_string,
is_terminal_state: post&.scanned? && post&.file&.present? || false,
}
end
def try_scan_posts
Rails.logger.info "params: #{params.inspect}"
fa_ids = params[:fa_ids].map(&:to_i)
fa_id_to_post =
Domain::Fa::Post
.where(fa_id: fa_ids)
.map { |post| [post.fa_id, post] }
.to_h
response = {}
fa_ids.each do |fa_id|
post = fa_id_to_post[fa_id]
if post.nil?
state = "not_seen"
elsif post.file.present?
state = "have_file"
elsif post.scanned?
state = "scanned"
else
state = "state_#{post.state}"
end
response[fa_id] = {
state: state,
enqueued: try_enqueue_post_scan(post, fa_id),
}
end
render json: response
end
private
def try_enqueue_post_scan(post, fa_id)
@@already_enqueued_fa_ids ||= Set.new
unless @@already_enqueued_fa_ids.add?(fa_id)
Rails.logger.info "Already enqueued #{fa_id}, skipping"
return false
end
if !post || !post.scanned?
Rails.logger.info "Enqueue scan #{fa_id}"
Domain::Fa::Job::ScanPostJob.set(
priority: -15,
queue: "manual",
).perform_later({ fa_id: fa_id })
return true
end
if post && post.file_uri && !post.file.present?
Rails.logger.info "Enqueue file #{fa_id}"
Domain::Fa::Job::ScanFileJob.set(
priority: -15,
queue: "manual",
).perform_later({ post: post })
return true
end
false
end
# Use callbacks to share common setup or constraints between actions.
def set_domain_fa_post
@post = Domain::Fa::Post.find_by_fa_id!(params[:fa_id])
end
end