Merge pull request #2882 from techAPJ/patch-1

FEATURE: show raw email for replies/topics created via email
This commit is contained in:
Régis Hanol 2014-10-18 21:16:17 +02:00
commit c59e56ec63
17 changed files with 118 additions and 2 deletions

View File

@ -0,0 +1,24 @@
import ModalFunctionality from 'discourse/mixins/modal-functionality';
import ObjectController from 'discourse/controllers/object';
/**
This controller handles displaying of raw email
@class RawEmailController
@extends ObjectController
@namespace Discourse
@uses ModalFunctionality
@module Discourse
**/
export default ObjectController.extend(ModalFunctionality, {
raw_email: "",
loadRawEmail: function(postId) {
var self = this;
Discourse.Post.loadRawEmail(postId).then(function (raw_email) {
self.set("raw_email", raw_email);
});
}
});

View File

@ -64,6 +64,10 @@ Discourse.Post = Discourse.Model.extend({
hasHistory: Em.computed.gt('version', 1),
postElementId: Discourse.computed.fmt('post_number', 'post_%@'),
canViewRawEmail: function() {
return Discourse.User.currentProp('staff');
}.property(),
bookmarkedChanged: function() {
Discourse.Post.bookmark(this.get('id'), this.get('bookmarked'))
.then(null, function (error) {
@ -486,6 +490,12 @@ Discourse.Post.reopenClass({
});
},
loadRawEmail: function(postId) {
return Discourse.ajax("/posts/" + postId + "/raw-email").then(function (result) {
return result.raw_email;
});
},
load: function(postId) {
return Discourse.ajax("/posts/" + postId + ".json").then(function (result) {
return Discourse.Post.create(result);

View File

@ -73,6 +73,11 @@ Discourse.TopicRoute = Discourse.Route.extend({
this.controllerFor('modal').set('modalClass', 'history-modal');
},
showRawEmail: function(post) {
Discourse.Route.showModal(this, 'raw-email', post);
this.controllerFor('raw_email').loadRawEmail(post.get("id"));
},
mergeTopic: function() {
Discourse.Route.showModal(this, 'mergeTopic', this.modelFor('topic'));
},

View File

@ -0,0 +1,7 @@
<div class="modal-body">
{{#if raw_email}}
<pre><code>{{raw_email}}</code></pre>
{{else}}
{{i18n raw_email.not_available}}
{{/if}}
</div>

View File

@ -53,7 +53,11 @@
<div class="post-info wiki" title="{{i18n post.wiki.about}}" {{action "editPost" this}}><i class="fa fa-pencil-square-o"></i></div>
{{/if}}
{{#if via_email}}
<div class="post-info via-email" title="{{i18n post.via_email}}"><i class="fa fa-envelope-o"></i></div>
{{#if canViewRawEmail}}
<div class="post-info via-email raw-email" title="{{i18n post.via_email}}" {{action "showRawEmail" this}}><i class="fa fa-envelope-o"></i></div>
{{else}}
<div class="post-info via-email" title="{{i18n post.via_email}}"><i class="fa fa-envelope-o"></i></div>
{{/if}}
{{/if}}
<div {{bind-attr class=":read-state read"}} title="{{i18n post.unread}}"><i class='fa fa-circle'></i></div>
</div>

View File

@ -0,0 +1,9 @@
export default Discourse.ModalBodyView.extend({
templateName: 'modal/raw_email',
title: I18n.t('raw_email.title'),
resizeModal: function(){
var viewPortHeight = $(window).height();
this.$(".modal-body").css("max-height", Math.floor(0.8 * viewPortHeight) + "px");
}.on("didInsertElement")
});

View File

@ -135,6 +135,9 @@ aside.quote {
&.via-email {
color: scale-color($primary, $lightness: 70%);
}
&.raw-email {
cursor: pointer;
}
}

View File

@ -30,6 +30,12 @@ class PostsController < ApplicationController
render json: {cooked: post.cooked}
end
def raw_email
guardian.ensure_can_view_raw_email!
post = Post.find(params[:id].to_i)
render json: {raw_email: post.raw_email}
end
def short_link
post = Post.find(params[:post_id].to_i)
# Stuff the user in the request object, because that's what IncomingLink wants

View File

@ -606,6 +606,8 @@ end
# version :integer default(1), not null
# cook_method :integer default(1), not null
# wiki :boolean default(FALSE), not null
# via_email :boolean default(FALSE), not null
# raw_email :text
# baked_at :datetime
# baked_version :integer
# hidden_at :datetime

View File

@ -1384,6 +1384,10 @@ en:
history: "History"
changed_by: "by {{author}}"
raw_email:
title: "Raw Email"
not_available: "Not available!"
categories_list: "Categories List"
filters:

View File

@ -416,6 +416,7 @@ Discourse::Application.routes.draw do
get "/posts/:id/cooked" => "posts#cooked"
get "/posts/:id/expand-embed" => "posts#expand_embed"
get "/posts/:id/raw" => "posts#markdown_id"
get "/posts/:id/raw-email" => "posts#raw_email"
get "raw/:topic_id(/:post_number)" => "posts#markdown_num"
resources :invites do

View File

@ -0,0 +1,5 @@
class AddRawEmailToPosts < ActiveRecord::Migration
def change
add_column :posts, :raw_email, :text
end
end

View File

@ -245,6 +245,7 @@ module Email
def create_post(user, options)
# Mark the reply as incoming via email
options[:via_email] = true
options[:raw_email] = @raw
creator = PostCreator.new(user, options)
post = creator.create

View File

@ -193,6 +193,10 @@ module PostGuardian
is_staff?
end
def can_view_raw_email?
is_staff?
end
def can_unhide?(post)
post.try(:hidden) && is_staff?
end

View File

@ -223,7 +223,7 @@ class PostCreator
reply_to_post_number: @opts[:reply_to_post_number])
# Attributes we pass through to the post instance if present
[:post_type, :no_bump, :cooking_options, :image_sizes, :acting_user, :invalidate_oneboxes, :cook_method, :via_email].each do |a|
[:post_type, :no_bump, :cooking_options, :image_sizes, :acting_user, :invalidate_oneboxes, :cook_method, :via_email, :raw_email].each do |a|
post.send("#{a}=", @opts[a]) if @opts[a].present?
end

View File

@ -146,6 +146,7 @@ Pleasure to have you here!
topic.posts.count.should == (start_count + 1)
created_post = topic.posts.last
created_post.via_email.should == true
created_post.raw_email.should == fixture_file("emails/valid_reply.eml")
created_post.cooked.strip.should == fixture_file("emails/valid_reply.cooked").strip
end
end

View File

@ -68,6 +68,36 @@ describe PostsController do
end
end
describe 'raw_email' do
include_examples "action requires login", :get, :raw_email, id: 2
describe "when logged in" do
let(:user) {log_in}
let(:post) {Fabricate(:post, user: user, raw_email: 'email_content')}
it "raises an error if the user doesn't have permission to view raw email" do
Guardian.any_instance.expects(:can_view_raw_email?).returns(false)
xhr :get, :raw_email, id: post.id
response.should be_forbidden
end
it "can view raw email" do
Guardian.any_instance.expects(:can_view_raw_email?).returns(true)
xhr :get, :raw_email, id: post.id
response.should be_success
json = ::JSON.parse(response.body)
json.should be_present
json['raw_email'].should == 'email_content'
end
end
end
describe 'show' do
include_examples 'finding and showing post' do
let(:action) { :show }