#14 共通のサムネとタイトルの取得は完成

This commit is contained in:
2025-06-04 01:17:43 +09:00
parent 0afba7f345
commit 7719a9ea9d
8 changed files with 1221 additions and 26 deletions
+45 -24
View File
@@ -1,3 +1,7 @@
require 'open-uri'
require 'nokogiri'
class PostsController < ApplicationController
before_action :set_post, only: %i[ show update destroy ]
@@ -7,48 +11,64 @@ class PostsController < ApplicationController
tag_names = params[:tags].split(',')
match_type = params[:match]
if match_type == 'any'
@posts = Post.joins(:tags).where(tags: { name: tag_names }).distinct
posts = Post.joins(:tags).where(tags: { name: tag_names }).distinct
else
@posts = Post.joins(:tags)
posts = Post.joins(:tags)
tag_names.each do |tag|
@posts = @posts.where(id: Post.joins(:tags).where(tags: { name: tag }))
posts = posts.where(id: Post.joins(:tags).where(tags: { name: tag }))
end
@posts = @posts.distinct
posts = posts.distinct
end
else
@posts = Post.all
posts = Post.all
end
render json: @posts.as_json(include: { tags: { only: [:id, :name, :category] } })
render json: posts.as_json(include: { tags: { only: [:id, :name, :category] } })
end
# GET /posts/1
def show
@post = Post.includes(:tags).find(params[:id])
viewed = current_user&.viewed?(@post)
render json: (@post
post = Post.includes(:tags).find(params[:id])
viewed = current_user&.viewed?(post)
render json: (post
.as_json(include: { tags: { only: [:id, :name, :category] } })
.merge(viewed: viewed))
end
# POST /posts
def create
# TODO: current_user.role が 'admin' もしくは 'member' でなければ 403
return head :unauthorized unless current_user
return head :forbidden unless ['admin', 'member'].include?(current_user.role)
# TODO: URL が正規のものがチェック,不正ならエラー
title = params[:title]
unless title.present?
# TODO:
# 既知サイトなら決まったフォーマットで,
# 未知サイトならページ名をセットする.
# TODO: # 既知サイトなら決まったフォーマットで title 取得するやぅに.
begin
html = URI.open(params[:url], open_timeout: 5, read_timeout: 5).read
doc = Nokogiri::HTML.parse(html)
title = doc.at('title')&.text&.strip || ''
rescue
title = ''
end
end
post = Post.new(title: title, url: params[:url], thumbnail_base: '', uploaded_user: current_user)
if params[:thumbnail].present?
post.thumbnail.attach(params[:thumbnail])
else
# TODO:
# 既知ドメインであれば,指定のアドレスからサムネール取得,
# それ以外なら URL のスクショ・イメージをサムネールに登録.
# TODO: 既知ドメインであれば指定のアドレスからサムネールを取得するやぅにする.
path = Rails.root.join('tmp', "thumb_#{ SecureRandom.hex }.png")
system("node #{ Rails.root }/lib/screenshot.js #{ Shellwords.escape(params[:url]) } #{ path }")
if File.exist?(path)
image = MiniMagick::Image.open(path)
image.resize '180x180'
post.thumbnail.attach(io: File.open(image.path),
filename: 'thumbnail.png',
content_type: 'image/png')
File.delete(path) rescue nil
end
end
if post.save
post.resized_thumbnail!
if params[:tags].present?
tag_ids = JSON.parse(params[:tags])
post.tags = Tag.where(id: tag_ids)
@@ -88,13 +108,14 @@ class PostsController < ApplicationController
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params.expect(:id))
end
# Only allow a list of trusted parameters through.
def post_params
params.expect(post: [ :title, :body ])
end
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params.expect(:id))
end
# Only allow a list of trusted parameters through.
def post_params
params.expect(post: [ :title, :body ])
end
end