diff --git a/app/controllers/media_assets_controller.rb b/app/controllers/media_assets_controller.rb new file mode 100644 index 000000000..cd8c37c91 --- /dev/null +++ b/app/controllers/media_assets_controller.rb @@ -0,0 +1,8 @@ +class MediaAssetsController < ApplicationController + respond_to :json, :xml + + def index + @media_assets = authorize MediaAsset.visible(CurrentUser.user).paginated_search(params, count_pages: true) + respond_with(@media_assets) + end +end diff --git a/app/logical/upload_service.rb b/app/logical/upload_service.rb index 12e95d90f..5279d0325 100644 --- a/app/logical/upload_service.rb +++ b/app/logical/upload_service.rb @@ -104,6 +104,13 @@ class UploadService p.uploader_id = upload.uploader_id p.uploader_ip_addr = upload.uploader_ip_addr p.parent_id = upload.parent_id + p.media_asset = MediaAsset.new( + md5: upload.md5, + file_ext: upload.file_ext, + file_size: upload.file_size, + image_width: upload.image_width, + image_height: upload.image_height, + ) if !upload.uploader.can_upload_free? || upload.upload_as_pending? p.is_pending = true diff --git a/app/models/media_asset.rb b/app/models/media_asset.rb new file mode 100644 index 000000000..5dd15c7ba --- /dev/null +++ b/app/models/media_asset.rb @@ -0,0 +1,7 @@ +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 = q.apply_default_order(params) + q + end +end diff --git a/app/models/post.rb b/app/models/post.rb index c578326ae..40babeb7e 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -40,6 +40,7 @@ class Post < ApplicationRecord belongs_to :approver, class_name: "User", optional: true belongs_to :uploader, :class_name => "User", :counter_cache => "post_upload_count" belongs_to :parent, class_name: "Post", optional: true + has_one :media_asset, foreign_key: :md5, primary_key: :md5 has_one :upload, :dependent => :destroy has_one :artist_commentary, :dependent => :destroy has_one :pixiv_ugoira_frame_data, :class_name => "PixivUgoiraFrameData", :dependent => :destroy diff --git a/app/policies/media_asset_policy.rb b/app/policies/media_asset_policy.rb new file mode 100644 index 000000000..ebef2da96 --- /dev/null +++ b/app/policies/media_asset_policy.rb @@ -0,0 +1,5 @@ +class MediaAssetPolicy < ApplicationPolicy + def index? + true + end +end diff --git a/config/routes.rb b/config/routes.rb index d15d2e9e7..c63eb34f6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -154,6 +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 :mod_actions resources :moderation_reports, only: [:new, :create, :index, :show] resources :modqueue, only: [:index] diff --git a/db/migrate/20210901230931_create_media_assets.rb b/db/migrate/20210901230931_create_media_assets.rb new file mode 100644 index 000000000..035da53d4 --- /dev/null +++ b/db/migrate/20210901230931_create_media_assets.rb @@ -0,0 +1,19 @@ +class CreateMediaAssets < ActiveRecord::Migration[6.1] + def change + create_table :media_assets do |t| + t.timestamps null: false, index: true + + t.string :md5, null: false, index: true, unique: true + t.string :file_ext, null: false, index: true + t.integer :file_size, null: false, index: true + t.integer :image_width, null: false, index: true + t.integer :image_height, null: false, index: true + end + + reversible do |dir| + dir.up do + execute "INSERT INTO media_assets (created_at, updated_at, md5, file_ext, file_size, image_width, image_height) SELECT created_at, created_at AS updated_at, md5, file_ext, file_size, image_width, image_height FROM posts ORDER BY id ASC" + end + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 4325545d1..464cdcc52 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2461,6 +2461,41 @@ CREATE SEQUENCE public.ip_geolocations_id_seq ALTER SEQUENCE public.ip_geolocations_id_seq OWNED BY public.ip_geolocations.id; +-- +-- Name: media_assets; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.media_assets ( + id bigint NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL, + md5 character varying NOT NULL, + file_ext character varying NOT NULL, + file_size integer NOT NULL, + image_width integer NOT NULL, + image_height integer NOT NULL +); + + +-- +-- Name: media_assets_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.media_assets_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: media_assets_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.media_assets_id_seq OWNED BY public.media_assets.id; + + -- -- Name: mod_actions; Type: TABLE; Schema: public; Owner: - -- @@ -4279,6 +4314,13 @@ ALTER TABLE ONLY public.ip_bans ALTER COLUMN id SET DEFAULT nextval('public.ip_b ALTER TABLE ONLY public.ip_geolocations ALTER COLUMN id SET DEFAULT nextval('public.ip_geolocations_id_seq'::regclass); +-- +-- Name: media_assets id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.media_assets ALTER COLUMN id SET DEFAULT nextval('public.media_assets_id_seq'::regclass); + + -- -- Name: mod_actions id; Type: DEFAULT; Schema: public; Owner: - -- @@ -4659,6 +4701,14 @@ ALTER TABLE ONLY public.ip_geolocations ADD CONSTRAINT ip_geolocations_pkey PRIMARY KEY (id); +-- +-- Name: media_assets media_assets_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.media_assets + ADD CONSTRAINT media_assets_pkey PRIMARY KEY (id); + + -- -- Name: mod_actions mod_actions_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -6935,6 +6985,55 @@ CREATE INDEX index_ip_geolocations_on_time_zone ON public.ip_geolocations USING CREATE INDEX index_ip_geolocations_on_updated_at ON public.ip_geolocations USING btree (updated_at); +-- +-- Name: index_media_assets_on_created_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_media_assets_on_created_at ON public.media_assets USING btree (created_at); + + +-- +-- Name: index_media_assets_on_file_ext; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_media_assets_on_file_ext ON public.media_assets USING btree (file_ext); + + +-- +-- Name: index_media_assets_on_file_size; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_media_assets_on_file_size ON public.media_assets USING btree (file_size); + + +-- +-- Name: index_media_assets_on_image_height; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_media_assets_on_image_height ON public.media_assets USING btree (image_height); + + +-- +-- Name: index_media_assets_on_image_width; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_media_assets_on_image_width ON public.media_assets USING btree (image_width); + + +-- +-- Name: index_media_assets_on_md5; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_media_assets_on_md5 ON public.media_assets USING btree (md5); + + +-- +-- Name: index_media_assets_on_updated_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_media_assets_on_updated_at ON public.media_assets USING btree (updated_at); + + -- -- Name: index_mod_actions_on_created_at; Type: INDEX; Schema: public; Owner: - -- @@ -8016,5 +8115,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20210310221248'), ('20210330003356'), ('20210330093133'); +('20210901230931'); diff --git a/test/factories/media_asset.rb b/test/factories/media_asset.rb new file mode 100644 index 000000000..9fe45e086 --- /dev/null +++ b/test/factories/media_asset.rb @@ -0,0 +1,9 @@ +FactoryBot.define do + factory(:media_asset) do + md5 { SecureRandom.hex(32) } + file_ext { "jpg" } + file_size { 1_000_000 } + image_width { 1000 } + image_height { 1000 } + end +end diff --git a/test/functional/media_assets_controller_test.rb b/test/functional/media_assets_controller_test.rb new file mode 100644 index 000000000..a652dc9d6 --- /dev/null +++ b/test/functional/media_assets_controller_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +class MediaAssetsControllerTest < ActionDispatch::IntegrationTest + context "The media assets controller" do + context "index action" do + should "render" do + create(:media_asset) + get media_assets_path, as: :json + + assert_response :success + end + end + end +end diff --git a/test/unit/upload_service_test.rb b/test/unit/upload_service_test.rb index 2828b30ab..3b9de7c70 100644 --- a/test/unit/upload_service_test.rb +++ b/test/unit/upload_service_test.rb @@ -937,6 +937,17 @@ class UploadServiceTest < ActiveSupport::TestCase assert_equal([], post.errors.full_messages) assert_not_nil(post.id) end + + should "create a media asset" do + post = subject.new({}).create_post_from_upload(@upload) + + assert_not_nil(post.media_asset) + assert_equal("12345", post.media_asset.md5) + assert_equal("jpg", post.media_asset.file_ext) + assert_equal(1000, post.media_asset.file_size) + assert_equal(100, post.media_asset.image_width) + assert_equal(100, post.media_asset.image_height) + end end end