/media_assets: add basic index and show pages.

* Add a basic index page at https://danbooru.donmai.us/media_assets.
* Add a basic show page at https://danbooru.donmai.us/media_assets/1.
* Add ability to search /media_assets.json by metadata. Example:
** https://danbooru.donmai.us/media_assets.json?search[metadata][File:ColorComponents]=3
* Add a "»" link next to the filesize on posts linking to the metadata page.

Known issues:

* Sometimes the MD5 links on the /media_assets page return "That record
  was not found" errors. These are unfinished uploads that haven't been
  made into posts yet.
* No good way to search for custom metadata fields in the search form.
* Design is ugly.
This commit is contained in:
evazion
2021-09-29 07:35:30 -05:00
parent 95fc3a207c
commit c99d0523bb
8 changed files with 94 additions and 6 deletions

View File

@@ -1,8 +1,15 @@
class MediaAssetsController < ApplicationController
respond_to :json, :xml
respond_to :html, :json, :xml
def index
@media_assets = authorize MediaAsset.visible(CurrentUser.user).paginated_search(params, count_pages: true)
@media_assets = authorize MediaAsset.visible(CurrentUser.user).paginated_search(params, count_pages: false)
@media_assets = @media_assets.joins(:media_metadata)
respond_with(@media_assets)
end
def show
@media_asset = authorize MediaAsset.find(params[:id])
@post = Post.find_by_md5(@media_asset.md5)
respond_with(@media_asset)
end
end

View File

@@ -8,7 +8,7 @@ $spacer: 0.25rem; /* 4px */
.invisible { visibility: hidden; }
.visible { visibility: visible; }
.font-monospace { font-family: var(--monospace-font); }
.font-monospace { font: var(--monospace-font); }
.font-bold { font-weight: bold; }
.inline-block { display: inline-block; }

View File

@@ -11,7 +11,12 @@ class MediaAsset < ApplicationRecord
}
def self.search(params)
q = search_attributes(params, :id, :created_at, :updated_at, :md5, :file_ext, :file_size, :image_width, :image_height)
q = search_attributes(params, :id, :created_at, :updated_at, :md5, :file_ext, :file_size, :image_width, :image_height, :media_metadata)
if params[:metadata].present?
q = q.joins(:media_metadata).merge(MediaMetadata.search(metadata: params[:metadata]))
end
q.apply_default_order(params)
end

View File

@@ -0,0 +1,39 @@
<div id="c-media-assets">
<div id="a-index">
<%= search_form_for(media_assets_path) do |f| %>
<%= f.input :md5, input_html: { value: params[:search][:md5] } %>
<%= f.input :image_width, input_html: { value: params[:search][:image_width] } %>
<%= f.input :image_height, input_html: { value: params[:search][:image_height] } %>
<%= f.input :file_size, input_html: { value: params[:search][:file_size] } %>
<%= f.input :file_ext, input_html: { value: params[:search][:file_ext] } %>
<%= f.simple_fields_for :metadata do |meta| %>
<% params.dig(:search, :metadata).to_h.each do |key, value| %>
<%= meta.input key, label: key, input_html: { value: value } %>
<% end %>
<% end %>
<%= f.submit "Search" %>
<% end %>
<%= table_for @media_assets, class: "striped autofit" do |t| %>
<% t.column "MD5", td: { class: "font-monospace" } do |media_asset| %>
<%= link_to media_asset.md5, posts_path(md5: media_asset.md5) %>
<% end %>
<% t.column :image_width %>
<% t.column :image_height %>
<% t.column :file_size %>
<% t.column :file_ext %>
<% t.column "Metadata" do |media_asset| %>
<%= link_to pluralize(media_asset.metadata.size, "tags"), media_asset %>
<% end %>
<% t.column "Created" do |media_asset| %>
<%= time_ago_in_words_tagged(media_asset.created_at) %>
<% end %>
<% end %>
<%= numbered_paginator(@media_assets) %>
</div>
</div>

View File

@@ -0,0 +1,20 @@
<div id="c-media-assets">
<div id="a-show" class="fixed-width-container">
<h1 class="mb-4">Media Asset</h1>
<% if @post.present? %>
<%= post_preview(@post, show_deleted: true) %>
<% else %>
<p>MD5: <%= link_to @media_asset.md5, posts_path(md5: @media_asset.md5) %></p>
<% end %>
<table class="striped aligned-vertical">
<% @media_asset.metadata.sort.each do |key, value| %>
<tr>
<th><%= key %></th>
<td><%= link_to value, media_assets_path(search: { metadata: { key => value }}) %></td>
</tr>
<% end %>
</table>
</div>
</div>

View File

@@ -16,6 +16,7 @@
<li id="post-info-size">
Size: <%= link_to_if policy(post).visible?, "#{number_to_human_size(post.file_size)} .#{post.file_ext}", post.tagged_file_url %>
(<%= post.image_width %>x<%= post.image_height %>)
<%= link_to "»", @post.media_asset %>
</li>
<li id="post-info-source">Source: <%= post_source_tag(post.source, post.normalized_source) %></li>
<li id="post-info-rating">Rating: <%= post.pretty_rating %></li>

View File

@@ -154,7 +154,7 @@ Rails.application.routes.draw do
get :check, to: redirect {|path_params, req| "/iqdb_queries?#{req.query_string}"}
end
end
resources :media_assets, only: [:index]
resources :media_assets, only: [:index, :show]
resources :media_metadata, only: [:index]
resources :mod_actions
resources :moderation_reports, only: [:new, :create, :index, :show]

View File

@@ -3,12 +3,28 @@ require 'test_helper'
class MediaAssetsControllerTest < ActionDispatch::IntegrationTest
context "The media assets controller" do
context "index action" do
setup do
@media_asset = create(:media_asset)
end
should "render" do
create(:media_asset)
get media_assets_path, as: :json
assert_response :success
end
should respond_to_search({}).with { @media_asset }
should respond_to_search(metadata: { "File:ColorComponents" => 3 }).with { @media_asset }
should respond_to_search(metadata: { "File:ColorComponents" => 4 }).with { [] }
end
context "show action" do
should "render" do
@media_asset = create(:media_asset)
get media_asset_path(@media_asset), as: :json
assert_response :success
end
end
end
end