remove old domain views, controllers

This commit is contained in:
Dylan Knutson
2025-02-27 21:22:26 +00:00
parent 8c2593b414
commit bfbbf5d7d4
49 changed files with 32 additions and 1598 deletions

View File

@@ -1,6 +0,0 @@
# typed: true
class Domain::E621::PostsController < ApplicationController
def show
@post = Domain::E621::Post.find_by!(e621_id: params[:e621_id])
end
end

View File

@@ -7,18 +7,7 @@ class Domain::Fa::ApiController < ApplicationController
only: %i[enqueue_objects object_statuses similar_users]
skip_before_action :validate_api_token!,
only: %i[search_user_names object_statuses similar_users]
def search_user_names
name = params[:name]
limit = (params[:limit] || 5).to_i.clamp(0, 15)
users = users_for_name(name, limit: limit)
if !Rails.env.production? && name == "error"
render status: 500, json: { error: "an error!" }
else
render json: { users: users }
end
end
only: %i[object_statuses similar_users]
def object_statuses
fa_ids = (params[:fa_ids] || []).reject(&:blank?).map(&:to_i)
@@ -298,37 +287,6 @@ class Domain::Fa::ApiController < ApplicationController
end
end
def users_for_name(name, limit: 10)
users =
Domain::Fa::User
.where(
[
"(name ilike :name) OR (url_name ilike :name)",
{ name: "#{ReduxApplicationRecord.sanitize_sql_like(name)}%" },
],
)
.includes(:avatar)
.select(:id, :state, :state_detail, :log_entry_detail, :name, :url_name)
.select(
"(SELECT COUNT(*) FROM domain_fa_posts WHERE creator_id = domain_fa_users.id) as num_posts",
)
.order(name: :asc)
.limit(limit)
users.map do |user|
{
id: user.id,
name: user.name,
url_name: user.url_name,
thumb: helpers.fa_user_avatar_path(user, thumb: "64-avatar"),
show_path: domain_fa_user_path(user.url_name),
# `num_posts` is a manually added column, so we need to use T.unsafe to
# access it
num_posts: T.unsafe(user).num_posts,
}
end
end
sig do
params(users_list: T::Array[Domain::User::FaUser]).returns(
T::Array[T::Hash[Symbol, T.untyped]],

View File

@@ -1,139 +0,0 @@
# typed: true
class Domain::Fa::PostsController < ApplicationController
before_action :set_ivfflat_probes!, only: %i[show]
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]
skip_before_action :authenticate_user!, only: %i[show index]
# This action is always scoped to a user, so the :user_url_name parameter is required.
# GET /domain/fa/users/:user_url_name/posts
def index
@user = Domain::Fa::User.find_by!(url_name: params[:user_url_name])
relation = policy_scope(@user.posts)
@posts =
relation
.includes(:creator, :file)
.order(fa_id: :desc)
.page(params[:page])
.per(50)
.without_count
end
# GET /domain/fa/posts/:fa_id
def show
end
# GET /domain/fa/posts/:fa_id/favorites
def favorites
@post = Domain::Fa::Post.find_by!(fa_id: params[:fa_id])
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 && (file = post.file).present? && created_at = file.created_at
state_string =
"downloaded #{helpers.time_ago_in_words(created_at, include_seconds: true)} ago"
elsif post && post.scanned? && scanned_at = post.scanned_at
state_string =
"scanned #{helpers.time_ago_in_words(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.includes(:creator, file: :response).find_by!(
fa_id: params[:fa_id],
)
end
end

View File

@@ -1,28 +0,0 @@
# typed: true
class Domain::Fa::UsersController < ApplicationController
before_action :set_ivfflat_probes!, only: %i[show]
before_action :set_user, only: %i[show]
skip_before_action :authenticate_user!, only: %i[show]
# GET /domain/fa/users or /domain/fa/users.json
def index
authorize Domain::Fa::User
@users =
policy_scope(Domain::Fa::User).includes({ avatar: [:file] }).page(
params[:page],
)
end
# GET /domain/fa/users/1 or /domain/fa/users/1.json
def show
authorize @user
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = Domain::Fa::User.find_by(url_name: params[:url_name])
end
end

View File

@@ -1,19 +0,0 @@
# typed: false
class Domain::Inkbunny::PostsController < ApplicationController
skip_before_action :authenticate_user!, only: %i[show index]
def index
relation = Domain::Inkbunny::Post.includes(:creator, :files)
if params[:user_id].present?
@user = Domain::Inkbunny::User.find(params[:user_id])
relation = relation.where(creator: @user)
end
@posts = relation.order(ib_post_id: :desc).page(params[:page]).per(50)
end
def show
@post = Domain::Inkbunny::Post.find_by!(ib_post_id: params[:ib_post_id])
end
end

View File

@@ -1,6 +0,0 @@
# typed: true
class Domain::Inkbunny::UsersController < ApplicationController
def show
@user = Domain::Inkbunny::User.find_by(name: params[:name])
end
end

View File

@@ -1,13 +0,0 @@
# typed: false
class IndexedPostsController < ApplicationController
def index
@posts = IndexedPost.all
active_sources = (params[:sources] || SourceHelper.all_source_names)
unless SourceHelper.has_all_sources?(active_sources)
postable_types = SourceHelper.source_names_to_class_names(active_sources)
@posts =
@posts.where(postable_type: postable_types) if postable_types.any?
end
@posts = @posts.order(created_at: :desc).page(params[:page]).per(50)
end
end

View File

@@ -1,5 +1,7 @@
# typed: false
module Domain::Fa::UsersHelper
extend T::Sig
def avatar_url(sha256, thumb: "32-avatar")
blob_path(HexUtil.bin2hex(sha256), format: "jpg", thumb: thumb)
end
@@ -87,38 +89,31 @@ module Domain::Fa::UsersHelper
end
# TODO - remove this once we've migrated similarity scores to new user model
sig do
params(
user: Domain::User::FaUser,
limit: Integer,
exclude_followed_by: T.nilable(Domain::User::FaUser),
).returns(T::Array[Domain::User::FaUser])
end
def similar_users_by_followed(user, limit: 10, exclude_followed_by: nil)
old_user = Domain::Fa::User.find_by(url_name: user.url_name)
old_exclude_user =
(
if exclude_followed_by
Domain::Fa::User.find_by(url_name: exclude_followed_by.url_name)
else
nil
end
)
factors = Domain::Factors::UserUserFollowToFactors.find_by(user: user)
return [] if factors.nil?
ReduxApplicationRecord.connection.execute("SET ivfflat.probes = 32")
return nil if old_user.nil?
if old_user.disco.nil?
nil
else
ReduxApplicationRecord.connection.execute("SET ivfflat.probes = 32")
old_users =
old_user.similar_users_by_followed(
exclude_followed_by: old_exclude_user,
).limit(limit)
old_user_url_names = old_users.map(&:url_name)
new_users = Domain::User::FaUser.where(url_name: old_user_url_names).to_a
# return in same order as old_users
old_users
.map do |old_user|
new_users.find { |new_user| new_user.url_name == old_user.url_name }
end
.compact
relation =
factors
.nearest_neighbors(:embedding, distance: "euclidean")
.limit(limit)
.includes(:user)
if exclude_followed_by
relation =
relation.where.not(
user_id: exclude_followed_by.followed_users.select(:to_id),
)
end
relation.map { |factor| factor.user }
end
def fa_user_account_status(user)

View File

@@ -1,22 +0,0 @@
# typed: false
module IndexablePostsHelper
def show_path(indexed_post)
case indexed_post.postable_type
when "Domain::Fa::Post"
# need to use the helper here because the postable is not loaded
Rails.application.routes.url_helpers.domain_fa_post_path(
indexed_post.postable,
)
when "Domain::E621::Post"
Rails.application.routes.url_helpers.domain_e621_post_path(
indexed_post.postable,
)
when "Domain::Inkbunny::Post"
Rails.application.routes.url_helpers.domain_inkbunny_post_path(
indexed_post.postable,
)
else
raise("Unsupported postable type: #{indexed_post.postable_type}")
end
end
end

View File

@@ -1,108 +0,0 @@
<div class="mx-auto mt-4 flex w-full flex-col gap-4 pb-4 md:max-w-2xl">
<section class="border border-slate-300 bg-slate-50 p-4 md:rounded-md">
<div class="flex items-center justify-between">
<div>
<span class="text-md italic">
<%= link_to "E621 Post ##{@post.e621_id}",
"https://e621.net/posts/#{@post.e621_id}",
class: "text-blue-600 hover:underline",
target: "_blank" %>
</span>
<% if @post.artists_array.any? %>
<span class="ml-2 italic"
>by <%= @post.artists_array.join(", ") %></span
>
<% end %>
</div>
<i class="fa-solid fa-arrow-up-right-from-square text-slate-400"></i>
</div>
<% new_post = Domain::Post::E621Post.find_by(e621_id: @post.e621_id) %>
<% if new_post %>
<div class="py-2">
<%= link_to "Go to new post",
domain_post_path(new_post),
class: "text-white bg-blue-500 hover:bg-blue-800 transition-colors duration-200 px-4 py-2 rounded-md shadow hover:shadow-lg" %>
</div>
<% end %>
<div class="mt-2 flex flex-wrap gap-x-4 text-sm text-slate-600">
<span
><i class="fa-solid fa-star mr-1"></i>Score: <%= @post.score %></span
>
<span
><i class="fa-solid fa-tag mr-1"></i>Rating:
<%= @post.rating&.upcase || "Unknown" %></span
>
<span>
<i class="fa-regular fa-calendar mr-1"></i>
Created: <%= @post.created_at.strftime("%Y-%m-%d") %>
(<%= time_ago_in_words(@post.created_at) %> ago)
</span>
</div>
</section>
<section>
<% if @post.file %>
<%= render partial: "log_entries/content_container",
locals: {
log_entry: @post.file,
} %>
<% else %>
<div class="p-4 text-center italic text-slate-400">No file available</div>
<% end %>
</section>
<section class="sky-section">
<div class="section-header">Post Description</div>
<% if @post.description.present? %>
<div class="bg-slate-800 p-4 text-slate-200">
<%= simple_format(@post.description) %>
</div>
<% else %>
<div class="bg-slate-50 p-4 text-center italic text-slate-400">
No description
</div>
<% end %>
</section>
<section class="sky-section">
<div class="section-header">Tags</div>
<div class="bg-slate-100 p-4">
<% if @post.tags_array.any? %>
<% tags_array =
(
if @post.tags_array.is_a?(Hash)
@post.tags_array
else
{ "general" => @post.tags_array }
end
) %>
<div class="flex flex-wrap gap-2">
<% tag_category_order.each do |category| %>
<% (tags_array[category.to_s] || []).each do |tag| %>
<span
class="<%= tag_category_tw_class(category) %> rounded px-2 py-1 text-sm text-slate-600"
>
<% icon = font_awesome_category_icon(category) %>
<% if icon %>
<i class="fa-solid <%= icon %> mr-1"></i>
<% end %>
<%= tag %>
</span>
<% end %>
<% end %>
</div>
<% else %>
<div class="text-center italic text-slate-400">No tags</div>
<% end %>
</div>
</section>
<% if @post.sources_array.any? %>
<section class="sky-section">
<div class="section-header">Sources</div>
<div class="bg-slate-100 p-4">
<div class="divide-y divide-slate-200">
<% @post.sources_array.each do |source| %>
<%= render partial: "domain/e621/posts/source_link", locals: { source: source } %>
<% end %>
</div>
</div>
</section>
<% end %>
</div>

View File

@@ -1,19 +0,0 @@
<div class="flex items-start gap-2 py-1 first:pt-0 last:pb-0">
<% if icon_path = icon_asset_for_url(source) %>
<%= image_tag icon_path, class: "h-4 w-4 mt-1 flex-shrink-0" %>
<% else %>
<i class="fa-solid fa-link mt-1 h-4 w-4 flex-shrink-0"></i>
<% end %>
<%= link_to source,
source,
class: "text-blue-600 hover:underline truncate",
target: "_blank" %>
<% fa_post = fa_post_for_source(source) %>
<% if fa_post %>
<%= link_to domain_fa_post_path(fa_post.fa_id),
class:
"float-right inline-flex items-center gap-2 rounded bg-blue-600 px-3 py-1 text-sm text-white hover:bg-blue-700" do %>
<span class="truncate"><%= fa_post.title %></span>
<% end %>
<% end %>
</div>

View File

@@ -1,2 +0,0 @@
<p style="color: green"><%= notice %></p>
<%= render @post %>

View File

@@ -1,32 +0,0 @@
json.user do
json.name @user.name
json.full_name @user.full_name
json.url_name @user.url_name
json.state @user.state
json.log_entry_detail @user.log_entry_detail
if @user.log_entry_detail["last_user_page_id"]
json.user_page_log_entry do
json.partial! "log_entries/show",
locals: {
log_entry:
HttpLogEntry.find(
@user.log_entry_detail["last_user_page_id"],
),
}
end
end
json.user_stats do
json.num_pageviews @user.num_pageviews
json.num_submissions @user.num_submissions
json.num_comments_recieved @user.num_comments_recieved
json.num_comments_given @user.num_comments_given
json.num_journals @user.num_journals
json.num_favorites @user.num_favorites
end
json.created_at @user.created_at
json.updated_at @user.updated_at
end

View File

@@ -1,6 +0,0 @@
<%= link_to domain_fa_post_path(post),
class:
"text-sky-200 transition-all hover:text-sky-800 inline-flex items-center hover:bg-gray-100 rounded-md gap-1 px-1" do %>
<i class="fa-regular fa-image h-4 w-4 flex-shrink-0"></i>
<span><%= post.title %></span>
<% end %>

View File

@@ -1,10 +0,0 @@
<%= link_to domain_fa_user_path(user),
class:
"text-sky-200 transition-all hover:text-sky-800 inline-flex items-center hover:bg-gray-100 rounded-md gap-1 px-1 align-bottom" do %>
<img
src="<%= fa_user_avatar_path(user, thumb: "32-avatar") %>"
class="inline-block h-4 w-4 flex-shrink-0 rounded-sm object-cover"
alt="<%= user.name %>'s avatar"
/>
<span><%= user.name %></span>
<% end %>

View File

@@ -1,15 +0,0 @@
<tr>
<td><%= time_ago_in_words(post.created_at) %> ago</td>
<td><%= post.scanned_at && time_ago_in_words(post.scanned_at) || "(never)" %></td>
<td><%= post.file && time_ago_in_words(post.file.created_at) || "(never)" %></td>
<td><%= post_state_string(post) %></td>
<td><%= link_to post.fa_id, domain_fa_post_path(post.fa_id) %></td>
<td><%= post.title %></td>
<td>
<% if post.creator %>
<%= link_to post.creator.name, post.creator %>
<% else %>
No creator
<% end %>
</td>
</tr>

View File

@@ -1,118 +0,0 @@
<div class="mx-auto mt-4 flex w-full max-w-2xl flex-col gap-4 pb-4">
<section class="rounded-md border border-slate-300 bg-slate-50 p-4">
<div class="flex items-center justify-between gap-4">
<div class="flex min-w-0 items-center gap-4">
<div class="flex min-w-0 items-center gap-2">
<span class="truncate text-lg font-medium">
<%= link_to @post.title,
"https://www.furaffinity.net/view/#{@post.fa_id}",
class: "text-blue-600 hover:underline",
target: "_blank" %>
</span>
<i class="fa-solid fa-arrow-up-right-from-square text-slate-400"></i>
</div>
<div class="flex items-center gap-2 whitespace-nowrap text-slate-600">
by
<%= render "domain/fa/users/inline_link",
user: @post.creator,
with_post_count: false %>
</div>
</div>
</div>
<div class="mt-2 flex flex-wrap gap-x-4 text-sm text-slate-600">
<span>
<i class="fa-regular fa-calendar mr-1"></i>
<% if (posted_at = @post.posted_at || @post.guess_posted_at) %>
Posted: <%= posted_at&.strftime("%Y-%m-%d") %>
(<%= time_ago_in_words(posted_at) if posted_at %> ago)
<% else %>
Posted: unknown
<% end %>
</span>
<span>
<i class="fa-solid fa-eye mr-1"></i>
Views: <%= @post.num_views %>
</span>
<span>
<i class="fa-solid fa-comment mr-1"></i>
Comments: <%= @post.num_comments %>
</span>
<span>
<i class="fa-solid fa-heart mr-1"></i>
Favorites: <%= @post.num_favorites %>
<% if policy(@post).view_scraper_metadata? %>
(<%= link_to pluralize(@post.faved_by.count, "fav"),
favorites_domain_fa_post_path(@post),
class: "text-blue-600 hover:underline" %>)
<% end %>
</span>
</div>
<% if policy(@post).view_scraper_metadata? %>
<% scanned_at = @post.scanned_at %>
<% scanned_hle = @post.last_submission_page || guess_scanned_http_log_entry(@post) %>
<% scanned_at ||= scanned_hle&.requested_at %>
<% if scanned_at %>
<div class="mt-2 text-sm text-slate-500">
<div class="mt-2 text-sm text-slate-500">
<% if scanned_hle %>
<%= link_to "Scanned #{time_ago_in_words(scanned_at)} ago",
log_entry_path(scanned_hle),
class: "text-blue-600 hover:underline",
target: "_blank" %>
<% else %>
<span> Scanned <%= time_ago_in_words(scanned_at) %> ago </span>
<% end %>
</div>
</div>
<% else %>
<div class="mt-2 text-sm text-slate-500">Unknown when post scanned</div>
<% end %>
<% if hle = guess_file_downloaded_http_log_entry(@post) %>
<div class="mt-2 text-sm text-slate-500">
<%= link_to "File downloaded #{time_ago_in_words(hle.requested_at)} ago",
log_entry_path(hle),
class: "text-blue-600 hover:underline",
target: "_blank" %>
</div>
<% else %>
<div class="mt-2 text-sm text-slate-500">
Unknown when file downloaded
</div>
<% end %>
<% end %>
</section>
<% if policy(@post).view_file? %>
<section>
<% if @post.file %>
<%= render partial: "log_entries/content_container",
locals: {
log_entry: @post.file,
} %>
<% else %>
<% if !@post.scanned? %>
<%= button_to "Force scan post", scan_post_domain_fa_post_path(fa_id: @post.fa_id) %>
<% elsif !@post.file %>
<%= button_to "Force scan file", scan_post_domain_fa_post_path(fa_id: @post.fa_id) %>
<% else %>
Scanned and have file
<% end %>
<% end %>
</section>
<%= render partial: "log_entries/file_details_sky_section",
locals: {
log_entry: @post.file,
} %>
<% else %>
<section class="sky-section">
<%= link_to "https://www.furaffinity.net/view/#{@post.fa_id}/",
target: "_blank",
rel: "noopener noreferrer",
class: "section-header flex items-center gap-2 hover:text-slate-600" do %>
<span>View Post on FurAffinity</span>
<i class="fa-solid fa-arrow-up-right-from-square"></i>
<% end %>
</section>
<% end %>
<%= render "section_description", { post: @post } %>
<%= render "section_similar_posts", { post: @post } %>
</div>

View File

@@ -1,10 +0,0 @@
<section class="sky-section">
<% if (post_description_html = @post.description) %>
<div class="section-header">Post Description</div>
<div class="bg-slate-800 p-4 text-slate-200">
<%= fa_post_description_sanitized(post_description_html) %>
</div>
<% else %>
<div>(No post description)</div>
<% end %>
</section>

View File

@@ -1,42 +0,0 @@
<section class="sky-section">
<div class="section-header">Similar Posts</div>
<div
class="grid grid-cols-[1fr_auto_auto] items-center divide-y divide-slate-300 bg-slate-100"
>
<% cache(post.disco, expires_in: 12.hours) do %>
<% similar =
post
.disco
&.nearest_neighbors(:for_favorite, distance: "cosine")
&.limit(20)
&.includes(post: { creator: :avatar }) %>
<% if similar %>
<% similar
.map(&:post)
.each do |post| %>
<% creator = post.creator %>
<div class="col-span-3 grid grid-cols-subgrid">
<span class="text-md truncate px-4 py-2">
<%= link_to post.title, domain_fa_post_path(post.fa_id), class: "underline italic" %>
</span>
<a href="<%= domain_fa_user_path(creator) %>" class="contents">
<div class="px-2 py-2">
<img
src="<%= fa_user_avatar_path(creator, thumb: "64-avatar") %>"
class="h-8 w-8 flex-shrink-0 rounded-md"
/>
</div>
<span class="sky-link truncate px-4 py-2">
<%= creator.url_name %>
</span>
</a>
</div>
<% end %>
<% else %>
<div class="col-span-3 p-4 text-center italic text-slate-400">
No similar posts
</div>
<% end %>
<% end %>
</div>
</section>

View File

@@ -1,51 +0,0 @@
<div class="mx-auto mt-4 flex w-full max-w-2xl flex-col gap-4 pb-4">
<section class="rounded-md border border-slate-300 bg-slate-50 p-4">
<div class="flex items-center justify-between gap-4">
<div class="flex min-w-0 items-center gap-2">
<h1 class="text-lg font-medium">
Users who favorited
<%= link_to @post.title,
domain_fa_post_path(@post),
class: "text-blue-600 hover:underline" %>
</h1>
</div>
</div>
</section>
<% favs = @post.faved_by.includes(:avatar).to_a %>
<% if favs.any? %>
<section
class="overflow-hidden rounded-md border border-slate-300 bg-slate-50"
>
<div class="divide-y divide-slate-200">
<% favs.each do |user| %>
<%= link_to domain_fa_user_path(user),
class: "flex items-center gap-4 p-4 hover:bg-slate-100" do %>
<% if user.avatar&.file_sha256.present? %>
<%= image_tag fa_user_avatar_path(user, thumb: "64-avatar"),
class: "h-12 w-12 rounded-md border object-cover",
alt: user.name %>
<% else %>
<div
class="flex h-12 w-12 items-center justify-center rounded-full bg-slate-200"
>
<i class="bi bi-person text-slate-400"></i>
</div>
<% end %>
<div class="min-w-0">
<div class="font-medium text-slate-900"><%= user.name %></div>
<div class="text-sm text-slate-500">@<%= user.url_name %></div>
</div>
<% end %>
<% end %>
</div>
</section>
<% else %>
<section
class="rounded-md border border-slate-300 bg-slate-50 p-8 text-center"
>
<i class="bi bi-heart mb-3 block text-4xl text-slate-400"></i>
<p class="text-slate-600">No users have favorited this post yet.</p>
</section>
<% end %>
</div>

View File

@@ -1,79 +0,0 @@
<div class="mx-auto mt-4 text-center sm:mt-6">
<% if @user %>
<h1 class="flex text-2xl">
<%= link_to(@user, class: "sky-link flex items-center gap-2") do %>
<img
src="<%= fa_user_avatar_path(@user, thumb: "64-avatar") %>"
class="inline-block h-8 w-8 rounded-md"
/>
<span><%= @user.name %></span>
<% end %>
<span>'s posts <%= page_str(params) %></span>
</h1>
<% else %>
<h1 class="text-2xl">
All FurAffinity posts, page <%= page_str(params) || 1 %>
</h1>
<% end %>
</div>
<%= render partial: "shared/pagination_controls", locals: { collection: @posts } %>
<div class="mx-auto flex max-w-full flex-row flex-wrap justify-center">
<% @posts.each do |post| %>
<div
class="m-4 flex flex-col rounded-lg border border-slate-300 bg-slate-50 shadow-sm"
>
<% if policy(post).view_file? %>
<div
class="flex flex-1 items-center justify-center border-b border-slate-300 p-4"
>
<% if post.file %>
<%= link_to domain_fa_post_path(post.fa_id) do %>
<img
class="max-h-[300px] max-w-[300px] rounded-md border border-slate-300 object-contain shadow-md"
alt="<%= post.title %>"
src="<%= blob_path(
HexUtil.bin2hex(post.file.response_sha256),
format: "jpg",
thumb: "small",
) %>"
/>
<% end %>
<% else %>
<span>No file for <%= post.fa_id %></span>
<% end %>
</div>
<% end %>
<div>
<h2 class="p-4 text-center text-lg">
<%= link_to post.title, domain_fa_post_path(post.fa_id), class: "sky-link" %>
</h2>
<div class="px-4 pb-4 text-sm text-slate-600">
<div class="flex items-start justify-between">
<div>
<% if post.posted_at %>
Posted <%= post.posted_at.strftime("%Y-%m-%d") %>
<div class="text-slate-500">
(<%= time_ago_in_words(post.posted_at) %> ago)
</div>
<% else %>
Posted date unknown
<% end %>
</div>
<%= link_to "https://www.furaffinity.net/view/#{post.fa_id}",
target: "_blank",
rel: "noopener",
class:
"inline-flex items-center text-slate-500 hover:text-slate-700 ml-8 decoration-dotted underline" do %>
<span>FA #<%= post.fa_id %></span>
<%= render partial: "shared/icons/external_link",
locals: {
class_name: "w-4 h-4 ml-1",
} %>
<% end %>
</div>
</div>
</div>
</div>
<% end %>
</div>
<%= render partial: "shared/pagination_controls", locals: { collection: @posts } %>

View File

@@ -1 +0,0 @@
<%= render @post %>

View File

@@ -1,17 +0,0 @@
<div class="flex w-full items-center">
<a
class="flex grow items-center gap-2"
href="<%= domain_fa_user_path(user) %>"
>
<img
src="<%= fa_user_avatar_path(user, thumb: "64-avatar") %>"
class="h-8 w-8 rounded-md"
/>
<span class="sky-link"> <%= user.url_name %> </span>
</a>
<% if !defined?(with_post_count) || with_post_count %>
<span class="ml-2 text-slate-500">
<%= pluralize(number_with_delimiter(user.posts.count, delimiter: ","), "post") %>
</span>
<% end %>
</div>

View File

@@ -1,13 +0,0 @@
<div class="mx-auto my-4 w-full space-y-4 md:max-w-2xl">
<%= render "domain/fa/users/show_sections/name_icon_and_status", user: user %>
<div class="flex flex-col gap-4 sm:flex-row">
<div class="w-full sm:w-1/2">
<%= render "domain/fa/users/show_sections/stats", user: user %>
</div>
<div class="w-full sm:w-1/2">
<%= render "domain/fa/users/show_sections/recent_posts", user: user %>
</div>
</div>
<%= render "domain/fa/users/show_sections/profile_description", user: user %>
<%= render "domain/fa/users/show_sections/similar_users", user: user %>
</div>

View File

@@ -1,53 +0,0 @@
<section class='w-full'>
<h1>Users</h1>
<% @users.each do |user| %>
<div class='mx-auto max-w-xl bg-slate-200 border-slate-300 border-2 my-2 p-2 rounded flex flex-row'>
<% if (a = user.avatar&.log_entry) %>
<img class='rounded-sm' alt='<%= user.name %> avatar' src='<%= contents_log_entry_path(a) %>' />
<% else %>
<div>(No avatar)</div>
<% end %>
<div class='flex-grow ml-2 flex-col'>
<div class='flex-row'>
<a
class='
text-lg text-black font-semibold
underline decoration-dotted hover:decoration-solid'
href='<%= domain_fa_user_path(user) %>'><%= user.name %></a>
<a
class='
m-l-2 text-md text-slate-600
underline decoration-dotted hover:decoration-solid'
href="<%= domain_fa_user_posts_path(user) %>"
>
<%= pluralize(user.posts.count, "post") %>
</a>
</div>
<p class='block text-md text-slate-600'>
<% if user.scanned_page_at %>
Scanned page <%= time_ago_in_words(user.scanned_page_at) %> ago
<% else %>
Not yet scanned page
<% end %>
</p>
<p class='block text-md text-slate-600'>
<% if user.scanned_gallery_at %>
Scanned gallery <%= time_ago_in_words(user.scanned_gallery_at) %> ago
<% else %>
Not yet scanned gallery
<% end %>
</p>
</div>
<div class='flex'>
<a class='
self-start inline
border-b text-slate-600 border-slate-600 border-dashed
hover:border-black hover:text-black
' target='_blank' rel='noopener noreferrer' href='https://www.furaffinity.net/user/<%= user.url_name %>'>
FurAffinity
<img class='w-4 h-4 align-text-top inline' src='<%= image_path("arrow-top-right-on-square.svg") %>'>
</a>
</div>
</div>
<% end %>
</section>

View File

@@ -1,2 +0,0 @@
<p style="color: green"><%= notice %></p>
<%= render @user %>

View File

@@ -1,40 +0,0 @@
<section class="animated-shadow-sky sky-section flex divide-none p-3">
<div class="flex grow items-center gap-4">
<img src="<%= fa_user_avatar_path(user) %>" class="h-12 w-12 rounded-lg" />
<div>
<div class="text-lg font-bold text-slate-900"><%= user.url_name %></div>
<div class="flex gap-6 text-sm text-slate-400">
<% if policy(user).view_scraped_at_timestamps? %>
<div class="flex flex-col">
<span class="font-medium italic text-slate-500">Status</span>
<span class=""><%= fa_user_account_status(user) %></span>
</div>
<div class="flex flex-col">
<span class="font-medium italic text-slate-500">State</span>
<span class=""><%= user.state %></span>
</div>
<% end %>
<div class="flex flex-col">
<span class="font-medium italic text-slate-500">Registered</span>
<span class="">
<% if user.registered_at %>
<%= time_ago_in_words(user.registered_at) %>
ago
<% else %>
unknown
<% end %>
</span>
</div>
</div>
</div>
</div>
<a
href="https://www.furaffinity.net/user/<%= user.url_name %>/"
target="_blank"
rel="noopener noreferrer"
class="sky-link flex items-center gap-2"
>
<span class="font-bold">FurAffinity</span>
<img src="<%= image_path("domain-icons/fa.png") %>" class="h-5 w-5" />
</a>
</section>

View File

@@ -1,12 +0,0 @@
<section class="animated-shadow-sky sky-section">
<% if (profile_html = user.profile_html) %>
<h2 class="section-header">Profile Description</h2>
<div class="bg-slate-800 p-4 text-slate-200">
<% cache(user, expires_in: 12.hours) do %>
<%= sanitized_fa_user_profile_html(profile_html) %>
<% end %>
</div>
<% else %>
<div class="px-4 py-3 text-slate-500">No profile description available</div>
<% end %>
</section>

View File

@@ -1,32 +0,0 @@
<section class="animated-shadow-sky sky-section">
<h2 class="section-header">
<span class="font-medium text-slate-900">Recent Posts</span>
<span class="float-right">
<%= link_to "#{user.posts.count} total",
domain_fa_user_posts_path(user),
class: "sky-link" %>
</span>
</h2>
<% if user.posts.any? %>
<% user
.posts
.order(fa_id: :desc)
.limit(5)
.each do |post| %>
<div class="flex items-center px-4 py-2">
<span class="grow truncate">
<%= link_to post.title, domain_fa_post_path(post), class: "sky-link block truncate" %>
</span>
<span class="whitespace-nowrap text-slate-500">
<% if posted_at = post.posted_at %>
<%= time_ago_in_words(posted_at) %> ago
<% else %>
Unknown posted at
<% end %>
</span>
</div>
<% end %>
<% else %>
<div class="px-4 py-3 text-slate-500">No posts found</div>
<% end %>
</section>

View File

@@ -1,15 +0,0 @@
<section class="animated-shadow-sky sky-section">
<h2 class="section-header">Similar Users</h2>
<% cache(user.disco, expires_in: 12.hours) do %>
<% similar = similar_users_by_followed(user)&.includes(:avatar) %>
<% if similar %>
<% similar.each do |user| %>
<div class="flex items-center px-4 py-2">
<%= render "inline_link", user: user %>
</div>
<% end %>
<% else %>
<div class="px-4 py-3 text-slate-500">No similar users found</div>
<% end %>
<% end %>
</section>

View File

@@ -1,22 +0,0 @@
<section class="sky-section animated-shadow-sky divide-y">
<h2 class="section-header">User Stats</h2>
<% rows = [
["Favorites", user.num_favorites],
["Following", user.follower_joins.count],
["Followed by", user.followed_joins.count],
]
if policy(user).view_scraped_at_timestamps?
rows << ["Gallery scanned", user.time_ago_for_gallery_scan]
rows << ["Page scanned", user.time_ago_for_page_scan]
end
rows.each do |label, value| %>
<div class="flex items-center px-4 py-2">
<span class="grow text-slate-900"><%= label %></span>
<span class="text-slate-500">
<%= value.is_a?(Integer) ? number_with_delimiter(value, delimiter: ",") : value %>
</span>
</div>
<% end %>
</section>

View File

@@ -1,65 +0,0 @@
<div class="mx-auto mt-4 text-center sm:mt-6">
<% if @user %>
<h1 class="text-2xl">
<%= link_to(@user.name, @user, class: "underline") %>'s posts
</h1>
<% else %>
<h1 class="text-2xl">
Inkbunny Posts (<%= @posts.total_count %>), page <%= page_str(params) %>
</h1>
<% end %>
</div>
<div
class="mx-auto mb-4 mt-4 w-full rounded-md border-2 border-slate-300 sm:mb-6 sm:mt-6 sm:max-w-md"
>
<div class="flex h-full items-stretch justify-center">
<%= link_to "Previous page",
path_to_prev_page(@posts),
class:
"hover:underline hover:bg-slate-200 hover:shadow-sm px-6 py-2 text-center border-slate-300 border-r-2 bg-slate-100 flex-1 flex items-center justify-center" %>
<%= link_to "Next page",
path_to_next_page(@posts),
class:
"hover:underline hover:bg-slate-200 hover:shadow-sm px-6 py-2 text-center bg-slate-100 flex-1 flex items-center justify-center" %>
</div>
</div>
<div class="mx-2 flex-row">
<% @posts.each do |post| %>
<div
class="mx-auto mb-4 max-w-6xl rounded-md border-2 border-slate-300 bg-slate-100 p-2"
>
<div class="mb-2 flex justify-between text-slate-800">
<div>
<%= link_to post.title, post, class: "hover:underline" %>
<span class="ml-2 text-sm text-slate-500"
>by
<%= link_to post.creator.name, post.creator, class: "hover:underline" %></span
>
</div>
<div class="text-sm text-slate-400">
(ID: <%= post.ib_post_id %>,
<%= pluralize(post.files.count, "file") %>)
</div>
</div>
<div class="flex flex-row gap-2">
<% post.files.each do |file| %>
<% if policy(post).view_file? %>
<% img_src_path =
blob_path(
HexUtil.bin2hex(file.blob_entry_sha256),
format: "jpg",
thumb: "small",
) %>
<div class="overflow-hidden rounded-md">
<img
class="my-2 h-32 rounded-md border-2 border-slate-400 shadow-md first:pl-0 last:pr-0"
alt="<%= post.title %>"
src="<%= img_src_path %>"
/>
</div>
<% end %>
<% end %>
</div>
</div>
<% end %>
</div>

View File

@@ -1,74 +0,0 @@
<div class="mx-auto mt-4 flex w-full max-w-2xl flex-col gap-4 pb-4">
<section class="rounded-md border border-slate-300 bg-slate-50 p-4">
<div class="flex items-center justify-between gap-4">
<div class="flex min-w-0 items-center gap-4">
<div class="flex min-w-0 items-center gap-2">
<span class="truncate text-lg font-medium">
<%= link_to @post.title,
"https://inkbunny.net/s/#{@post.ib_post_id}",
class: "text-blue-600 hover:underline",
target: "_blank" %>
</span>
<i class="fa-solid fa-arrow-up-right-from-square text-slate-400"></i>
</div>
<div class="flex items-center gap-2 whitespace-nowrap text-slate-600">
by
<%= link_to @post.creator.name, @post.creator, class: "hover:underline" %>
</div>
</div>
</div>
<div class="mt-2 flex flex-wrap gap-x-4 text-sm text-slate-600">
<span>
<i class="fa-regular fa-calendar mr-1"></i>
Posted: <%= @post.posted_at&.strftime("%Y-%m-%d") %>
(<%= time_ago_in_words(@post.posted_at) if @post.posted_at %> ago)
</span>
<span>
<i class="fa-solid fa-tag mr-1"></i>
Type: <%= @post.submission_type&.titleize || "Unknown" %>
</span>
<span>
<i class="fa-solid fa-shield mr-1"></i>
Rating: <%= @post.rating&.titleize || "Unknown" %>
</span>
</div>
<% if policy(@post).view_scraper_metadata? %>
<div class="mt-2 text-sm text-slate-500">
Scanned: <%= @post.created_at.strftime("%Y-%m-%d %H:%M:%S") %>
(<%= time_ago_in_words(@post.created_at) %> ago)
</div>
<% end %>
</section>
<% if policy(@post).view_file? %>
<section>
<div class="flex flex-col gap-4">
<% @post.files.each do |file| %>
<% if file.blob_entry %>
<div class="overflow-hidden rounded-lg shadow-lg">
<img
class="h-auto w-full"
alt="<%= @post.title %>"
src="<%= blob_path(HexUtil.bin2hex(file.blob_entry_sha256), format: "jpg") %>"
/>
</div>
<% else %>
<div class="text-center text-slate-600">
File #<%= file.ib_file_id %> not yet downloaded
</div>
<% end %>
<% end %>
</div>
</section>
<% else %>
<section class="sky-section">
<%= link_to "https://inkbunny.net/s/#{@post.ib_post_id}",
target: "_blank",
rel: "noopener noreferrer",
class: "section-header flex items-center gap-2 hover:text-slate-600" do %>
<span>View Post on Inkbunny</span>
<i class="fa-solid fa-arrow-up-right-from-square"></i>
<% end %>
</section>
<% end %>
</div>

View File

@@ -1,44 +0,0 @@
<div class="mx-auto">
<h1 class="text-2xl"><%= @user.name %>'s Profile</h1>
</div>
<div class="mx-auto">
<h2 class="mb-2 mt-4 text-xl">Posts (<%= @user.posts.count %>)</h2>
<div class="mx-2 flex-row">
<% @user
.posts
.order(posted_at: :desc)
.limit(10)
.each do |post| %>
<div class="border-stone-00 mb-4 rounded-md border-2 p-4">
<div class="mb-2 flex justify-between text-stone-800">
<div><%= link_to post.title, post, class: "hover:underline" %></div>
<div class="text-sm text-stone-400">
(ID: <%= post.ib_post_id %>,
<%= pluralize(post.files.count, "file") %>)
</div>
</div>
<div class="flex flex-row gap-2">
<% post.files.each do |file| %>
<% if file.blob_entry_sha256.present? %>
<% img_src_path =
blob_path(
HexUtil.bin2hex(file.blob_entry_sha256),
format: "jpg",
thumb: "small",
) %>
<% else %>
(no media file)
<% end %>
<div class="overflow-hidden rounded-md">
<img
class="h-32 p-2 first:pl-0 last:pr-0"
alt="<%= post.title %>"
src="<%= img_src_path %>"
/>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
</div>

View File

@@ -5,7 +5,7 @@
>
<% factors = Domain::Factors::UserPostFavPostFactors.find_by(post: post) %>
<% if factors %>
<% nearest_neighbors = factors.nearest_neighbors(:embedding, distance: "cosine").includes(:post).limit(20) %>
<% nearest_neighbors = factors.nearest_neighbors(:embedding, distance: "euclidean").includes(:post).limit(10) %>
<% nearest_neighbors.each do |factor| %>
<% post = factor.post %>
<% creator = post.class.has_creators? ? post.creator : nil %>

View File

@@ -4,7 +4,7 @@
<span class="font-medium text-slate-900">Similar Users</span>
</h2>
<% if factors %>
<% nearest_neighbors = factors.nearest_neighbors(:embedding, distance: "cosine").includes(:user).limit(10) %>
<% nearest_neighbors = factors.nearest_neighbors(:embedding, distance: "euclidean").includes(:user).limit(10) %>
<% nearest_neighbors.each do |neighbor| %>
<% user = neighbor.user %>
<div class="flex items-center gap-2 whitespace-nowrap text-slate-600 justify-between w-full px-4 py-2">

View File

@@ -8,14 +8,15 @@ Rails.application.routes.draw do
registrations: "users/registrations",
sessions: "users/sessions",
}
root to: "pages#root"
get "furecs-user-script", to: "pages#furecs_user_script"
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
root to: "pages#root"
get "furecs-user-script", to: "pages#furecs_user_script"
get "us/:script", to: "user_scripts#get", constraints: { script: /.*/ }
namespace :api do
namespace :fa do
get :similar_users, to: "/domain/fa/api#similar_users"
get :search_user_names, to: "/domain/fa/api#search_user_names"
get :object_statuses, to: "/domain/fa/api#object_statuses"
end
end
@@ -57,68 +58,8 @@ Rails.application.routes.draw do
end
end
# Domain::RouteHelper::DOMAIN_POST_RESOURCES.each do |resource_data|
# resolve resource_data.klass.name do |post|
# domain_post_path(post)
# end
# end
# Domain::RouteHelper::DOMAIN_USER_RESOURCES.each do |resource_data|
# resources resource_data.resource_name,
# only: [:show],
# param: resource_data.param,
# controller: resource_data.controller,
# path: "users/#{resource_data.subpath}" do
# resources :posts,
# controller: "domain/posts",
# only: %i[index],
# path: "posts"
# end
# end
# Domain::RouteHelper::DOMAIN_POST_RESOURCES.each do |resource_data|
# resources resource_data.resource_name,
# only: %i[show],
# param: resource_data.param,
# controller: resource_data.controller,
# path: "posts/#{resource_data.subpath}" do
# get :faved_by, on: :member
# end
# end
namespace :domain do
namespace :fa do
resources :users,
param: :url_name,
only: [:show],
constraints: {
url_name: %r{[^/]+},
} do
resources :posts, controller: "/domain/fa/posts", only: %i[index]
end
resources :posts, param: :fa_id, only: %i[show] do
post :scan_post, on: :member
get :favorites, on: :member
end
end
namespace :e621 do
resources :posts, param: :e621_id, only: [:show]
end
namespace :inkbunny, path: "ib" do
resources :users, param: :name, only: [:show] do
resources :posts, controller: "/domain/inkbunny/posts", only: %i[index]
end
resources :posts, param: :ib_post_id, only: %i[show]
end
end
resources :blobs, controller: :blob_entries, only: [:show], param: :sha256
resources :indexed_posts, only: [:index]
get "us/:script", to: "user_scripts#get", constraints: { script: /.*/ }
resources :global_states, path: "state" do
collection do
get "fa-cookies", to: "global_states#fa_cookies"
@@ -141,18 +82,6 @@ Rails.application.routes.draw do
via: :all,
as: :prometheus
namespace :api do
get "search/user/:prefix", to: "search#user"
namespace :fa do
post :enqueue_objects, to: "/domain/fa/api#enqueue_objects"
end
namespace :twitter do
post :enqueue_objects, to: "/domain/twitter/api#enqueue_objects"
post :object_statuses, to: "/domain/twitter/api#object_statuses"
end
end
resources :log_entries, only: %i[index show] do
get :stats, on: :collection

View File

@@ -44,7 +44,6 @@ class ApplicationController
include ::Domain::PostGroupsHelper
include ::DomainSourceHelper
include ::GoodJobHelper
include ::IndexablePostsHelper
include ::SourceHelper
include ::DeviseHelper
include ::ReactOnRails::Utils::Required

View File

@@ -41,7 +41,6 @@ class DeviseController
include ::Domain::PostGroupsHelper
include ::DomainSourceHelper
include ::GoodJobHelper
include ::IndexablePostsHelper
include ::SourceHelper
include ::DeviseHelper
include ::ReactOnRails::Utils::Required

View File

@@ -9,9 +9,6 @@ module GeneratedPathHelpersModule
include ::ActionDispatch::Routing::UrlFor
include ::ActionDispatch::Routing::PolymorphicRoutes
sig { params(args: T.untyped).returns(String) }
def api_fa_enqueue_objects_path(*args); end
sig { params(args: T.untyped).returns(String) }
def api_fa_object_statuses_path(*args); end
@@ -21,15 +18,6 @@ module GeneratedPathHelpersModule
sig { params(args: T.untyped).returns(String) }
def api_fa_similar_users_path(*args); end
sig { params(args: T.untyped).returns(String) }
def api_path(*args); end
sig { params(args: T.untyped).returns(String) }
def api_twitter_enqueue_objects_path(*args); end
sig { params(args: T.untyped).returns(String) }
def api_twitter_object_statuses_path(*args); end
sig { params(args: T.untyped).returns(String) }
def blob_path(*args); end
@@ -39,27 +27,6 @@ module GeneratedPathHelpersModule
sig { params(args: T.untyped).returns(String) }
def destroy_user_session_path(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_e621_post_path(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_fa_post_path(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_fa_user_path(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_fa_user_posts_path(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_inkbunny_post_path(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_inkbunny_user_path(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_inkbunny_user_posts_path(*args); end
sig { params(args: T.untyped).returns(String) }
def edit_global_state_path(*args); end
@@ -78,9 +45,6 @@ module GeneratedPathHelpersModule
sig { params(args: T.untyped).returns(String) }
def faved_by_post_users_path(*args); end
sig { params(args: T.untyped).returns(String) }
def favorites_domain_fa_post_path(*args); end
sig { params(args: T.untyped).returns(String) }
def favorites_user_posts_path(*args); end
@@ -105,9 +69,6 @@ module GeneratedPathHelpersModule
sig { params(args: T.untyped).returns(String) }
def ib_cookies_global_states_path(*args); end
sig { params(args: T.untyped).returns(String) }
def indexed_posts_path(*args); end
sig { params(args: T.untyped).returns(String) }
def log_entries_path(*args); end
@@ -228,9 +189,6 @@ module GeneratedPathHelpersModule
sig { params(args: T.untyped).returns(String) }
def root_path(*args); end
sig { params(args: T.untyped).returns(String) }
def scan_post_domain_fa_post_path(*args); end
sig { params(args: T.untyped).returns(String) }
def search_by_name_users_path(*args); end

View File

@@ -9,9 +9,6 @@ module GeneratedUrlHelpersModule
include ::ActionDispatch::Routing::UrlFor
include ::ActionDispatch::Routing::PolymorphicRoutes
sig { params(args: T.untyped).returns(String) }
def api_fa_enqueue_objects_url(*args); end
sig { params(args: T.untyped).returns(String) }
def api_fa_object_statuses_url(*args); end
@@ -21,15 +18,6 @@ module GeneratedUrlHelpersModule
sig { params(args: T.untyped).returns(String) }
def api_fa_similar_users_url(*args); end
sig { params(args: T.untyped).returns(String) }
def api_twitter_enqueue_objects_url(*args); end
sig { params(args: T.untyped).returns(String) }
def api_twitter_object_statuses_url(*args); end
sig { params(args: T.untyped).returns(String) }
def api_url(*args); end
sig { params(args: T.untyped).returns(String) }
def blob_url(*args); end
@@ -39,27 +27,6 @@ module GeneratedUrlHelpersModule
sig { params(args: T.untyped).returns(String) }
def destroy_user_session_url(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_e621_post_url(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_fa_post_url(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_fa_user_posts_url(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_fa_user_url(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_inkbunny_post_url(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_inkbunny_user_posts_url(*args); end
sig { params(args: T.untyped).returns(String) }
def domain_inkbunny_user_url(*args); end
sig { params(args: T.untyped).returns(String) }
def edit_global_state_url(*args); end
@@ -78,9 +45,6 @@ module GeneratedUrlHelpersModule
sig { params(args: T.untyped).returns(String) }
def faved_by_post_users_url(*args); end
sig { params(args: T.untyped).returns(String) }
def favorites_domain_fa_post_url(*args); end
sig { params(args: T.untyped).returns(String) }
def favorites_user_posts_url(*args); end
@@ -105,9 +69,6 @@ module GeneratedUrlHelpersModule
sig { params(args: T.untyped).returns(String) }
def ib_cookies_global_states_url(*args); end
sig { params(args: T.untyped).returns(String) }
def indexed_posts_url(*args); end
sig { params(args: T.untyped).returns(String) }
def log_entries_url(*args); end
@@ -228,9 +189,6 @@ module GeneratedUrlHelpersModule
sig { params(args: T.untyped).returns(String) }
def root_url(*args); end
sig { params(args: T.untyped).returns(String) }
def scan_post_domain_fa_post_url(*args); end
sig { params(args: T.untyped).returns(String) }
def search_by_name_users_url(*args); end

View File

@@ -44,7 +44,6 @@ class Rails::ApplicationController
include ::Domain::PostGroupsHelper
include ::DomainSourceHelper
include ::GoodJobHelper
include ::IndexablePostsHelper
include ::SourceHelper
include ::DeviseHelper
include ::ReactOnRails::Utils::Required

View File

@@ -44,7 +44,6 @@ class Rails::Conductor::BaseController
include ::Domain::PostGroupsHelper
include ::DomainSourceHelper
include ::GoodJobHelper
include ::IndexablePostsHelper
include ::SourceHelper
include ::DeviseHelper
include ::ReactOnRails::Utils::Required

View File

@@ -44,7 +44,6 @@ class Rails::HealthController
include ::Domain::PostGroupsHelper
include ::DomainSourceHelper
include ::GoodJobHelper
include ::IndexablePostsHelper
include ::SourceHelper
include ::DeviseHelper
include ::ReactOnRails::Utils::Required

View File

@@ -2,14 +2,6 @@
require "rails_helper"
RSpec.describe Domain::Fa::ApiController, type: :controller do
describe "GET #search_user_names" do
it "returns matching users" do
get :search_user_names, params: { name: "test" }
expect(response).to be_successful
expect(JSON.parse(response.body)).to include("users")
end
end
describe "POST #object_statuses" do
it "returns status of posts and users" do
post :object_statuses, params: { fa_ids: [123], url_names: ["test"] }

View File

@@ -1,71 +0,0 @@
# typed: false
require "rails_helper"
RSpec.describe Domain::Fa::PostsController, type: :controller do
render_views
describe "GET #show" do
let(:post) { create(:domain_fa_post, :with_creator) }
it "returns a successful response" do
get :show,
params: {
fa_id: post.fa_id,
user_url_name: post.creator.url_name,
}
expect(response).to be_successful
end
end
describe "GET #index" do
let(:user) { create(:domain_fa_user, :with_avatar) }
let!(:posts) do
[
create(:domain_fa_post, creator: user, title: "Test Post 1"),
create(:domain_fa_post, creator: user, title: "Test Post 2"),
]
end
before do
allow_any_instance_of(Domain::Fa::PostPolicy).to receive(
:view_file?,
).and_return(true)
end
it "renders index template with posts" do
get :index, params: { user_url_name: user.url_name }
expect(response).to be_successful
expect(response.body).to include(user.name)
expect(response.body).to include("posts")
posts.each do |post|
expect(response.body).to include(post.title)
if post.file
expect(response.body).to include(
blob_path(
HexUtil.bin2hex(post.file.response_sha256),
format: "jpg",
thumb: "small",
),
)
end
end
end
context "when viewing a specific user's posts" do
it "shows the user's posts with avatar" do
get :index, params: { user_url_name: user.url_name }
expect(response).to be_successful
expect(response.body).to include(user.name)
expect(response.body).to include("posts")
expect(response.body).to include(
blob_path(
HexUtil.bin2hex(user.avatar.file_sha256),
format: "jpg",
thumb: "64-avatar",
),
)
posts.each { |post| expect(response.body).to include(post.title) }
end
end
end
end

View File

@@ -1,15 +0,0 @@
# typed: false
require "rails_helper"
RSpec.describe Domain::Fa::UsersController, type: :controller do
render_views
describe "GET #show" do
let(:user) { create(:domain_fa_user, registered_at: 1.year.ago) }
it "returns a successful response" do
get :show, params: { url_name: user.url_name }
expect(response).to be_successful
end
end
end

View File

@@ -1,78 +0,0 @@
# typed: false
require "rails_helper"
RSpec.describe Domain::Inkbunny::PostsController, type: :controller do
render_views
describe "GET #show" do
let(:post) { create(:domain_inkbunny_post) }
it "returns http success" do
get :show, params: { ib_post_id: post.ib_post_id }
expect(response).to be_successful
end
end
describe "GET #index" do
let(:user) { create(:domain_inkbunny_user, name: "Test User") }
let!(:posts) do
[
create(:domain_inkbunny_post, creator: user, title: "Test Post 1"),
create(:domain_inkbunny_post, creator: user, title: "Test Post 2"),
]
end
let!(:files) do
posts.map { |post| create(:domain_inkbunny_file, post: post) }
end
context "when user is not an admin" do
it "renders index template with posts but without thumbnails" do
get :index, params: { user_name: user.name }
expect(response).to be_successful
expect(response).to render_template(:index)
expect(response.body).to include(posts[0].title)
expect(response.body).to include(posts[1].title)
expect(response.body).to include(user.name)
expect(response.body).not_to match(/<img.+blobs/)
end
end
context "when user is an admin" do
let(:admin) { create(:user, :admin) }
before { sign_in admin }
it "renders index template with posts and thumbnails" do
get :index, params: { user_name: user.name }
expect(response).to be_successful
expect(response).to render_template(:index)
expect(response.body).to include(posts[0].title)
expect(response.body).to include(posts[1].title)
expect(response.body).to include(user.name)
files.each do |file|
expect(response.body).to include(
blob_path(
HexUtil.bin2hex(file.blob_entry_sha256),
format: "jpg",
thumb: "small",
),
)
end
end
it "requires a user_name parameter" do
expect { get :index }.to raise_error(
ActionController::UrlGenerationError,
)
end
end
context "when viewing a specific user's posts" do
it "shows the user's posts" do
get :index, params: { user_name: user.name }
expect(response).to be_successful
expect(response.body).to include("#{user.name}")
posts.each { |post| expect(response.body).to include(post.title) }
end
end
end
end

View File

@@ -1,72 +0,0 @@
# typed: false
require "rails_helper"
RSpec.describe IndexedPostsController, type: :controller do
render_views
let(:admin_user) { create(:user, role: :admin) }
describe "GET #index" do
context "when user is not signed in" do
it "redirects to the sign in page" do
get :index
expect(response).to redirect_to(new_user_session_path)
end
end
context "when admin user is signed in" do
before { sign_in admin_user }
let(:file) { create(:http_log_entry) }
let!(:fa_post) { create(:domain_fa_post, file: file, title: "Test Post") }
context "with gallery view" do
it "renders gallery view with thumbnails" do
get :index, params: { view: "gallery" }
expect(response).to be_successful
expect(response).to render_template(:index)
expect(response.body).to include(fa_post.title)
expect(response.body).to include(
blob_path(
HexUtil.bin2hex(file.response_sha256),
format: "jpg",
thumb: "small",
),
)
end
end
context "with table view" do
it "renders table view with thumbnails" do
get :index, params: { view: "table" }
expect(response).to be_successful
expect(response).to render_template(:index)
expect(response.body).to include(fa_post.title)
expect(response.body).to include(
blob_path(
HexUtil.bin2hex(file.response_sha256),
format: "jpg",
thumb: "tiny",
),
)
end
end
context "when post has no file" do
let!(:fa_post) do
create(:domain_fa_post, file: nil, title: "Test Post")
end
it "shows appropriate message in gallery view" do
get :index, params: { view: "gallery" }
expect(response.body).to include("No file available")
end
it "shows appropriate message in table view" do
get :index, params: { view: "table" }
expect(response.body).to include("(none)")
end
end
end
end
end