| 
				
				
				
				 | 
			
			 | 
			@@ -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 |