Commit d7243971 authored by theworldbright's avatar theworldbright Committed by Jonne Haß
Browse files

Refactor posts controller

parent b9bc20c7
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -38,13 +38,6 @@ app.models.Post = Backbone.Model.extend(_.extend({}, app.models.formatDateMixin,
             .done(function(){ app.events.trigger('person:block:'+personId); });
  },

  toggleFavorite : function(options){
    this.set({favorite : !this.get("favorite")});

    /* guard against attempting to save a model that a user doesn't own */
    if(options.save){ this.save() }
  },

  headline : function() {
    var headline = this.get("text").trim()
      , newlineIdx = headline.indexOf("\n");
+25 −59
Original line number Diff line number Diff line
@@ -5,94 +5,60 @@
class PostsController < ApplicationController
  include PostsHelper

  before_action :authenticate_user!, :except => [:show, :iframe, :oembed, :interactions]
  before_action :set_format_if_malformed_from_status_net, :only => :show
  before_action :find_post, :only => [:show, :interactions]
  before_action :authenticate_user!, only: :destroy
  before_action :set_format_if_malformed_from_status_net, only: :show

  respond_to :html,
             :mobile,
             :json,
             :xml
  respond_to :html, :mobile, :json, :xml

  rescue_from Diaspora::NonPublic do |exception|
  rescue_from Diaspora::NonPublic do |_exception|
    respond_to do |format|
      format.all { render :template=>'errors/not_public', :status=>404, :layout => "application"}
      format.all { render template: "errors/not_public", status: 404, layout: "application" }
    end
  end

  def show
    mark_corresponding_notifications_read if user_signed_in?

    post_service = PostService.new(id: params[:id], user: current_user)
    post_service.assign_post_and_mark_notifications
    @post = post_service.post
    respond_to do |format|
      format.html {
        gon.post = PostPresenter.new(@post, current_user)
        render "posts/show"
      }
      format.html { gon.post = post_service.present_json }
      format.xml { render xml: @post.to_diaspora_xml }
      format.mobile { render "posts/show" }
      format.json { render json: PostPresenter.new(@post, current_user) }
      format.json { render json: post_service.present_json }
    end
  end

  def iframe
    render :text => post_iframe_url(params[:id]), :layout => false
    render text: post_iframe_url(params[:id]), layout: false
  end

  def oembed
    post_id = OEmbedPresenter.id_from_url(params.delete(:url))
    post = Post.find_by_guid_or_id_with_user(post_id, current_user)
    if post.present?
      oembed = OEmbedPresenter.new(post, params.slice(:format, :maxheight, :minheight))
      render :json => oembed
    else
      render :nothing => true, :status => 404
    end
    post_service = PostService.new(id: post_id, user: current_user,
                                    oembed: params.slice(:format, :maxheight, :minheight))
    post_service.assign_post
    render json: post_service.present_oembed
  end

  def interactions
    respond_with(PostInteractionPresenter.new(@post, current_user))
    post_service = PostService.new(id: params[:id], user: current_user)
    post_service.assign_post
    respond_with(post_service.present_interactions_json)
  end

  def destroy
    find_current_user_post(params[:id])
    current_user.retract(@post)

    post_service = PostService.new(id: params[:id], user: current_user)
    post_service.retract_post
    @post = post_service.post
    respond_to do |format|
      format.js { render 'destroy',:layout => false, :format => :js }
      format.json { render :nothing => true, :status => 204 }
      format.js { render "destroy", layout: false, format: :js }
      format.json { render nothing: true, status: 204 }
      format.any { redirect_to stream_path }
    end
  end

  def update
    find_current_user_post(params[:id])
    @post.favorite = !@post.favorite
    @post.save
    render :nothing => true, :status => 202
  end

  protected

  def find_post #checks whether current user can see it
    @post = Post.find_by_guid_or_id_with_user(params[:id], current_user)
  end

  def find_current_user_post(id) #makes sure current_user can modify
    @post = current_user.posts.find(id)
  end
  private

  def set_format_if_malformed_from_status_net
   request.format = :html if request.format == 'application/html+xml'
  end

  def mark_corresponding_notifications_read
    # For comments, reshares, likes
    Notification.where(recipient_id: current_user.id, target_type: "Post", target_id: @post.id, unread: true).each do |n|
      n.set_read_state( true )
    end

    # For mentions
    mention = @post.mentions.where(person_id: current_user.person_id).first
    Notification.where(recipient_id: current_user.id, target_type: "Mention", target_id: mention.id, unread: true).first.try(:set_read_state, true) if mention
    request.format = :html if request.format == "application/html+xml"
  end
end
+11 −10
Original line number Diff line number Diff line
@@ -148,17 +148,18 @@ class Post < ActiveRecord::Base
    self.author.profile.nsfw?
  end

  def self.find_by_guid_or_id_with_user(id, user=nil)
    key = id.to_s.length <= 8 ? :id : :guid
    post = if user
             user.find_visible_shareable_by_id(Post, id, :key => key)
           else
             Post.where(key => id).includes(:author, :comments => :author).first
  def self.find_public(id)
    post = Post.where(Post.key_sym(id) => id).includes(:author, comments: :author).first
    post.try(:public?) || raise(Diaspora::NonPublic)
    post || raise(ActiveRecord::RecordNotFound.new("could not find a post with id #{id}"))
  end

    # is that a private post?
    raise(Diaspora::NonPublic) unless user || post.try(:public?)

  def self.find_non_public_by_guid_or_id_with_user(id, user)
    post = user.find_visible_shareable_by_id(Post, id, key: Post.key_sym(id))
    post || raise(ActiveRecord::RecordNotFound.new("could not find a post with id #{id}"))
  end

  def self.key_sym(id)
    id.to_s.length <= 8 ? :id : :guid
  end
end
+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ class PostInteractionPresenter
    }
  end

  private

  def participations
    return @post.participations.none unless @current_user
    @post.participations.where(author: @current_user.person)
+65 −0
Original line number Diff line number Diff line
class PostService
  attr_reader :post

  def initialize(params)
    @id = params[:id]
    @user = params[:user]
    @oembed = params[:oembed]
  end

  def present_json
    PostPresenter.new(post, user)
  end

  def present_interactions_json
    PostInteractionPresenter.new(post, user)
  end

  def present_oembed
    OEmbedPresenter.new(post, oembed)
  end

  def assign_post_and_mark_notifications
    assign_post
    mark_corresponding_notifications_read if user
  end

  def assign_post
    if user
      @post = Post.find_non_public_by_guid_or_id_with_user(id, user)
    else
      @post = Post.find_public(id)
    end
  end

  def retract_post
    find_user_post
    user.retract(@post)
  end

  private

  attr_reader :user, :id, :oembed

  def find_user_post
    @post = user.posts.find(id)
  end

  def mark_corresponding_notifications_read
    mark_comment_reshare_like_notifications_read
    mark_mention_notifications_read
  end

  def mark_comment_reshare_like_notifications_read
    notification = Notification.where(recipient_id: user.id, target_type: "Post", target_id: post.id, unread: true)
    notification.each do |notification|
      notification.set_read_state(true)
    end
  end

  def mark_mention_notifications_read
    mention = post.mentions.where(person_id: user.person_id).first
    Notification.where(recipient_id: user.id, target_type: "Mention", target_id: mention.id, unread: true)
      .first.try(:set_read_state, true) if mention
  end
end
Loading