Track times individual images have been seen

This commit is contained in:
Donovan Daniels 2024-10-24 01:36:13 -05:00
parent 73ec849903
commit 7aac4f7e72
Signed by: Donovan_DMC
GPG Key ID: 907D29CBFD6157BA
9 changed files with 50 additions and 7 deletions

View File

@ -89,7 +89,6 @@ module YiffRest
end
def iqdb
@sp = {}
end
def query_iqdb
@ -108,6 +107,14 @@ module YiffRest
render(:index)
end
def leaderboard
@list = APIImage.all_seen.sort_by(&:second).reverse.to_h
@keys = @list.map(&:first)
@results = APIImage.where(id: @keys).sort_by { |img| @keys.index(img.md5) }
@pagy, @images = pagy_array(@results, size: [1, 2, 2, 1])
render(:index)
end
private
def load_category

View File

@ -32,6 +32,9 @@ module YiffRest
r.incr("yiffy2:stats:images:ip:#{request.remote_ip}:#{category}")
r.incr("yiffy2:stats:images:total")
r.incr("yiffy2:stats:images:total:#{category}")
images.each do |img|
r.incr("yiffy2:stats:image:#{img.md5}")
end
if @apikey.present? && !@apikey&.is_anon?
r.incr("yiffy2:stats:images:key:#{@apikey.id}")
r.incr("yiffy2:stats:images:key:#{@apikey.id}:#{category}")
@ -123,6 +126,9 @@ module YiffRest
r.incr("yiffy2:stats:images:total:bulk")
r.incrby("yiffy2:stats:images:key:#{@apikey.id}", total)
r.incr("yiffy2:stats:images:key:#{@apikey.id}:bulk")
images.each do |img|
r.incr("yiffy2:stats:image:#{img.md5}")
end
req.each do |category, amount|
r.incrby("yiffy2:stats:images:#{category}", amount.to_i)
r.incr("yiffy2:stats:images:#{category}:bulk")
@ -168,6 +174,7 @@ module YiffRest
end
def execute_webhook(category, bulk_categories = nil)
return unless Rails.env.production?
bulk = ""
color = 0x008000
if bulk_categories.present?

View File

@ -177,6 +177,7 @@ class APIImage < ApplicationRecord
shortURL: short_url,
external: true,
viewable: is_viewable?,
seen: seen,
}
end
@ -198,6 +199,7 @@ class APIImage < ApplicationRecord
shortURL: short_url,
external: false,
viewable: is_viewable?,
seen: seen,
}
end
@ -457,6 +459,26 @@ class APIImage < ApplicationRecord
IqdbRemoveJob.perform_now(iqdb_id)
end
def seen
Cache.fetch("img:#{md5}", expires_in: 1.minute) do
(Cache.redis.get("yiffy2:stats:image:#{md5}").presence || 0).to_i
end
end
def self.all_seen
Cache.fetch("img:all_seen", expires_in: 10.minutes) do
keys = all.map { |img| "yiffy2:stats:image:#{img.md5}" }
values = Cache.redis.mget(*keys)
results = {}
keys.each_with_index do |key, index|
val = values.at(index)
next if val.nil?
results[key[-32..]] = val.to_i
end
results
end
end
def self.create_external!(type, id, category)
site = ExternalAPIImage::SITES.find { |s| s.value == type }
raise(Error, "Invalid site: #{type}") if site.blank?

View File

@ -14,7 +14,7 @@
<ul class="details">
<li>Resolution: <b><%= external.width %>x<%= external.height %></b></li>
<% if image.md5 != external.md5 %>
<li>ID: <b><%= image.md5 %></li>
<li>ID: <b><%= image.md5 %></b></li>
<% end %>
<li>MD5: <b><%= external.md5 %></b></li>
<li>Type: <b><%= external.ext %></b></li>
@ -22,13 +22,18 @@
<li>Creator: <b><%= image.creator.name %></b></li>
<li>Created At: <b><%= compact_time(image.created_at) %></b></li>
<li>Updated At: <b><%= compact_time(image.updated_at) %></b></li>
<% unless @sp[:category].present? %>
<% unless @sp.try(:[], :category).present? %>
<li>Category: <b><%= image.category %></b></li>
<% end %>
<li>
Upload Type: <b>external</b>
</li>
<li>Viewable: <b class="<%= image.is_viewable? ? "green-text" : "red-text" %>"><%= image.is_viewable? ? "Yes" : "No" %></b></li>
<% if params[:action] == "leaderboard" %>
<li>Times Seen: <b><%= @list.try(:[], image.md5).presence || image.seen %></b></li>
<% else %>
<li>Times Seen: <b><%= image.seen %></b></li>
<% end %>
</ul>
</td>
<td>

View File

@ -15,7 +15,7 @@
<li>Creator: <b><%= image.creator.name %></b></li>
<li>Created At: <b><%= compact_time(image.created_at) %></b></li>
<li>Updated At: <b><%= compact_time(image.updated_at) %></b></li>
<% unless @sp[:category].present? %>
<% unless @sp.try(:[], :category).present? %>
<li>Category: <b><%= image.category %></b></li>
<% end %>
<li>
@ -27,6 +27,7 @@
<% end %>
</li>
<li>Viewable: <b class="<%= image.is_viewable? ? "green-text" : "red-text" %>"><%= image.is_viewable? ? "Yes" : "No" %></b></li>
<li>Times Seen: <b><%= image.seen %></b></li>
</ul>
</td>
<td>

View File

@ -26,7 +26,7 @@
</div>
<footer class="bg-dark pt-3 fixed-bottom">
<div class=" d-flex align-items-center justify-content-center">
<div class="d-flex align-items-center justify-content-center">
<%== pagy_bootstrap_nav(@pagy) if @pagy.pages > 1 %>
</div>
</footer>

View File

@ -9,7 +9,7 @@
<div style="width: 40%; margin-left: 30%;">
<%= simple_form_for(:api_image, url: create_external_yiff_rest_api_v2_manage_images_path, method: :post) do |f| %>
<%= f.input(:site, label: "Site", as: :select, selected: params.dig(:api_image, :site), collection: ExternalAPIImage::SITES.map { |s| [s.name, s.value] }, include_blank: true) %>
<%= f.input(:external_id, input_html: { value: params.dig(:api_image, :external_id) }) %>
<%= f.input(:external_id, label: "External ID", input_html: { value: params.dig(:api_image, :external_id) }) %>
<%= f.input(:category, as: :select, selected: params.dig(:api_image, :category), collection: @categories.map { |cat| [cat.name, cat.db] }, include_blank: true) %>
<%= f.button(:submit, "Upload Image", name: nil) %>
<% end %>

View File

@ -18,7 +18,7 @@
<% elsif params[:controller] == "yiff_rest/api_v2/images" %>
<% if %w[index iqdb query_iqdb].include?(params[:action]) %>
<li class="nav-item">
<%= link_to("Upload Image", new_yiff_rest_api_v2_manage_image_path(api_image: ({ category: @sp[:category] } if @sp[:category])), class: "nav-link#{if_active(' active', path: new_yiff_rest_api_v2_manage_image_path)}") %>
<%= link_to("Upload Image", new_yiff_rest_api_v2_manage_image_path(api_image: ({ category: @sp[:category] } if @sp.try(:[], :category).present?)), class: "nav-link#{if_active(' active', path: new_yiff_rest_api_v2_manage_image_path)}") %>
</li>
<% else %>
<% category = params.dig(:api_image, :category) if params[:action] == "new" %>

View File

@ -60,6 +60,7 @@ module YiffRestRoutes
put(:update_cache)
end
collection do
get(:leaderboard)
get(:iqdb)
match("/iqdb/query", via: %i[get post], action: :query_iqdb)
post(:external, action: :create_external, as: "create_external")