|
- require 'open-uri'
- require 'nokogiri'
-
-
- class PostsController < ApplicationController
- before_action :set_post, only: %i[ show update destroy ]
-
- # GET /posts
- def index
- if params[:tags].present?
- tag_names = params[:tags].split(',')
- match_type = params[:match]
- if match_type == 'any'
- posts = Post.joins(:tags).where(tags: { name: tag_names }).distinct
- else
- posts = Post.joins(:tags)
- tag_names.each do |tag|
- posts = posts.where(id: Post.joins(:tags).where(tags: { name: tag }))
- end
- posts = posts.distinct
- end
- else
- posts = Post.all
- end
- 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
- .as_json(include: { tags: { only: [:id, :name, :category] } })
- .merge(viewed: viewed))
- end
-
- # POST /posts
- def create
- 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: # 既知サイトなら決まったフォーマットで 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: 既知ドメインであれば指定のアドレスからサムネールを取得するやぅにする.
- 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)
- end
- render json: post, status: :created
- else
- render json: { errors: post.errors.full_messages }, status: :unprocessable_entity
- end
- end
-
- def viewed
- return head :unauthorized unless current_user
-
- current_user.viewed_posts << Post.find(params[:id])
- head :no_content
- end
-
- def unviewed
- return head :unauthorized unless current_user
-
- current_user.viewed_posts.delete(Post.find(params[:id]))
- head :no_content
- end
-
- # PATCH/PUT /posts/1
- def update
- if @post.update(post_params)
- render json: @post
- else
- render json: @post.errors, status: :unprocessable_entity
- end
- end
-
- # DELETE /posts/1
- def destroy
- @post.destroy!
- 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
- end
|