mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-30 10:58:31 -05:00
FEATURE: better email in support
FEATURE: new incoming_email model FEATURE: infinite scrolling in emails admin FEATURE: new 'emails:import' rake task
This commit is contained in:
parent
d0bcea3411
commit
3083657358
119 changed files with 1560 additions and 4408 deletions
|
@ -1,3 +0,0 @@
|
||||||
import AdminEmailSkippedController from "admin/controllers/admin-email-skipped";
|
|
||||||
|
|
||||||
export default AdminEmailSkippedController.extend();
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import IncomingEmail from 'admin/models/incoming-email';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
loadMore() {
|
||||||
|
return IncomingEmail.findAll(this.get("filter"), this.get("model.length"))
|
||||||
|
.then(incoming => {
|
||||||
|
if (incoming.length < 50) { this.get("model").set("allLoaded", true); }
|
||||||
|
this.get("model").addObjects(incoming);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,11 @@
|
||||||
|
import EmailLog from 'admin/models/email-log';
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
loadMore() {
|
||||||
|
return EmailLog.findAll(this.get("filter"), this.get("model.length"))
|
||||||
|
.then(logs => {
|
||||||
|
if (logs.length < 50) { this.get("model").set("allLoaded", true); }
|
||||||
|
this.get("model").addObjects(logs);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
import AdminEmailIncomingsController from 'admin/controllers/admin-email-incomings';
|
||||||
|
import debounce from 'discourse/lib/debounce';
|
||||||
|
import IncomingEmail from 'admin/models/incoming-email';
|
||||||
|
|
||||||
|
export default AdminEmailIncomingsController.extend({
|
||||||
|
filterIncomingEmails: debounce(function() {
|
||||||
|
IncomingEmail.findAll(this.get("filter")).then(incomings => this.set("model", incomings));
|
||||||
|
}, 250).observes("filter.{from,to,subject}")
|
||||||
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
import AdminEmailIncomingsController from 'admin/controllers/admin-email-incomings';
|
||||||
|
import debounce from 'discourse/lib/debounce';
|
||||||
|
import IncomingEmail from 'admin/models/incoming-email';
|
||||||
|
|
||||||
|
export default AdminEmailIncomingsController.extend({
|
||||||
|
filterIncomingEmails: debounce(function() {
|
||||||
|
IncomingEmail.findAll(this.get("filter")).then(incomings => this.set("model", incomings));
|
||||||
|
}, 250).observes("filter.{from,to,subject,error}")
|
||||||
|
});
|
|
@ -1,12 +1,9 @@
|
||||||
|
import AdminEmailLogsController from 'admin/controllers/admin-email-logs';
|
||||||
import debounce from 'discourse/lib/debounce';
|
import debounce from 'discourse/lib/debounce';
|
||||||
import EmailLog from 'admin/models/email-log';
|
import EmailLog from 'admin/models/email-log';
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default AdminEmailLogsController.extend({
|
||||||
|
|
||||||
filterEmailLogs: debounce(function() {
|
filterEmailLogs: debounce(function() {
|
||||||
var self = this;
|
EmailLog.findAll(this.get("filter")).then(logs => this.set("model", logs));
|
||||||
EmailLog.findAll(this.get("filter")).then(function(logs) {
|
}, 250).observes("filter.{user,address,type,reply_key}")
|
||||||
self.set("model", logs);
|
|
||||||
});
|
|
||||||
}, 250).observes("filter.user", "filter.address", "filter.type", "filter.reply_key")
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
import AdminEmailLogsController from 'admin/controllers/admin-email-logs';
|
||||||
import debounce from 'discourse/lib/debounce';
|
import debounce from 'discourse/lib/debounce';
|
||||||
|
import EmailLog from 'admin/models/email-log';
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default AdminEmailLogsController.extend({
|
||||||
filterEmailLogs: debounce(function() {
|
filterEmailLogs: debounce(function() {
|
||||||
const EmailLog = require('admin/models/email-log').default;
|
|
||||||
EmailLog.findAll(this.get("filter")).then(logs => this.set("model", logs));
|
EmailLog.findAll(this.get("filter")).then(logs => this.set("model", logs));
|
||||||
}, 250).observes("filter.user", "filter.address", "filter.type", "filter.skipped_reason")
|
}, 250).observes("filter.{user,address,type,skipped_reason}")
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@ const EmailLog = Discourse.Model.extend({});
|
||||||
|
|
||||||
EmailLog.reopenClass({
|
EmailLog.reopenClass({
|
||||||
|
|
||||||
create: function(attrs) {
|
create(attrs) {
|
||||||
attrs = attrs || {};
|
attrs = attrs || {};
|
||||||
|
|
||||||
if (attrs.user) {
|
if (attrs.user) {
|
||||||
|
@ -14,16 +14,15 @@ EmailLog.reopenClass({
|
||||||
return this._super(attrs);
|
return this._super(attrs);
|
||||||
},
|
},
|
||||||
|
|
||||||
findAll: function(filter) {
|
findAll(filter, offset) {
|
||||||
filter = filter || {};
|
filter = filter || {};
|
||||||
var status = filter.status || "all";
|
offset = offset || 0;
|
||||||
|
|
||||||
|
const status = filter.status || "sent";
|
||||||
filter = _.omit(filter, "status");
|
filter = _.omit(filter, "status");
|
||||||
|
|
||||||
return Discourse.ajax("/admin/email/" + status + ".json", { data: filter }).then(function(logs) {
|
return Discourse.ajax(`/admin/email/${status}.json?offset=${offset}`, { data: filter })
|
||||||
return _.map(logs, function (log) {
|
.then(logs => _.map(logs, log => EmailLog.create(log)));
|
||||||
return EmailLog.create(log);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
29
app/assets/javascripts/admin/models/incoming-email.js.es6
Normal file
29
app/assets/javascripts/admin/models/incoming-email.js.es6
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import AdminUser from 'admin/models/admin-user';
|
||||||
|
|
||||||
|
const IncomingEmail = Discourse.Model.extend({});
|
||||||
|
|
||||||
|
IncomingEmail.reopenClass({
|
||||||
|
|
||||||
|
create(attrs) {
|
||||||
|
attrs = attrs || {};
|
||||||
|
|
||||||
|
if (attrs.user) {
|
||||||
|
attrs.user = AdminUser.create(attrs.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._super(attrs);
|
||||||
|
},
|
||||||
|
|
||||||
|
findAll(filter, offset) {
|
||||||
|
filter = filter || {};
|
||||||
|
offset = offset || 0;
|
||||||
|
|
||||||
|
const status = filter.status || "received";
|
||||||
|
filter = _.omit(filter, "status");
|
||||||
|
|
||||||
|
return Discourse.ajax(`/admin/email/${status}.json?offset=${offset}`, { data: filter })
|
||||||
|
.then(incomings => _.map(incomings, incoming => IncomingEmail.create(incoming)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default IncomingEmail;
|
|
@ -1,2 +0,0 @@
|
||||||
import AdminEmailLogs from 'admin/routes/admin-email-logs';
|
|
||||||
export default AdminEmailLogs.extend({ status: "all" });
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import IncomingEmail from 'admin/models/incoming-email';
|
||||||
|
|
||||||
|
export default Discourse.Route.extend({
|
||||||
|
|
||||||
|
model() {
|
||||||
|
return IncomingEmail.findAll({ status: this.get("status") });
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController(controller, model) {
|
||||||
|
controller.set("model", model);
|
||||||
|
controller.set("filter", { status: this.get("status") });
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -1,11 +1,11 @@
|
||||||
import EmailSettings from 'admin/models/email-settings';
|
import EmailSettings from 'admin/models/email-settings';
|
||||||
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
model: function() {
|
model() {
|
||||||
return EmailSettings.find();
|
return EmailSettings.find();
|
||||||
},
|
},
|
||||||
|
|
||||||
renderTemplate: function() {
|
renderTemplate() {
|
||||||
this.render('admin/templates/email_index', { into: 'adminEmail' });
|
this.render('admin/templates/email_index', { into: 'adminEmail' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,27 +1,14 @@
|
||||||
import EmailLog from 'admin/models/email-log';
|
import EmailLog from 'admin/models/email-log';
|
||||||
|
|
||||||
/**
|
|
||||||
Handles routes related to viewing email logs.
|
|
||||||
|
|
||||||
@class AdminEmailSentRoute
|
|
||||||
@extends Discourse.Route
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
|
|
||||||
model: function() {
|
model() {
|
||||||
return EmailLog.findAll({ status: this.get("status") });
|
return EmailLog.findAll({ status: this.get("status") });
|
||||||
},
|
},
|
||||||
|
|
||||||
setupController: function(controller, model) {
|
setupController(controller, model) {
|
||||||
controller.set("model", model);
|
controller.set("model", model);
|
||||||
// resets the filters
|
|
||||||
controller.set("filter", { status: this.get("status") });
|
controller.set("filter", { status: this.get("status") });
|
||||||
},
|
|
||||||
|
|
||||||
renderTemplate: function() {
|
|
||||||
this.render("admin/templates/email_" + this.get("status"), { into: "adminEmail" });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
import AdminEmailIncomings from 'admin/routes/admin-email-incomings';
|
||||||
|
export default AdminEmailIncomings.extend({ status: "received" });
|
|
@ -0,0 +1,2 @@
|
||||||
|
import AdminEmailIncomings from 'admin/routes/admin-email-incomings';
|
||||||
|
export default AdminEmailIncomings.extend({ status: "rejected" });
|
|
@ -8,9 +8,10 @@ export default {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resource('adminEmail', { path: '/email'}, function() {
|
this.resource('adminEmail', { path: '/email'}, function() {
|
||||||
this.route('all');
|
|
||||||
this.route('sent');
|
this.route('sent');
|
||||||
this.route('skipped');
|
this.route('skipped');
|
||||||
|
this.route('received');
|
||||||
|
this.route('rejected');
|
||||||
this.route('previewDigest', { path: '/preview-digest' });
|
this.route('previewDigest', { path: '/preview-digest' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
55
app/assets/javascripts/admin/templates/email-received.hbs
Normal file
55
app/assets/javascripts/admin/templates/email-received.hbs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<table class='table email-list'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n 'admin.email.time'}}</th>
|
||||||
|
<th>{{i18n 'admin.email.incoming_emails.from_address'}}</th>
|
||||||
|
<th>{{i18n 'admin.email.incoming_emails.to_addresses'}}</th>
|
||||||
|
<th>{{i18n 'admin.email.incoming_emails.subject'}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tr class="filters">
|
||||||
|
<td>{{i18n 'admin.email.logs.filters.title'}}</td>
|
||||||
|
<td>{{text-field value=filter.from placeholderKey="admin.email.incoming_emails.filters.from_placeholder"}}</td>
|
||||||
|
<td>{{text-field value=filter.to placeholderKey="admin.email.incoming_emails.filters.to_placeholder"}}</td>
|
||||||
|
<td>{{text-field value=filter.subject placeholderKey="admin.email.incoming_emails.filters.subject_placeholder"}}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{{#each email in model}}
|
||||||
|
<tr>
|
||||||
|
<td class="time">{{format-date email.created_at}}</td>
|
||||||
|
<td class="username">
|
||||||
|
<div>
|
||||||
|
{{#if email.user}}
|
||||||
|
{{#link-to 'adminUser' email.user}}
|
||||||
|
{{avatar email.user imageSize="tiny"}}
|
||||||
|
{{email.from_address}}
|
||||||
|
{{/link-to}}
|
||||||
|
{{else}}
|
||||||
|
—
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="addresses">
|
||||||
|
{{#each to in email.to_addresses}}
|
||||||
|
<p><a href="mailto:{{unbound to}}" title="TO">{{unbound to}}</a></p>
|
||||||
|
{{/each}}
|
||||||
|
{{#each cc in email.cc_addresses}}
|
||||||
|
<p><a href="mailto:{{unbound cc}}" title="CC">{{unbound cc}}</a></p>
|
||||||
|
{{/each}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{#if email.post_url}}
|
||||||
|
<a href="{{email.post_url}}">{{email.subject}}</a>
|
||||||
|
{{else}}
|
||||||
|
{{email.subject}}
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td colspan="4">{{i18n 'admin.email.incoming_emails.none'}}</td></tr>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{{conditional-loading-spinner condition=view.loading}}
|
52
app/assets/javascripts/admin/templates/email-rejected.hbs
Normal file
52
app/assets/javascripts/admin/templates/email-rejected.hbs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<table class='table email-list'>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n 'admin.email.time'}}</th>
|
||||||
|
<th>{{i18n 'admin.email.incoming_emails.from_address'}}</th>
|
||||||
|
<th>{{i18n 'admin.email.incoming_emails.to_addresses'}}</th>
|
||||||
|
<th>{{i18n 'admin.email.incoming_emails.subject'}}</th>
|
||||||
|
<th>{{i18n 'admin.email.incoming_emails.error'}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tr class="filters">
|
||||||
|
<td>{{i18n 'admin.email.logs.filters.title'}}</td>
|
||||||
|
<td>{{text-field value=filter.from placeholderKey="admin.email.incoming_emails.filters.from_placeholder"}}</td>
|
||||||
|
<td>{{text-field value=filter.to placeholderKey="admin.email.incoming_emails.filters.to_placeholder"}}</td>
|
||||||
|
<td>{{text-field value=filter.subject placeholderKey="admin.email.incoming_emails.filters.subject_placeholder"}}</td>
|
||||||
|
<td>{{text-field value=filter.error placeholderKey="admin.email.incoming_emails.filters.error_placeholder"}}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{{#each email in model}}
|
||||||
|
<tr>
|
||||||
|
<td class="time">{{format-date email.created_at}}</td>
|
||||||
|
<td class="username">
|
||||||
|
<div>
|
||||||
|
{{#if email.user}}
|
||||||
|
{{#link-to 'adminUser' email.user}}
|
||||||
|
{{avatar email.user imageSize="tiny"}}
|
||||||
|
{{email.from_address}}
|
||||||
|
{{/link-to}}
|
||||||
|
{{else}}
|
||||||
|
—
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="addresses">
|
||||||
|
{{#each to in email.to_addresses}}
|
||||||
|
<p><a href="mailto:{{unbound to}}" title="TO">{{unbound to}}</a></p>
|
||||||
|
{{/each}}
|
||||||
|
{{#each cc in email.cc_addresses}}
|
||||||
|
<p><a href="mailto:{{unbound cc}}" title="CC">{{unbound cc}}</a></p>
|
||||||
|
{{/each}}
|
||||||
|
</td>
|
||||||
|
<td>{{email.subject}}</td>
|
||||||
|
<td class="error">{{email.error}}</td>
|
||||||
|
</tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td colspan="5">{{i18n 'admin.email.incoming_emails.none'}}</td></tr>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{{conditional-loading-spinner condition=view.loading}}
|
|
@ -1,4 +1,4 @@
|
||||||
<table class='table'>
|
<table class='table email-list'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.email.sent_at'}}</th>
|
<th>{{i18n 'admin.email.sent_at'}}</th>
|
||||||
|
@ -37,3 +37,5 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
{{conditional-loading-spinner condition=view.loading}}
|
|
@ -1,4 +1,4 @@
|
||||||
<table class='table'>
|
<table class='table email-list'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{i18n 'admin.email.time'}}</th>
|
<th>{{i18n 'admin.email.time'}}</th>
|
||||||
|
@ -37,3 +37,5 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
{{conditional-loading-spinner condition=view.loading}}
|
|
@ -1,10 +1,11 @@
|
||||||
{{#admin-nav}}
|
{{#admin-nav}}
|
||||||
{{nav-item route='adminEmail.index' label='admin.email.settings'}}
|
{{nav-item route='adminEmail.index' label='admin.email.settings'}}
|
||||||
{{nav-item route='adminEmail.all' label='admin.email.all'}}
|
{{nav-item route='adminEmail.previewDigest' label='admin.email.preview_digest'}}
|
||||||
|
{{nav-item route='adminCustomizeEmailTemplates' label='admin.email.templates'}}
|
||||||
{{nav-item route='adminEmail.sent' label='admin.email.sent'}}
|
{{nav-item route='adminEmail.sent' label='admin.email.sent'}}
|
||||||
{{nav-item route='adminEmail.skipped' label='admin.email.skipped'}}
|
{{nav-item route='adminEmail.skipped' label='admin.email.skipped'}}
|
||||||
{{nav-item route='adminEmail.previewDigest' label='admin.email.preview_digest'}}
|
{{nav-item route='adminEmail.received' label='admin.email.received'}}
|
||||||
{{nav-item route='adminCustomizeEmailTemplates' label='admin.customize.email_templates.title'}}
|
{{nav-item route='adminEmail.rejected' label='admin.email.rejected'}}
|
||||||
{{/admin-nav}}
|
{{/admin-nav}}
|
||||||
|
|
||||||
<div class="admin-container">
|
<div class="admin-container">
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
<table class='table'>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>{{i18n 'admin.email.time'}}</th>
|
|
||||||
<th>{{i18n 'admin.email.user'}}</th>
|
|
||||||
<th>{{i18n 'admin.email.to_address'}}</th>
|
|
||||||
<th>{{i18n 'admin.email.email_type'}}</th>
|
|
||||||
<th>{{i18n 'admin.email.skipped_reason'}}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tr class="filters">
|
|
||||||
<td>{{i18n 'admin.email.logs.filters.title'}}</td>
|
|
||||||
<td>{{text-field value=filter.user placeholderKey="admin.email.logs.filters.user_placeholder"}}</td>
|
|
||||||
<td>{{text-field value=filter.address placeholderKey="admin.email.logs.filters.address_placeholder"}}</td>
|
|
||||||
<td>{{text-field value=filter.type placeholderKey="admin.email.logs.filters.type_placeholder"}}</td>
|
|
||||||
<td>{{text-field value=filter.skipped_reason placeholderKey="admin.email.logs.filters.skipped_reason_placeholder"}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
{{#each l in model}}
|
|
||||||
<tr>
|
|
||||||
<td>{{format-date l.created_at}}</td>
|
|
||||||
<td>
|
|
||||||
{{#if l.user}}
|
|
||||||
{{#link-to 'adminUser' l.user}}{{avatar l.user imageSize="tiny"}}{{/link-to}}
|
|
||||||
{{#link-to 'adminUser' l.user}}{{l.user.username}}{{/link-to}}
|
|
||||||
{{else}}
|
|
||||||
—
|
|
||||||
{{/if}}
|
|
||||||
</td>
|
|
||||||
<td><a href='mailto:{{unbound l.to_address}}'>{{l.to_address}}</a></td>
|
|
||||||
<td>{{l.email_type}}</td>
|
|
||||||
<td>{{l.skipped_reason}}</td>
|
|
||||||
</tr>
|
|
||||||
{{else}}
|
|
||||||
<tr><td colspan="5">{{i18n 'admin.email.logs.none'}}</td></tr>
|
|
||||||
{{/each}}
|
|
||||||
|
|
||||||
</table>
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import LoadMore from "discourse/mixins/load-more";
|
||||||
|
|
||||||
|
export default Ember.View.extend(LoadMore, {
|
||||||
|
loading: false,
|
||||||
|
eyelineSelector: ".email-list tr",
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
loadMore() {
|
||||||
|
if (this.get("loading") || this.get("model.allLoaded")) { return; }
|
||||||
|
this.set("loading", true);
|
||||||
|
return this.get("controller").loadMore().then(() => this.set("loading", false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
14
app/assets/javascripts/admin/views/admin-email-logs.js.es6
Normal file
14
app/assets/javascripts/admin/views/admin-email-logs.js.es6
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import LoadMore from "discourse/mixins/load-more";
|
||||||
|
|
||||||
|
export default Ember.View.extend(LoadMore, {
|
||||||
|
loading: false,
|
||||||
|
eyelineSelector: ".email-list tr",
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
loadMore() {
|
||||||
|
if (this.get("loading") || this.get("model.allLoaded")) { return; }
|
||||||
|
this.set("loading", true);
|
||||||
|
return this.get("controller").loadMore().then(() => this.set("loading", false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
import AdminEmailIncomingsView from "admin/views/admin-email-incomings";
|
||||||
|
|
||||||
|
export default AdminEmailIncomingsView.extend({
|
||||||
|
templateName: "admin/templates/email-received"
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
import AdminEmailIncomingsView from "admin/views/admin-email-incomings";
|
||||||
|
|
||||||
|
export default AdminEmailIncomingsView.extend({
|
||||||
|
templateName: "admin/templates/email-rejected"
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
import AdminEmailLogsView from "admin/views/admin-email-logs";
|
||||||
|
|
||||||
|
export default AdminEmailLogsView.extend({
|
||||||
|
templateName: "admin/templates/email-sent"
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
import AdminEmailLogsView from "admin/views/admin-email-logs";
|
||||||
|
|
||||||
|
export default AdminEmailLogsView.extend({
|
||||||
|
templateName: "admin/templates/email-skipped"
|
||||||
|
});
|
|
@ -1769,6 +1769,30 @@ table#user-badges {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emails
|
||||||
|
|
||||||
|
.email-list {
|
||||||
|
.filters input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
.username div {
|
||||||
|
max-width: 180px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.addresses p {
|
||||||
|
margin: 2px 0;
|
||||||
|
max-width: 200px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mobile specific styles
|
// Mobile specific styles
|
||||||
// Mobile view text-inputs need some padding
|
// Mobile view text-inputs need some padding
|
||||||
.mobile-view .admin-contents {
|
.mobile-view .admin-contents {
|
||||||
|
|
|
@ -17,11 +17,6 @@ class Admin::EmailController < Admin::AdminController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def all
|
|
||||||
email_logs = filter_email_logs(EmailLog.all, params)
|
|
||||||
render_serialized(email_logs, EmailLogSerializer)
|
|
||||||
end
|
|
||||||
|
|
||||||
def sent
|
def sent
|
||||||
email_logs = filter_email_logs(EmailLog.sent, params)
|
email_logs = filter_email_logs(EmailLog.sent, params)
|
||||||
render_serialized(email_logs, EmailLogSerializer)
|
render_serialized(email_logs, EmailLogSerializer)
|
||||||
|
@ -32,6 +27,16 @@ class Admin::EmailController < Admin::AdminController
|
||||||
render_serialized(email_logs, EmailLogSerializer)
|
render_serialized(email_logs, EmailLogSerializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def received
|
||||||
|
incoming_emails = filter_incoming_emails(IncomingEmail, params)
|
||||||
|
render_serialized(incoming_emails, IncomingEmailSerializer)
|
||||||
|
end
|
||||||
|
|
||||||
|
def rejected
|
||||||
|
incoming_emails = filter_incoming_emails(IncomingEmail.errored, params)
|
||||||
|
render_serialized(incoming_emails, IncomingEmailSerializer)
|
||||||
|
end
|
||||||
|
|
||||||
def preview_digest
|
def preview_digest
|
||||||
params.require(:last_seen_at)
|
params.require(:last_seen_at)
|
||||||
params.require(:username)
|
params.require(:username)
|
||||||
|
@ -49,13 +54,33 @@ class Admin::EmailController < Admin::AdminController
|
||||||
private
|
private
|
||||||
|
|
||||||
def filter_email_logs(email_logs, params)
|
def filter_email_logs(email_logs, params)
|
||||||
email_logs = email_logs.limit(50).includes(:user).order("email_logs.created_at desc").references(:user)
|
email_logs = email_logs.includes(:user)
|
||||||
email_logs = email_logs.where("users.username LIKE ?", "%#{params[:user]}%") if params[:user].present?
|
.references(:user)
|
||||||
email_logs = email_logs.where("email_logs.to_address LIKE ?", "%#{params[:address]}%") if params[:address].present?
|
.order(created_at: :desc)
|
||||||
email_logs = email_logs.where("email_logs.email_type LIKE ?", "%#{params[:type]}%") if params[:type].present?
|
.offset(params[:offset] || 0)
|
||||||
email_logs = email_logs.where("email_logs.reply_key LIKE ?", "%#{params[:reply_key]}%") if params[:reply_key].present?
|
.limit(50)
|
||||||
email_logs = email_logs.where("email_logs.skipped_reason LIKE ?", "%#{params[:skipped_reason]}%") if params[:skipped_reason].present?
|
|
||||||
email_logs.to_a
|
email_logs = email_logs.where("users.username ILIKE ?", "%#{params[:user]}%") if params[:user].present?
|
||||||
|
email_logs = email_logs.where("email_logs.to_address ILIKE ?", "%#{params[:address]}%") if params[:address].present?
|
||||||
|
email_logs = email_logs.where("email_logs.email_type ILIKE ?", "%#{params[:type]}%") if params[:type].present?
|
||||||
|
email_logs = email_logs.where("email_logs.reply_key ILIKE ?", "%#{params[:reply_key]}%") if params[:reply_key].present?
|
||||||
|
email_logs = email_logs.where("email_logs.skipped_reason ILIKE ?", "%#{params[:skipped_reason]}%") if params[:skipped_reason].present?
|
||||||
|
|
||||||
|
email_logs
|
||||||
|
end
|
||||||
|
|
||||||
|
def filter_incoming_emails(incoming_emails, params)
|
||||||
|
incoming_emails = incoming_emails.includes(:user, { post: :topic })
|
||||||
|
.order(created_at: :desc)
|
||||||
|
.offset(params[:offset] || 0)
|
||||||
|
.limit(50)
|
||||||
|
|
||||||
|
incoming_emails = incoming_emails.where("from_address ILIKE ?", "%#{params[:from]}%") if params[:from].present?
|
||||||
|
incoming_emails = incoming_emails.where("to_addresses ILIKE ? OR cc_addresses ILIKE ?", "%#{params[:to]}%") if params[:to].present?
|
||||||
|
incoming_emails = incoming_emails.where("subject ILIKE ?", "%#{params[:subject]}%") if params[:subject].present?
|
||||||
|
incoming_emails = incoming_emails.where("error ILIKE ?", "%#{params[:error]}%") if params[:error].present?
|
||||||
|
|
||||||
|
incoming_emails
|
||||||
end
|
end
|
||||||
|
|
||||||
def delivery_settings
|
def delivery_settings
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
#
|
|
||||||
# Connects to a mailbox and checks for replies
|
|
||||||
#
|
|
||||||
require 'net/pop'
|
require 'net/pop'
|
||||||
require_dependency 'email/receiver'
|
require_dependency 'email/receiver'
|
||||||
require_dependency 'email/sender'
|
require_dependency 'email/sender'
|
||||||
|
@ -10,6 +7,7 @@ module Jobs
|
||||||
class PollMailbox < Jobs::Scheduled
|
class PollMailbox < Jobs::Scheduled
|
||||||
every SiteSetting.pop3_polling_period_mins.minutes
|
every SiteSetting.pop3_polling_period_mins.minutes
|
||||||
sidekiq_options retry: false
|
sidekiq_options retry: false
|
||||||
|
|
||||||
include Email::BuildEmailHelper
|
include Email::BuildEmailHelper
|
||||||
|
|
||||||
def execute(args)
|
def execute(args)
|
||||||
|
@ -17,53 +15,42 @@ module Jobs
|
||||||
poll_pop3 if SiteSetting.pop3_polling_enabled?
|
poll_pop3 if SiteSetting.pop3_polling_enabled?
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_mail(mail)
|
def process_popmail(popmail)
|
||||||
begin
|
begin
|
||||||
mail_string = mail.pop
|
mail_string = popmail.pop
|
||||||
Email::Receiver.new(mail_string).process
|
Email::Receiver.new(mail_string).process
|
||||||
rescue => e
|
rescue => e
|
||||||
handle_failure(mail_string, e)
|
handle_failure(mail_string, e)
|
||||||
ensure
|
|
||||||
mail.delete
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_failure(mail_string, e)
|
def handle_failure(mail_string, e)
|
||||||
Rails.logger.warn("Email can not be processed: #{e}\n\n#{mail_string}") if SiteSetting.log_mail_processing_failures
|
Rails.logger.warn("Email can not be processed: #{e}\n\n#{mail_string}") if SiteSetting.log_mail_processing_failures
|
||||||
|
|
||||||
template_args = {}
|
message_template = case e
|
||||||
case e
|
when Email::Receiver::EmptyEmailError then :email_reject_empty
|
||||||
when Email::Receiver::UserNotSufficientTrustLevelError
|
when Email::Receiver::NoBodyDetectedError then :email_reject_empty
|
||||||
message_template = :email_reject_trust_level
|
when Email::Receiver::NoMessageIdError then :email_reject_no_message_id
|
||||||
when Email::Receiver::UserNotFoundError
|
when Email::Receiver::AutoGeneratedEmailError then :email_reject_auto_generated
|
||||||
message_template = :email_reject_no_account
|
when Email::Receiver::InactiveUserError then :email_reject_inactive_user
|
||||||
when Email::Receiver::EmptyEmailError
|
when Email::Receiver::BadDestinationAddress then :email_reject_bad_destination_address
|
||||||
message_template = :email_reject_empty
|
when Email::Receiver::StrangersNotAllowedError then :email_reject_strangers_not_allowed
|
||||||
when Email::Receiver::EmailUnparsableError
|
when Email::Receiver::InsufficientTrustLevelError then :email_reject_insufficient_trust_level
|
||||||
message_template = :email_reject_parsing
|
when Email::Receiver::ReplyUserNotMatchingError then :email_reject_reply_user_not_matching
|
||||||
when Email::Receiver::EmailLogNotFound
|
when Email::Receiver::TopicNotFoundError then :email_reject_topic_not_found
|
||||||
message_template = :email_reject_reply_key
|
when Email::Receiver::TopicClosedError then :email_reject_topic_closed
|
||||||
when Email::Receiver::BadDestinationAddress
|
when Email::Receiver::InvalidPost then :email_reject_invalid_post
|
||||||
message_template = :email_reject_destination
|
when ActiveRecord::Rollback then :email_reject_invalid_post
|
||||||
when Email::Receiver::TopicNotFoundError
|
when Email::Receiver::InvalidPostAction then :email_reject_invalid_post_action
|
||||||
message_template = :email_reject_topic_not_found
|
when Discourse::InvalidAccess then :email_reject_invalid_access
|
||||||
when Email::Receiver::TopicClosedError
|
|
||||||
message_template = :email_reject_topic_closed
|
|
||||||
when Email::Receiver::AutoGeneratedEmailError
|
|
||||||
message_template = :email_reject_auto_generated
|
|
||||||
when Discourse::InvalidAccess
|
|
||||||
message_template = :email_reject_invalid_access
|
|
||||||
when ActiveRecord::Rollback
|
|
||||||
message_template = :email_reject_post_error
|
|
||||||
when Email::Receiver::InvalidPost
|
|
||||||
if e.message.length < 6
|
|
||||||
message_template = :email_reject_post_error
|
|
||||||
else
|
|
||||||
message_template = :email_reject_post_error_specified
|
|
||||||
template_args[:post_error] = e.message
|
|
||||||
end
|
end
|
||||||
else
|
|
||||||
message_template = nil
|
template_args = {}
|
||||||
|
|
||||||
|
# there might be more information available in the exception
|
||||||
|
if message_template == :email_reject_invalid_post && e.message.size > 6
|
||||||
|
message_template = :email_reject_invalid_post_specified
|
||||||
|
template_args[:post_error] = e.message
|
||||||
end
|
end
|
||||||
|
|
||||||
if message_template
|
if message_template
|
||||||
|
@ -81,19 +68,16 @@ module Jobs
|
||||||
end
|
end
|
||||||
|
|
||||||
def poll_pop3
|
def poll_pop3
|
||||||
connection = Net::POP3.new(SiteSetting.pop3_polling_host, SiteSetting.pop3_polling_port)
|
pop3 = Net::POP3.new(SiteSetting.pop3_polling_host, SiteSetting.pop3_polling_port)
|
||||||
connection.enable_ssl if SiteSetting.pop3_polling_ssl
|
pop3.enable_ssl if SiteSetting.pop3_polling_ssl
|
||||||
|
|
||||||
connection.start(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) do |pop|
|
pop3.start(SiteSetting.pop3_polling_username, SiteSetting.pop3_polling_password) do |pop|
|
||||||
unless pop.mails.empty?
|
pop.delete_all do |p|
|
||||||
pop.each { |mail| handle_mail(mail) }
|
process_popmail(p)
|
||||||
end
|
end
|
||||||
pop.finish
|
|
||||||
end
|
end
|
||||||
rescue Net::POPAuthenticationError => e
|
rescue Net::POPAuthenticationError => e
|
||||||
Discourse.handle_job_exception(e, error_context(@args, "Signing in to poll incoming email"))
|
Discourse.handle_job_exception(e, error_context(@args, "Signing in to poll incoming email"))
|
||||||
rescue Net::POPError => e
|
|
||||||
Discourse.handle_job_exception(e, error_context(@args, "Generic POP error"))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,13 +3,23 @@ require_dependency 'email/message_builder'
|
||||||
class RejectionMailer < ActionMailer::Base
|
class RejectionMailer < ActionMailer::Base
|
||||||
include Email::BuildEmailHelper
|
include Email::BuildEmailHelper
|
||||||
|
|
||||||
DISALLOWED_TEMPLATE_ARGS = [:to, :from, :base_url,
|
DISALLOWED_TEMPLATE_ARGS = [:to,
|
||||||
|
:from,
|
||||||
|
:base_url,
|
||||||
:user_preferences_url,
|
:user_preferences_url,
|
||||||
:include_respond_instructions, :html_override,
|
:include_respond_instructions,
|
||||||
:add_unsubscribe_link, :respond_instructions,
|
:html_override,
|
||||||
:style, :body, :post_id, :topic_id, :subject,
|
:add_unsubscribe_link,
|
||||||
:template, :allow_reply_by_email,
|
:respond_instructions,
|
||||||
:private_reply, :from_alias]
|
:style,
|
||||||
|
:body,
|
||||||
|
:post_id,
|
||||||
|
:topic_id,
|
||||||
|
:subject,
|
||||||
|
:template,
|
||||||
|
:allow_reply_by_email,
|
||||||
|
:private_reply,
|
||||||
|
:from_alias]
|
||||||
|
|
||||||
# Send an email rejection message.
|
# Send an email rejection message.
|
||||||
#
|
#
|
||||||
|
|
32
app/models/incoming_email.rb
Normal file
32
app/models/incoming_email.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
class IncomingEmail < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :topic
|
||||||
|
belongs_to :post
|
||||||
|
|
||||||
|
scope :errored, -> { where.not(error: nil) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: incoming_emails
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# user_id :integer
|
||||||
|
# topic_id :integer
|
||||||
|
# post_id :integer
|
||||||
|
# raw :text
|
||||||
|
# error :text
|
||||||
|
# message_id :text
|
||||||
|
# from_address :text
|
||||||
|
# to_addresses :text
|
||||||
|
# cc_addresses :text
|
||||||
|
# subject :text
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_incoming_emails_on_created_at (created_at)
|
||||||
|
# index_incoming_emails_on_error (error)
|
||||||
|
# index_incoming_emails_on_message_id (message_id)
|
||||||
|
#
|
|
@ -514,6 +514,12 @@ class Topic < ActiveRecord::Base
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def add_small_action(user, action_code, who=nil)
|
||||||
|
custom_fields = {}
|
||||||
|
custom_fields["action_code_who"] = who if who.present?
|
||||||
|
add_moderator_post(user, nil, post_type: Post.types[:small_action], action_code: action_code, custom_fields: custom_fields)
|
||||||
|
end
|
||||||
|
|
||||||
def add_moderator_post(user, text, opts=nil)
|
def add_moderator_post(user, text, opts=nil)
|
||||||
opts ||= {}
|
opts ||= {}
|
||||||
new_post = nil
|
new_post = nil
|
||||||
|
@ -562,14 +568,7 @@ class Topic < ActiveRecord::Base
|
||||||
topic_user = topic_allowed_users.find_by(user_id: user.id)
|
topic_user = topic_allowed_users.find_by(user_id: user.id)
|
||||||
if topic_user
|
if topic_user
|
||||||
topic_user.destroy
|
topic_user.destroy
|
||||||
# add small action
|
add_small_action(removed_by, "removed_user", user.username)
|
||||||
self.add_moderator_post(
|
|
||||||
removed_by,
|
|
||||||
nil,
|
|
||||||
post_type: Post.types[:small_action],
|
|
||||||
action_code: "removed_user",
|
|
||||||
custom_fields: { action_code_who: user.username }
|
|
||||||
)
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -584,13 +583,7 @@ class Topic < ActiveRecord::Base
|
||||||
user = User.find_by_username_or_email(username_or_email)
|
user = User.find_by_username_or_email(username_or_email)
|
||||||
if user && topic_allowed_users.create!(user_id: user.id)
|
if user && topic_allowed_users.create!(user_id: user.id)
|
||||||
# Create a small action message
|
# Create a small action message
|
||||||
self.add_moderator_post(
|
add_small_action(invited_by, "invited_user", user.username)
|
||||||
invited_by,
|
|
||||||
nil,
|
|
||||||
post_type: Post.types[:small_action],
|
|
||||||
action_code: "invited_user",
|
|
||||||
custom_fields: { action_code_who: user.username }
|
|
||||||
)
|
|
||||||
|
|
||||||
# Notify the user they've been invited
|
# Notify the user they've been invited
|
||||||
user.notifications.create(notification_type: Notification.types[:invited_to_private_message],
|
user.notifications.create(notification_type: Notification.types[:invited_to_private_message],
|
||||||
|
|
|
@ -169,8 +169,7 @@ class User < ActiveRecord::Base
|
||||||
|
|
||||||
def self.suggest_name(email)
|
def self.suggest_name(email)
|
||||||
return "" if email.blank?
|
return "" if email.blank?
|
||||||
name = email.split(/[@\+]/)[0].gsub(".", " ")
|
email[/\A[^@]+/].tr(".", " ").titleize
|
||||||
name.titleize
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_by_username_or_email(username_or_email)
|
def self.find_by_username_or_email(username_or_email)
|
||||||
|
|
32
app/serializers/incoming_email_serializer.rb
Normal file
32
app/serializers/incoming_email_serializer.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
class IncomingEmailSerializer < ApplicationSerializer
|
||||||
|
|
||||||
|
attributes :id,
|
||||||
|
:created_at,
|
||||||
|
:from_address,
|
||||||
|
:to_addresses,
|
||||||
|
:cc_addresses,
|
||||||
|
:subject,
|
||||||
|
:error,
|
||||||
|
:post_url
|
||||||
|
|
||||||
|
has_one :user, serializer: BasicUserSerializer, embed: :objects
|
||||||
|
|
||||||
|
def post_url
|
||||||
|
object.post.url
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_post_url?
|
||||||
|
object.post.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_addresses
|
||||||
|
return if object.to_addresses.blank?
|
||||||
|
object.to_addresses.split(";")
|
||||||
|
end
|
||||||
|
|
||||||
|
def cc_addresses
|
||||||
|
return if object.cc_addresses.blank?
|
||||||
|
object.cc_addresses.split(";")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -18,7 +18,8 @@ class SpamRule::AutoBlock
|
||||||
|
|
||||||
def block?
|
def block?
|
||||||
@user.blocked? or
|
@user.blocked? or
|
||||||
(!@user.has_trust_level?(TrustLevel[1]) and
|
(!@user.staged? and
|
||||||
|
!@user.has_trust_level?(TrustLevel[1]) and
|
||||||
SiteSetting.num_flags_to_block_new_user > 0 and
|
SiteSetting.num_flags_to_block_new_user > 0 and
|
||||||
SiteSetting.num_users_to_block_new_user > 0 and
|
SiteSetting.num_users_to_block_new_user > 0 and
|
||||||
num_spam_flags_against_user >= SiteSetting.num_flags_to_block_new_user and
|
num_spam_flags_against_user >= SiteSetting.num_flags_to_block_new_user and
|
||||||
|
|
|
@ -21,6 +21,8 @@ class SpamRule::FlagSockpuppets
|
||||||
|
|
||||||
!first_post.user.staff? &&
|
!first_post.user.staff? &&
|
||||||
!@post.user.staff? &&
|
!@post.user.staff? &&
|
||||||
|
!first_post.user.staged? &&
|
||||||
|
!@post.user.staged? &&
|
||||||
@post.user != first_post.user &&
|
@post.user != first_post.user &&
|
||||||
@post.user.ip_address == first_post.user.ip_address &&
|
@post.user.ip_address == first_post.user.ip_address &&
|
||||||
@post.user.new_user? &&
|
@post.user.new_user? &&
|
||||||
|
|
|
@ -2190,14 +2190,17 @@ en:
|
||||||
|
|
||||||
|
|
||||||
email:
|
email:
|
||||||
title: "Email"
|
title: "Emails"
|
||||||
settings: "Settings"
|
settings: "Settings"
|
||||||
all: "All"
|
templates: "Templates"
|
||||||
|
preview_digest: "Preview Digest"
|
||||||
sending_test: "Sending test Email..."
|
sending_test: "Sending test Email..."
|
||||||
error: "<b>ERROR</b> - %{server_error}"
|
error: "<b>ERROR</b> - %{server_error}"
|
||||||
test_error: "There was a problem sending the test email. Please double-check your mail settings, verify that your host is not blocking mail connections, and try again."
|
test_error: "There was a problem sending the test email. Please double-check your mail settings, verify that your host is not blocking mail connections, and try again."
|
||||||
sent: "Sent"
|
sent: "Sent"
|
||||||
skipped: "Skipped"
|
skipped: "Skipped"
|
||||||
|
received: "Received"
|
||||||
|
rejected: "Rejected"
|
||||||
sent_at: "Sent At"
|
sent_at: "Sent At"
|
||||||
time: "Time"
|
time: "Time"
|
||||||
user: "User"
|
user: "User"
|
||||||
|
@ -2207,7 +2210,6 @@ en:
|
||||||
send_test: "Send Test Email"
|
send_test: "Send Test Email"
|
||||||
sent_test: "sent!"
|
sent_test: "sent!"
|
||||||
delivery_method: "Delivery Method"
|
delivery_method: "Delivery Method"
|
||||||
preview_digest: "Preview Digest"
|
|
||||||
preview_digest_desc: "Preview the content of the digest emails sent to inactive users."
|
preview_digest_desc: "Preview the content of the digest emails sent to inactive users."
|
||||||
refresh: "Refresh"
|
refresh: "Refresh"
|
||||||
format: "Format"
|
format: "Format"
|
||||||
|
@ -2216,6 +2218,19 @@ en:
|
||||||
last_seen_user: "Last Seen User:"
|
last_seen_user: "Last Seen User:"
|
||||||
reply_key: "Reply Key"
|
reply_key: "Reply Key"
|
||||||
skipped_reason: "Skip Reason"
|
skipped_reason: "Skip Reason"
|
||||||
|
incoming_emails:
|
||||||
|
from_address: "From"
|
||||||
|
to_addresses: "To"
|
||||||
|
cc_addresses: "Cc"
|
||||||
|
subject: "Subject"
|
||||||
|
error: "Error"
|
||||||
|
none: "No incoming emails found."
|
||||||
|
filters:
|
||||||
|
from_placeholder: "from@example.com"
|
||||||
|
to_placeholder: "to@example.com"
|
||||||
|
cc_placeholder: "cc@example.com"
|
||||||
|
subject_placeholder: "Subject..."
|
||||||
|
error_placeholder: "Error"
|
||||||
logs:
|
logs:
|
||||||
none: "No logs found."
|
none: "No logs found."
|
||||||
filters:
|
filters:
|
||||||
|
|
|
@ -945,8 +945,6 @@ en:
|
||||||
verbose_localization: "Show extended localization tips in the UI"
|
verbose_localization: "Show extended localization tips in the UI"
|
||||||
previous_visit_timeout_hours: "How long a visit lasts before we consider it the 'previous' visit, in hours"
|
previous_visit_timeout_hours: "How long a visit lasts before we consider it the 'previous' visit, in hours"
|
||||||
|
|
||||||
allow_staged_accounts: "[BETA] Automatically create staged accounts for incoming emails."
|
|
||||||
|
|
||||||
rate_limit_create_topic: "After creating a topic, users must wait (n) seconds before creating another topic."
|
rate_limit_create_topic: "After creating a topic, users must wait (n) seconds before creating another topic."
|
||||||
rate_limit_create_post: "After posting, users must wait (n) seconds before creating another post."
|
rate_limit_create_post: "After posting, users must wait (n) seconds before creating another post."
|
||||||
rate_limit_new_user_create_topic: "After creating a topic, new users must wait (n) seconds before creating another topic."
|
rate_limit_new_user_create_topic: "After creating a topic, new users must wait (n) seconds before creating another topic."
|
||||||
|
@ -1744,13 +1742,34 @@ en:
|
||||||
subject_template: "Data export failed"
|
subject_template: "Data export failed"
|
||||||
text_body_template: "We're sorry, but your data export failed. Please check the logs or contact a staff member."
|
text_body_template: "We're sorry, but your data export failed. Please check the logs or contact a staff member."
|
||||||
|
|
||||||
email_reject_trust_level:
|
email_reject_insufficient_trust_level:
|
||||||
subject_template: "[%{site_name}] Email issue -- Insufficient Trust Level"
|
subject_template: "[%{site_name}] Email issue -- Insufficient Trust Level"
|
||||||
text_body_template: |
|
text_body_template: |
|
||||||
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
|
||||||
Your account does not have the required trust level to post new topics to this email address. If you believe this is in error, contact a staff member.
|
Your account does not have the required trust level to post new topics to this email address. If you believe this is in error, contact a staff member.
|
||||||
|
|
||||||
|
email_reject_inactive_user:
|
||||||
|
subject_template: "[%{site_name}] Email issue -- Inactive User"
|
||||||
|
text_body_template: |
|
||||||
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
|
||||||
|
Your account associated with this email address is not activated. Please activate your account before sending emails in.
|
||||||
|
|
||||||
|
email_reject_reply_user_not_matching:
|
||||||
|
subject_template: "[%{site_name}] Email issue -- Reply User Not Matching"
|
||||||
|
text_body_template: |
|
||||||
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
|
||||||
|
The original notification was not sent to this email address. Try sending from a different email address, or contact a staff member.
|
||||||
|
|
||||||
|
email_reject_no_message_id:
|
||||||
|
subject_template: "[%{site_name}] Email issue -- No Message Id"
|
||||||
|
text_body_template: |
|
||||||
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
|
||||||
|
There was no Message-Id header in the email. Try sending from a different email address, or contact a staff member.
|
||||||
|
|
||||||
email_reject_no_account:
|
email_reject_no_account:
|
||||||
subject_template: "[%{site_name}] Email issue -- Unknown Account"
|
subject_template: "[%{site_name}] Email issue -- Unknown Account"
|
||||||
text_body_template: |
|
text_body_template: |
|
||||||
|
@ -1781,14 +1800,21 @@ en:
|
||||||
|
|
||||||
Your account does not have the privileges to post new topics in that category. If you believe this is in error, contact a staff member.
|
Your account does not have the privileges to post new topics in that category. If you believe this is in error, contact a staff member.
|
||||||
|
|
||||||
email_reject_post_error:
|
email_reject_strangers_not_allowed:
|
||||||
|
subject_template: "[%{site_name}] Email issue -- Invalid Access"
|
||||||
|
text_body_template: |
|
||||||
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
|
||||||
|
The category you sent this email to does not allow emails from unrestricted accounts. If you believe this is in error, contact a staff member.
|
||||||
|
|
||||||
|
email_reject_invalid_post:
|
||||||
subject_template: "[%{site_name}] Email issue -- Posting error"
|
subject_template: "[%{site_name}] Email issue -- Posting error"
|
||||||
text_body_template: |
|
text_body_template: |
|
||||||
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
|
||||||
Some possible causes are: complex formatting, message too large, message too small. Please try again, or post via the website if this continues.
|
Some possible causes are: complex formatting, message too large, message too small. Please try again, or post via the website if this continues.
|
||||||
|
|
||||||
email_reject_post_error_specified:
|
email_reject_invalid_post_specified:
|
||||||
subject_template: "[%{site_name}] Email issue -- Posting error"
|
subject_template: "[%{site_name}] Email issue -- Posting error"
|
||||||
text_body_template: |
|
text_body_template: |
|
||||||
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
@ -1799,6 +1825,14 @@ en:
|
||||||
|
|
||||||
If you can correct the problem, please try again.
|
If you can correct the problem, please try again.
|
||||||
|
|
||||||
|
email_reject_invalid_post_action:
|
||||||
|
subject_template: "[%{site_name}] Email issue -- Invalid Post Action"
|
||||||
|
text_body_template: |
|
||||||
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
|
||||||
|
The Post Action was not recognized. Please try again, or post via the website if this continues.
|
||||||
|
|
||||||
|
|
||||||
email_reject_reply_key:
|
email_reject_reply_key:
|
||||||
subject_template: "[%{site_name}] Email issue -- Unknown Reply Key"
|
subject_template: "[%{site_name}] Email issue -- Unknown Reply Key"
|
||||||
text_body_template: |
|
text_body_template: |
|
||||||
|
@ -1806,12 +1840,12 @@ en:
|
||||||
|
|
||||||
The provided reply key is invalid or unknown, so we don't know what this email is in reply to. Contact a staff member.
|
The provided reply key is invalid or unknown, so we don't know what this email is in reply to. Contact a staff member.
|
||||||
|
|
||||||
email_reject_destination:
|
email_reject_bad_destination_address:
|
||||||
subject_template: "[%{site_name}] Email issue -- Unknown To: Address"
|
subject_template: "[%{site_name}] Email issue -- Unknown To: Address"
|
||||||
text_body_template: |
|
text_body_template: |
|
||||||
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||||
|
|
||||||
None of the destination addresses are recognized. Please make sure that the site address is in the To: line (not Cc: or Bcc:), and that you are sending to the correct email address provided by staff.
|
None of the destination addresses are recognized. Please make sure that you are sending to the correct email address provided by staff.
|
||||||
|
|
||||||
email_reject_topic_not_found:
|
email_reject_topic_not_found:
|
||||||
subject_template: "[%{site_name}] Email issue -- Topic Not Found"
|
subject_template: "[%{site_name}] Email issue -- Topic Not Found"
|
||||||
|
|
|
@ -119,9 +119,10 @@ Discourse::Application.routes.draw do
|
||||||
resources :email, constraints: AdminConstraint.new do
|
resources :email, constraints: AdminConstraint.new do
|
||||||
collection do
|
collection do
|
||||||
post "test"
|
post "test"
|
||||||
get "all"
|
|
||||||
get "sent"
|
get "sent"
|
||||||
get "skipped"
|
get "skipped"
|
||||||
|
get "received"
|
||||||
|
get "rejected"
|
||||||
get "preview-digest" => "email#preview_digest"
|
get "preview-digest" => "email#preview_digest"
|
||||||
post "handle_mail"
|
post "handle_mail"
|
||||||
end
|
end
|
||||||
|
|
|
@ -806,8 +806,6 @@ developer:
|
||||||
default: 500
|
default: 500
|
||||||
client: true
|
client: true
|
||||||
hidden: true
|
hidden: true
|
||||||
allow_staged_accounts:
|
|
||||||
default: false
|
|
||||||
|
|
||||||
embedding:
|
embedding:
|
||||||
feed_polling_enabled:
|
feed_polling_enabled:
|
||||||
|
|
|
@ -10,6 +10,6 @@ class DropGroupManagers < ActiveRecord::Migration
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
raise ActiveRecord::IrriversableMigration
|
raise ActiveRecord::IrreversibleMigration
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
24
db/migrate/20160113160742_create_incoming_emails.rb
Normal file
24
db/migrate/20160113160742_create_incoming_emails.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
class CreateIncomingEmails < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :incoming_emails do |t|
|
||||||
|
t.integer :user_id
|
||||||
|
t.integer :topic_id
|
||||||
|
t.integer :post_id
|
||||||
|
|
||||||
|
t.text :raw
|
||||||
|
t.text :error
|
||||||
|
|
||||||
|
t.text :message_id
|
||||||
|
t.text :from_address
|
||||||
|
t.text :to_addresses
|
||||||
|
t.text :cc_addresses
|
||||||
|
t.text :subject
|
||||||
|
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :incoming_emails, :created_at
|
||||||
|
add_index :incoming_emails, :message_id
|
||||||
|
add_index :incoming_emails, :error
|
||||||
|
end
|
||||||
|
end
|
28
db/migrate/20160118233631_backfill_incoming_emails.rb
Normal file
28
db/migrate/20160118233631_backfill_incoming_emails.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
class BackfillIncomingEmails < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
execute <<-SQL
|
||||||
|
INSERT INTO incoming_emails (post_id, created_at, updated_at, user_id, topic_id, message_id, from_address, to_addresses, subject)
|
||||||
|
SELECT posts.id
|
||||||
|
, posts.created_at
|
||||||
|
, posts.created_at
|
||||||
|
, posts.user_id
|
||||||
|
, posts.topic_id
|
||||||
|
, array_to_string(regexp_matches(posts.raw_email, '^\s*Message-Id: .*<([^>]+)>', 'im'), '')
|
||||||
|
, users.email
|
||||||
|
, array_to_string(regexp_matches(array_to_string(regexp_matches(posts.raw_email, '^to:.+$', 'im'), ''), '[^<\s"''(]+@[^>\s"'')]+'), '')
|
||||||
|
, topics.title
|
||||||
|
FROM posts
|
||||||
|
JOIN topics ON posts.topic_id = topics.id
|
||||||
|
JOIN users ON posts.user_id = users.id
|
||||||
|
WHERE posts.user_id IS NOT NULL
|
||||||
|
AND posts.topic_id IS NOT NULL
|
||||||
|
AND posts.via_email = 't'
|
||||||
|
AND posts.raw_email ~* 'Message-Id'
|
||||||
|
ORDER BY posts.id;
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
|
@ -16,9 +16,7 @@
|
||||||
{ "path": "script" },
|
{ "path": "script" },
|
||||||
{ "path": "spec" },
|
{ "path": "spec" },
|
||||||
{ "path": "vendor" },
|
{ "path": "vendor" },
|
||||||
{ "path": "test",
|
{ "path": "test" },
|
||||||
"folder_exclude_patterns": ["fixtures"]
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"settings":
|
"settings":
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,7 @@ module BackupRestore
|
||||||
|
|
||||||
switch_schema!
|
switch_schema!
|
||||||
|
|
||||||
migrate_database
|
# migrate_database
|
||||||
reconnect_database
|
reconnect_database
|
||||||
reload_site_settings
|
reload_site_settings
|
||||||
clear_emoji_cache
|
clear_emoji_cache
|
||||||
|
@ -56,7 +56,7 @@ module BackupRestore
|
||||||
disable_readonly_mode
|
disable_readonly_mode
|
||||||
### READ-ONLY / END ###
|
### READ-ONLY / END ###
|
||||||
|
|
||||||
extract_uploads
|
# extract_uploads
|
||||||
rescue SystemExit
|
rescue SystemExit
|
||||||
log "Restore process was cancelled!"
|
log "Restore process was cancelled!"
|
||||||
rollback
|
rollback
|
||||||
|
|
|
@ -1,144 +1,198 @@
|
||||||
require_dependency 'new_post_manager'
|
require_dependency "new_post_manager"
|
||||||
require_dependency 'email/html_cleaner'
|
require_dependency "post_action_creator"
|
||||||
require_dependency 'post_action_creator'
|
require_dependency "email/html_cleaner"
|
||||||
|
|
||||||
module Email
|
module Email
|
||||||
|
|
||||||
class Receiver
|
class Receiver
|
||||||
|
|
||||||
include ActionView::Helpers::NumberHelper
|
|
||||||
|
|
||||||
class ProcessingError < StandardError; end
|
class ProcessingError < StandardError; end
|
||||||
class EmailUnparsableError < ProcessingError; end
|
|
||||||
class EmptyEmailError < ProcessingError; end
|
class EmptyEmailError < ProcessingError; end
|
||||||
class UserNotFoundError < ProcessingError; end
|
class NoMessageIdError < ProcessingError; end
|
||||||
class UserNotSufficientTrustLevelError < ProcessingError; end
|
class AutoGeneratedEmailError < ProcessingError; end
|
||||||
|
class NoBodyDetectedError < ProcessingError; end
|
||||||
|
class InactiveUserError < ProcessingError; end
|
||||||
class BadDestinationAddress < ProcessingError; end
|
class BadDestinationAddress < ProcessingError; end
|
||||||
|
class StrangersNotAllowedError < ProcessingError; end
|
||||||
|
class InsufficientTrustLevelError < ProcessingError; end
|
||||||
|
class ReplyUserNotMatchingError < ProcessingError; end
|
||||||
class TopicNotFoundError < ProcessingError; end
|
class TopicNotFoundError < ProcessingError; end
|
||||||
class TopicClosedError < ProcessingError; end
|
class TopicClosedError < ProcessingError; end
|
||||||
class AutoGeneratedEmailError < ProcessingError; end
|
|
||||||
class EmailLogNotFound < ProcessingError; end
|
|
||||||
class InvalidPost < ProcessingError; end
|
class InvalidPost < ProcessingError; end
|
||||||
class ReplyUserNotFoundError < ProcessingError; end
|
|
||||||
class ReplyUserNotMatchingError < ProcessingError; end
|
|
||||||
class InactiveUserError < ProcessingError; end
|
|
||||||
class InvalidPostAction < ProcessingError; end
|
class InvalidPostAction < ProcessingError; end
|
||||||
|
|
||||||
attr_reader :body, :email_log
|
def initialize(mail_string)
|
||||||
|
raise EmptyEmailError if mail_string.blank?
|
||||||
def initialize(raw, opts=nil)
|
@raw_email = mail_string
|
||||||
@raw = raw
|
@mail = Mail.new(@raw_email)
|
||||||
@opts = opts || {}
|
raise NoMessageIdError if @mail.message_id.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
def process
|
def process
|
||||||
raise EmptyEmailError if @raw.blank?
|
@incoming_email = find_or_create_incoming_email
|
||||||
|
process_internal
|
||||||
|
rescue => e
|
||||||
|
@incoming_email.update_columns(error: e.to_s)
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
|
||||||
@message = Mail.new(@raw)
|
def find_or_create_incoming_email
|
||||||
|
IncomingEmail.find_or_create_by(message_id: @mail.message_id) do |incoming_email|
|
||||||
|
incoming_email.raw = @raw_email
|
||||||
|
incoming_email.subject = @mail.subject
|
||||||
|
incoming_email.from_address = @mail.from.first.downcase
|
||||||
|
incoming_email.to_addresses = @mail.to.map(&:downcase).join(";") if @mail.to.present?
|
||||||
|
incoming_email.cc_addresses = @mail.cc.map(&:downcase).join(";") if @mail.cc.present?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
raise AutoGeneratedEmailError if @message.header.to_s =~ /auto-(replied|generated)/
|
def process_internal
|
||||||
|
raise AutoGeneratedEmailError if is_auto_generated?
|
||||||
|
|
||||||
@body = parse_body(@message)
|
body = select_body || ""
|
||||||
|
|
||||||
# 'smtp_envelope_to' is a combination of: to, cc and bcc fields
|
raise NoBodyDetectedError if body.blank? && !@mail.has_attachments?
|
||||||
# prioriziting the `:reply` types
|
|
||||||
dest_infos = @message.smtp_envelope_to
|
user = find_or_create_user(from)
|
||||||
.map { |to_address| check_address(to_address) }
|
|
||||||
.compact
|
@incoming_email.update_columns(user_id: user.id)
|
||||||
.sort do |a, b|
|
|
||||||
if a[:type] == :reply && b[:type] != :reply
|
raise InactiveUserError if !user.active && !user.staged
|
||||||
1
|
|
||||||
elsif a[:type] != :reply && b[:type] == :reply
|
if post = find_related_post
|
||||||
-1
|
create_reply(user: user, raw: body, post: post, topic: post.topic)
|
||||||
else
|
else
|
||||||
0
|
destination = destinations.first
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
raise BadDestinationAddress if dest_infos.empty?
|
raise BadDestinationAddress if destination.blank?
|
||||||
|
|
||||||
from = @message[:from].address_list.addresses.first
|
case destination[:type]
|
||||||
user_email = from.address
|
|
||||||
user_name = from.display_name
|
|
||||||
|
|
||||||
user = User.find_by_email(user_email)
|
|
||||||
raise InactiveUserError if user.present? && !user.active && !user.staged
|
|
||||||
|
|
||||||
# TODO: take advantage of all the "TO"s
|
|
||||||
dest_info = dest_infos[0]
|
|
||||||
case dest_info[:type]
|
|
||||||
when :group
|
when :group
|
||||||
group = dest_info[:obj]
|
group = destination[:obj]
|
||||||
|
create_topic(user: user, raw: body, title: @mail.subject, archetype: Archetype.private_message, target_group_names: [group.name], skip_validations: true)
|
||||||
if user.blank?
|
|
||||||
if SiteSetting.allow_staged_accounts
|
|
||||||
user = create_staged_account(user_email, user_name)
|
|
||||||
else
|
|
||||||
wrap_body_in_quote(user_email)
|
|
||||||
user = Discourse.system_user
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
create_new_topic(user, archetype: Archetype.private_message, target_group_names: [group.name])
|
|
||||||
when :category
|
when :category
|
||||||
category = dest_info[:obj]
|
category = destination[:obj]
|
||||||
|
|
||||||
if user.blank? && category.email_in_allow_strangers
|
raise StrangersNotAllowedError if user.staged? && !category.email_in_allow_strangers
|
||||||
if SiteSetting.allow_staged_accounts
|
raise InsufficientTrustLevelError if !user.has_trust_level?(SiteSetting.email_in_min_trust)
|
||||||
user = create_staged_account(user_email)
|
|
||||||
else
|
|
||||||
wrap_body_in_quote(user_email)
|
|
||||||
user = Discourse.system_user
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
raise UserNotFoundError if user.blank?
|
create_topic(user: user, raw: body, title: @mail.subject, category: category.id)
|
||||||
raise UserNotSufficientTrustLevelError.new(user) unless category.email_in_allow_strangers || user.has_trust_level?(TrustLevel[SiteSetting.email_in_min_trust.to_i])
|
|
||||||
|
|
||||||
create_new_topic(user, category: category.id)
|
|
||||||
when :reply
|
when :reply
|
||||||
@email_log = dest_info[:obj]
|
email_log = destination[:obj]
|
||||||
|
|
||||||
raise EmailLogNotFound if @email_log.blank?
|
raise ReplyUserNotMatchingError if email_log.user_id != user.id
|
||||||
raise TopicNotFoundError if Topic.find_by_id(@email_log.topic_id).nil?
|
|
||||||
raise TopicClosedError if Topic.find_by_id(@email_log.topic_id).closed?
|
|
||||||
raise ReplyUserNotFoundError if user.blank?
|
|
||||||
raise ReplyUserNotMatchingError if @email_log.user_id != user.id
|
|
||||||
|
|
||||||
if post_action_type = post_action_for(@body)
|
create_reply(user: user, raw: body, post: email_log.post, topic: email_log.post.topic)
|
||||||
create_post_action(@email_log, post_action_type)
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_auto_generated?
|
||||||
|
@mail.return_path.blank? ||
|
||||||
|
@mail[:precedence].to_s[/list|junk|bulk|auto_reply/] ||
|
||||||
|
@mail.header.to_s[/auto-(submitted|replied|generated)/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_body
|
||||||
|
text = nil
|
||||||
|
html = nil
|
||||||
|
|
||||||
|
if @mail.multipart?
|
||||||
|
text = fix_charset(@mail.text_part)
|
||||||
|
html = fix_charset(@mail.html_part)
|
||||||
|
elsif @mail.content_type.to_s["text/html"]
|
||||||
|
html = fix_charset(@mail)
|
||||||
else
|
else
|
||||||
create_reply(@email_log)
|
text = fix_charset(@mail)
|
||||||
|
end
|
||||||
|
|
||||||
|
# prefer text over html
|
||||||
|
if text.present?
|
||||||
|
text_encoding = text.encoding
|
||||||
|
text = DiscourseEmailParser.parse_reply(text)
|
||||||
|
text = try_to_encode(text, text_encoding)
|
||||||
|
return text if text.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
# clean the html if that's all we've got
|
||||||
|
if html.present?
|
||||||
|
html_encoding = html.encoding
|
||||||
|
html = Email::HtmlCleaner.new(html).output_html
|
||||||
|
html = DiscourseEmailParser.parse_reply(html)
|
||||||
|
html = try_to_encode(html, html_encoding)
|
||||||
|
return html if html.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError => e
|
def fix_charset(mail_part)
|
||||||
raise EmailUnparsableError.new(e)
|
return nil if mail_part.blank? || mail_part.body.blank?
|
||||||
|
|
||||||
|
string = mail_part.body.to_s
|
||||||
|
|
||||||
|
# TODO (use charlock_holmes to properly detect encoding)
|
||||||
|
|
||||||
|
# 1) use the charset provided
|
||||||
|
if mail_part.charset.present?
|
||||||
|
fixed = try_to_encode(string, mail_part.charset)
|
||||||
|
return fixed if fixed.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_staged_account(email, name=nil)
|
# 2) default to UTF-8
|
||||||
User.create(
|
try_to_encode(string, "UTF-8")
|
||||||
email: email,
|
end
|
||||||
username: UserNameSuggester.suggest(name.presence || email),
|
|
||||||
name: name.presence || User.suggest_name(email),
|
def try_to_encode(string, encoding)
|
||||||
staged: true,
|
string.encode("UTF-8", encoding)
|
||||||
)
|
rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def from
|
||||||
|
@from ||= @mail[:from].address_list.addresses.first
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_create_user(address_field)
|
||||||
|
# decode the address field
|
||||||
|
address_field.decoded
|
||||||
|
# extract email and name
|
||||||
|
email = address_field.address.downcase
|
||||||
|
name = address_field.display_name.try(:to_s)
|
||||||
|
username = UserNameSuggester.sanitize_username(name) if name.present?
|
||||||
|
|
||||||
|
User.find_or_create_by(email: email) do |user|
|
||||||
|
user.username = UserNameSuggester.suggest(username.presence || email)
|
||||||
|
user.name = name.presence || User.suggest_name(email)
|
||||||
|
user.staged = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destinations
|
||||||
|
[ @mail.destinations,
|
||||||
|
[@mail[:x_forwarded_to]].flatten.compact.map(&:decoded),
|
||||||
|
[@mail[:delivered_to]].flatten.compact.map(&:decoded),
|
||||||
|
].flatten
|
||||||
|
.select(&:present?)
|
||||||
|
.uniq
|
||||||
|
.lazy
|
||||||
|
.map { |d| check_address(d) }
|
||||||
|
.drop_while(&:blank?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_address(address)
|
def check_address(address)
|
||||||
# only check for a group/category when 'email_in' is enabled
|
# only check for a group/category when 'email_in' is enabled
|
||||||
if SiteSetting.email_in
|
if SiteSetting.email_in
|
||||||
group = Group.find_by_email(address)
|
group = Group.find_by_email(address)
|
||||||
return { address: address, type: :group, obj: group } if group
|
return { type: :group, obj: group } if group
|
||||||
|
|
||||||
category = Category.find_by_email(address)
|
category = Category.find_by_email(address)
|
||||||
return { address: address, type: :category, obj: category } if category
|
return { type: :category, obj: category } if category
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# reply
|
||||||
match = reply_by_email_address_regex.match(address)
|
match = reply_by_email_address_regex.match(address)
|
||||||
if match && match[1].present?
|
if match && match[1].present?
|
||||||
email_log = EmailLog.for(match[1])
|
email_log = EmailLog.for(match[1])
|
||||||
return { address: address, type: :reply, obj: email_log }
|
return { type: :reply, obj: email_log } if email_log
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -147,173 +201,89 @@ module Email
|
||||||
.gsub(Regexp.escape("%{reply_key}"), "([[:xdigit:]]{32})")
|
.gsub(Regexp.escape("%{reply_key}"), "([[:xdigit:]]{32})")
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_body(message)
|
def find_related_post
|
||||||
body = select_body(message)
|
message_ids = [@mail.in_reply_to, extract_references]
|
||||||
encoding = body.encoding
|
message_ids.flatten!
|
||||||
raise EmptyEmailError if body.strip.blank?
|
message_ids.select!(&:present?)
|
||||||
|
message_ids.uniq!
|
||||||
|
return if message_ids.empty?
|
||||||
|
|
||||||
body = discourse_email_trimmer(body)
|
IncomingEmail.where.not(post_id: nil)
|
||||||
raise EmptyEmailError if body.strip.blank?
|
.where(message_id: message_ids)
|
||||||
|
.first
|
||||||
body = DiscourseEmailParser.parse_reply(body)
|
.try(:post)
|
||||||
raise EmptyEmailError if body.strip.blank?
|
|
||||||
|
|
||||||
body.force_encoding(encoding).encode("UTF-8")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def select_body(message)
|
def extract_references
|
||||||
html = nil
|
if Array === @mail.references
|
||||||
|
@mail.references
|
||||||
if message.multipart?
|
elsif @mail.references.present?
|
||||||
text = fix_charset message.text_part
|
@mail.references.split(/[\s,]/).map { |r| r.sub(/^</, "").sub(/>$/, "") }
|
||||||
# prefer text over html
|
end
|
||||||
return text if text
|
|
||||||
html = fix_charset message.html_part
|
|
||||||
elsif message.content_type =~ /text\/html/
|
|
||||||
html = fix_charset message
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if html
|
def likes
|
||||||
body = HtmlCleaner.new(html).output_html
|
@likes ||= Set.new ["+1", I18n.t('post_action_types.like.title').downcase]
|
||||||
else
|
|
||||||
body = fix_charset message
|
|
||||||
end
|
|
||||||
|
|
||||||
return body if @opts[:skip_sanity_check]
|
|
||||||
|
|
||||||
# Certain trigger phrases that means we didn't parse correctly
|
|
||||||
if body =~ /Content\-Type\:/ || body =~ /multipart\/alternative/ || body =~ /text\/plain/
|
|
||||||
raise EmptyEmailError
|
|
||||||
end
|
|
||||||
|
|
||||||
body
|
|
||||||
end
|
|
||||||
|
|
||||||
# Force encoding to UTF-8 on a Mail::Message or Mail::Part
|
|
||||||
def fix_charset(object)
|
|
||||||
return nil if object.nil?
|
|
||||||
|
|
||||||
if object.charset
|
|
||||||
object.body.decoded.force_encoding(object.charset.gsub(/utf8/i, "UTF-8")).encode("UTF-8").to_s
|
|
||||||
else
|
|
||||||
object.body.to_s
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
REPLYING_HEADER_LABELS = ['From', 'Sent', 'To', 'Subject', 'In-Reply-To', 'Cc', 'Bcc', 'Date']
|
|
||||||
REPLYING_HEADER_REGEX = Regexp.union(REPLYING_HEADER_LABELS.map { |lbl| "#{lbl}:" })
|
|
||||||
|
|
||||||
def line_is_quote?(l)
|
|
||||||
l =~ /\A\s*\-{3,80}\s*\z/ ||
|
|
||||||
l =~ Regexp.new("\\A\\s*" + I18n.t('user_notifications.previous_discussion') + "\\s*\\Z") ||
|
|
||||||
(l =~ /via #{SiteSetting.title}(.*)\:$/) ||
|
|
||||||
# This one might be controversial but so many reply lines have years, times and end with a colon.
|
|
||||||
# Let's try it and see how well it works.
|
|
||||||
(l =~ /\d{4}/ && l =~ /\d:\d\d/ && l =~ /\:$/) ||
|
|
||||||
(l =~ /On [\w, ]+\d+.*wrote:/)
|
|
||||||
end
|
|
||||||
|
|
||||||
def discourse_email_trimmer(body)
|
|
||||||
lines = body.scrub.lines.to_a
|
|
||||||
range_start = 0
|
|
||||||
range_end = 0
|
|
||||||
|
|
||||||
# If we started with a quote, skip it
|
|
||||||
lines.each_with_index do |l, idx|
|
|
||||||
break unless line_is_quote?(l) or l =~ /^>/ or l.blank?
|
|
||||||
range_start = idx + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
lines[range_start..-1].each_with_index do |l, idx|
|
|
||||||
break if line_is_quote?(l)
|
|
||||||
|
|
||||||
# Headers on subsequent lines
|
|
||||||
break if (0..2).all? { |off| lines[idx+off] =~ REPLYING_HEADER_REGEX }
|
|
||||||
# Headers on the same line
|
|
||||||
break if REPLYING_HEADER_LABELS.count { |lbl| l.include? lbl } >= 3
|
|
||||||
range_end = range_start + idx
|
|
||||||
end
|
|
||||||
|
|
||||||
lines[range_start..range_end].join.strip
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def wrap_body_in_quote(user_email)
|
|
||||||
@body = "[quote=\"#{user_email}\"]\n#{@body}\n[/quote]"
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_post_action(email_log, type)
|
|
||||||
PostActionCreator.new(email_log.user, email_log.post).perform(type)
|
|
||||||
rescue Discourse::InvalidAccess, PostAction::AlreadyActed => e
|
|
||||||
raise InvalidPostAction.new(e)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_action_for(body)
|
def post_action_for(body)
|
||||||
if ['+1', I18n.t('post_action_types.like.title').downcase].include? body.downcase
|
if likes.include?(body.strip.downcase)
|
||||||
PostActionType.types[:like]
|
PostActionType.types[:like]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_reply(email_log)
|
def create_topic(options={})
|
||||||
create_post_with_attachments(email_log.user,
|
create_post_with_attachments(options)
|
||||||
raw: @body,
|
|
||||||
topic_id: email_log.topic_id,
|
|
||||||
reply_to_post_number: email_log.post.post_number)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_new_topic(user, topic_options={})
|
def create_reply(options={})
|
||||||
topic_options[:raw] = @body
|
raise TopicNotFoundError if options[:topic].nil? || options[:topic].trashed?
|
||||||
topic_options[:title] = @message.subject
|
raise TopicClosedError if options[:topic].closed?
|
||||||
|
|
||||||
result = create_post_with_attachments(user, topic_options)
|
if post_action_type = post_action_for(options[:raw])
|
||||||
topic_id = result.post.present? ? result.post.topic_id : nil
|
create_post_action(options[:user], options[:post], post_action_type)
|
||||||
|
else
|
||||||
EmailLog.create(
|
options[:topic_id] = options[:post].try(:topic_id)
|
||||||
email_type: "topic_via_incoming_email",
|
options[:reply_to_post_number] = options[:post].try(:post_number)
|
||||||
to_address: user.email,
|
create_post_with_attachments(options)
|
||||||
topic_id: topic_id,
|
end
|
||||||
user_id: user.id,
|
|
||||||
)
|
|
||||||
|
|
||||||
result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_post_with_attachments(user, post_options={})
|
def create_post_action(user, post, type)
|
||||||
options = {
|
PostActionCreator.new(user, post).perform(type)
|
||||||
cooking_options: { traditional_markdown_linebreaks: true },
|
rescue PostAction::AlreadyActed
|
||||||
}.merge(post_options)
|
# it's cool, don't care
|
||||||
|
rescue Discourse::InvalidAccess => e
|
||||||
raw = options[:raw]
|
raise InvalidPostAction.new(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_post_with_attachments(options={})
|
||||||
# deal with attachments
|
# deal with attachments
|
||||||
@message.attachments.each do |attachment|
|
@mail.attachments.each do |attachment|
|
||||||
tmp = Tempfile.new("discourse-email-attachment")
|
tmp = Tempfile.new("discourse-email-attachment")
|
||||||
begin
|
begin
|
||||||
# read attachment
|
# read attachment
|
||||||
File.open(tmp.path, "w+b") { |f| f.write attachment.body.decoded }
|
File.open(tmp.path, "w+b") { |f| f.write attachment.body.decoded }
|
||||||
# create the upload for the user
|
# create the upload for the user
|
||||||
upload = Upload.create_for(user.id, tmp, attachment.filename, tmp.size)
|
upload = Upload.create_for(options[:user].id, tmp, attachment.filename, tmp.size)
|
||||||
if upload && upload.errors.empty?
|
if upload && upload.errors.empty?
|
||||||
# try to inline images
|
# try to inline images
|
||||||
if attachment.content_type.start_with?("image/")
|
if attachment.content_type.start_with?("image/") && options[:raw][/\[image: .+ \d+\]/]
|
||||||
if raw =~ /\[image: Inline image \d+\]/
|
options[:raw].sub!(/\[image: .+ \d+\]/, attachment_markdown(upload))
|
||||||
raw.sub!(/\[image: Inline image \d+\]/, attachment_markdown(upload))
|
else
|
||||||
next
|
options[:raw] << "\n#{attachment_markdown(upload)}\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
raw << "\n#{attachment_markdown(upload)}\n"
|
|
||||||
end
|
|
||||||
ensure
|
ensure
|
||||||
tmp.close!
|
tmp.try(:close!) rescue nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
options[:raw] = raw
|
post_options = {
|
||||||
|
cooking_options: { traditional_markdown_linebreaks: true },
|
||||||
|
}.merge(options)
|
||||||
|
|
||||||
create_post(user, options)
|
create_post(post_options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def attachment_markdown(upload)
|
def attachment_markdown(upload)
|
||||||
|
@ -324,20 +294,46 @@ module Email
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_post(user, options)
|
def create_post(options={})
|
||||||
# Mark the reply as incoming via email
|
|
||||||
options[:via_email] = true
|
options[:via_email] = true
|
||||||
options[:raw_email] = @raw
|
options[:raw_email] = @raw_email
|
||||||
|
|
||||||
manager = NewPostManager.new(user, options)
|
# ensure posts aren't created in the future
|
||||||
|
options[:created_at] = [@mail.date, DateTime.now].min
|
||||||
|
|
||||||
|
manager = NewPostManager.new(options[:user], options)
|
||||||
result = manager.perform
|
result = manager.perform
|
||||||
|
|
||||||
if result.errors.present?
|
raise InvalidPost, result.errors.full_messages.join("\n") if result.errors.any?
|
||||||
raise InvalidPost, result.errors.full_messages.join("\n")
|
|
||||||
|
if result.post
|
||||||
|
@incoming_email.update_columns(topic_id: result.post.topic_id, post_id: result.post.id)
|
||||||
|
if result.post.topic && result.post.topic.private_message?
|
||||||
|
add_other_addresses(result.post.topic, options[:user])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
result
|
def add_other_addresses(topic, sender)
|
||||||
|
%i(to cc bcc).each do |d|
|
||||||
|
if @mail[d] && @mail[d].address_list && @mail[d].address_list.addresses
|
||||||
|
@mail[d].address_list.addresses.each do |address|
|
||||||
|
begin
|
||||||
|
if user = find_or_create_user(address)
|
||||||
|
unless topic.topic_allowed_users.where(user_id: user.id).exists? &&
|
||||||
|
topic.topic_allowed_groups.where("group_id IN (SELECT group_id FROM group_users WHERE user_id = ?)", user.id).exists?
|
||||||
|
topic.topic_allowed_users.create!(user_id: user.id)
|
||||||
|
topic.add_small_action(sender, "invited_user", user.username)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue ActiveRecord::RecordInvalid
|
||||||
|
# don't care if user already allowed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
56
lib/tasks/emails.rake
Normal file
56
lib/tasks/emails.rake
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
def process_popmail(popmail)
|
||||||
|
begin
|
||||||
|
mail_string = popmail.pop
|
||||||
|
Email::Receiver.new(mail_string).process
|
||||||
|
rescue
|
||||||
|
putc "!"
|
||||||
|
else
|
||||||
|
putc "."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "use this task to import a mailbox into Disourse"
|
||||||
|
task "emails:import" => :environment do
|
||||||
|
begin
|
||||||
|
unless SiteSetting.email_in
|
||||||
|
puts "ERROR: you should enable the 'email_in' site setting before running this task"
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
address = ENV["ADDRESS"].presence || "pop.gmail.com"
|
||||||
|
port = (ENV["PORT"].presence || 995).to_i
|
||||||
|
ssl = (ENV["SSL"].presence || "1") == "1"
|
||||||
|
username = ENV["USERNAME"].presence
|
||||||
|
password = ENV["PASSWORD"].presence
|
||||||
|
|
||||||
|
if username.blank?
|
||||||
|
puts "ERROR: expecting USERNAME=<username> rake emails:import"
|
||||||
|
exit(2)
|
||||||
|
elsif password.blank?
|
||||||
|
puts "ERROR: expecting PASSWORD=<password> rake emails:import"
|
||||||
|
exit(3)
|
||||||
|
end
|
||||||
|
|
||||||
|
RateLimiter.disable
|
||||||
|
|
||||||
|
mails_left = 1
|
||||||
|
pop3 = Net::POP3.new(address, port)
|
||||||
|
pop3.enable_ssl if ssl
|
||||||
|
|
||||||
|
while mails_left > 0
|
||||||
|
pop3.start(username, password) do |pop|
|
||||||
|
pop.delete_all do |p|
|
||||||
|
process_popmail(p)
|
||||||
|
end
|
||||||
|
mails_left = pop.n_mails
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Done"
|
||||||
|
rescue Net::POPAuthenticationError
|
||||||
|
puts "AUTH EXCEPTION: please make sure your credentials are correct."
|
||||||
|
exit(10)
|
||||||
|
ensure
|
||||||
|
RateLimiter.enable
|
||||||
|
end
|
||||||
|
end
|
|
@ -193,6 +193,6 @@ class TopicCreator
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_can_send_permission!(topic, obj)
|
def check_can_send_permission!(topic, obj)
|
||||||
rollback_with!(topic, :cant_send_pm) unless @guardian.can_send_private_message?(obj)
|
rollback_with!(topic, :cant_send_pm) unless @opts[:skip_validations] || @guardian.can_send_private_message?(obj)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,12 +34,11 @@ module UserNameSuggester
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.sanitize_username(name)
|
def self.sanitize_username(name)
|
||||||
name = ActiveSupport::Inflector.transliterate(name)
|
ActiveSupport::Inflector.transliterate(name)
|
||||||
name = name.gsub(/^[^[:alnum:]]+|\W+$/, "")
|
.gsub(/^[^[:alnum:]]+|\W+$/, "")
|
||||||
.gsub(/\W+/, "_")
|
.gsub(/\W+/, "_")
|
||||||
.gsub(/^\_+/, '')
|
.gsub(/^\_+/, '')
|
||||||
.gsub(/[\-_\.]{2,}/, "_")
|
.gsub(/[\-_\.]{2,}/, "_")
|
||||||
name
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.rightsize_username(name)
|
def self.rightsize_username(name)
|
||||||
|
|
|
@ -1,791 +1,233 @@
|
||||||
# -*- encoding : utf-8 -*-
|
require "rails_helper"
|
||||||
|
require "email/receiver"
|
||||||
require 'rails_helper'
|
|
||||||
require 'email/receiver'
|
|
||||||
|
|
||||||
describe Email::Receiver do
|
describe Email::Receiver do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
SiteSetting.reply_by_email_address = "reply+%{reply_key}@appmail.adventuretime.ooo"
|
SiteSetting.email_in = true
|
||||||
SiteSetting.email_in = false
|
SiteSetting.reply_by_email_address = "reply+%{reply_key}@bar.com"
|
||||||
SiteSetting.title = "Discourse"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'parse_body' do
|
def email(email_name)
|
||||||
def test_parse_body(mail_string)
|
fixture_file("emails/#{email_name}.eml")
|
||||||
Email::Receiver.new(nil).parse_body(Mail::Message.new mail_string)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises EmptyEmailError if the message is blank" do
|
def process(email_name)
|
||||||
expect { test_parse_body("") }.to raise_error(Email::Receiver::EmptyEmailError)
|
Email::Receiver.new(email(email_name)).process
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises EmptyEmailError if the message is not an email" do
|
it "raises an EmptyEmailError when 'mail_string' is blank" do
|
||||||
expect { test_parse_body("asdf" * 30) }.to raise_error(Email::Receiver::EmptyEmailError)
|
expect { Email::Receiver.new(nil) }.to raise_error(Email::Receiver::EmptyEmailError)
|
||||||
|
expect { Email::Receiver.new("") }.to raise_error(Email::Receiver::EmptyEmailError)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises EmptyEmailError if there is no reply content" do
|
it "raises an NoMessageIdError when 'mail_string' is not an email" do
|
||||||
expect { test_parse_body(fixture_file("emails/no_content_reply.eml")) }.to raise_error(Email::Receiver::EmptyEmailError)
|
expect { Email::Receiver.new("wat") }.to raise_error(Email::Receiver::NoMessageIdError)
|
||||||
end
|
end
|
||||||
|
|
||||||
skip "raises EmailUnparsableError if the headers are corrupted" do
|
it "raises an NoMessageIdError when 'mail_string' is missing the message_id" do
|
||||||
expect { ; }.to raise_error(Email::Receiver::EmailUnparsableError)
|
expect { Email::Receiver.new(email(:missing_message_id)) }.to raise_error(Email::Receiver::NoMessageIdError)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can parse the html section" do
|
it "raises an AutoGeneratedEmailError when the mail has no return path" do
|
||||||
expect(test_parse_body(fixture_file("emails/html_only.eml"))).to eq("The EC2 instance - I've seen that there tends to be odd and " +
|
expect { process(:no_return_path) }.to raise_error(Email::Receiver::AutoGeneratedEmailError)
|
||||||
"unrecommended settings on the Bitnami installs that I've checked out.")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports a Dutch reply" do
|
it "raises an AutoGeneratedEmailError when the mail is auto generated" do
|
||||||
expect(test_parse_body(fixture_file("emails/dutch.eml"))).to eq("Dit is een antwoord in het Nederlands.")
|
expect { process(:auto_generated_precedence) }.to raise_error(Email::Receiver::AutoGeneratedEmailError)
|
||||||
|
expect { process(:auto_generated_header) }.to raise_error(Email::Receiver::AutoGeneratedEmailError)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports a Hebrew reply" do
|
it "raises a NoBodyDetectedError when the body is blank" do
|
||||||
I18n.stubs(:t).with('user_notifications.previous_discussion').returns('כלטוב')
|
expect { process(:no_body) }.to raise_error(Email::Receiver::NoBodyDetectedError)
|
||||||
|
|
||||||
# The force_encoding call is only needed for the test - it is passed on fine to the cooked post
|
|
||||||
expect(test_parse_body(fixture_file("emails/hebrew.eml"))).to eq("שלום")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports a BIG5-encoded reply" do
|
it "raises an InactiveUserError when the sender is inactive" do
|
||||||
# The force_encoding call is only needed for the test - it is passed on fine to the cooked post
|
Fabricate(:user, email: "inactive@bar.com", active: false)
|
||||||
expect(test_parse_body(fixture_file("emails/big5.eml"))).to eq("媽!我上電視了!")
|
expect { process(:inactive_sender) }.to raise_error(Email::Receiver::InactiveUserError)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "removes 'via' lines if they match the site title" do
|
skip "doesn't raise an InactiveUserError when the sender is staged" do
|
||||||
SiteSetting.title = "Discourse"
|
Fabricate(:user, email: "staged@bar.com", active: false, staged: true)
|
||||||
|
expect { process(:staged_sender) }.not_to raise_error
|
||||||
expect(test_parse_body(fixture_file("emails/via_line.eml"))).to eq("Hello this email has content!")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "removes an 'on date wrote' quoting line" do
|
it "raises a BadDestinationAddress when destinations aren't matching any of the incoming emails" do
|
||||||
expect(test_parse_body(fixture_file("emails/on_wrote.eml"))).to eq("Sure, all you need to do is frobnicate the foobar and you'll be all set!")
|
expect { process(:bad_destinations) }.to raise_error(Email::Receiver::BadDestinationAddress)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "removes the 'Previous Discussion' marker" do
|
context "reply" do
|
||||||
expect(test_parse_body(fixture_file("emails/previous.eml"))).to eq("This will not include the previous discussion that is present in this email.")
|
|
||||||
|
let(:reply_key) { "4f97315cc828096c9cb34c6f1a0d6fe8" }
|
||||||
|
let(:user) { Fabricate(:user, email: "discourse@bar.com") }
|
||||||
|
let(:topic) { create_topic(user: user) }
|
||||||
|
let(:post) { create_post(topic: topic, user: user) }
|
||||||
|
let!(:email_log) { Fabricate(:email_log, reply_key: reply_key, user: user, topic: topic, post: post) }
|
||||||
|
|
||||||
|
it "raises a ReplyUserNotMatchingError when the email address isn't matching the one we sent the notification to" do
|
||||||
|
expect { process(:reply_user_not_matching) }.to raise_error(Email::Receiver::ReplyUserNotMatchingError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises a TopicNotFoundError when the topic was deleted" do
|
||||||
|
topic.update_columns(deleted_at: 1.day.ago)
|
||||||
|
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicNotFoundError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises a TopicClosedError when the topic was closed" do
|
||||||
|
topic.update_columns(closed: true)
|
||||||
|
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicClosedError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an InvalidPost when there was an error while creating the post" do
|
||||||
|
expect { process(:too_small) }.to raise_error(Email::Receiver::InvalidPost)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an InvalidPost when there are too may mentions" do
|
||||||
|
SiteSetting.max_mentions_per_post = 1
|
||||||
|
Fabricate(:user, username: "user1")
|
||||||
|
Fabricate(:user, username: "user2")
|
||||||
|
expect { process(:too_many_mentions) }.to raise_error(Email::Receiver::InvalidPost)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an InvalidPostAction when they aren't allowed to like a post" do
|
||||||
|
topic.update_columns(archived: true)
|
||||||
|
expect { process(:like) }.to raise_error(Email::Receiver::InvalidPostAction)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "works" do
|
||||||
|
expect { process(:text_reply) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("This is a text reply :)")
|
||||||
|
expect(topic.posts.last.via_email).to eq(true)
|
||||||
|
expect(topic.posts.last.cooked).not_to match(/<br/)
|
||||||
|
|
||||||
|
expect { process(:html_reply) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("This is a <b>HTML</b> reply ;)")
|
||||||
|
|
||||||
|
expect { process(:hebrew_reply) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("שלום! מה שלומך היום?")
|
||||||
|
|
||||||
|
expect { process(:chinese_reply) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("您好! 你今天好吗?")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prefers text over html" do
|
||||||
|
expect { process(:text_and_html_reply) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("This is the *text* part.")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "removes the 'on <date>, <contact> wrote' quoting line" do
|
||||||
|
expect { process(:on_date_contact_wrote) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("This is the actual reply.")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "removes the 'Previous Replies' marker" do
|
||||||
|
expect { process(:previous_replies) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("This will not include the previous discussion that is present in this email.")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "handles multiple paragraphs" do
|
it "handles multiple paragraphs" do
|
||||||
expect(test_parse_body(fixture_file("emails/paragraphs.eml"))).
|
expect { process(:paragraphs) }.to change { topic.posts.count }
|
||||||
to eq(
|
expect(topic.posts.last.raw).to eq("Do you like liquorice?\n\nI really like them. One could even say that I am *addicted* to liquorice. Anf if\nyou can mix it up with some anise, then I'm in heaven ;)")
|
||||||
"Is there any reason the *old* candy can't be be kept in silos while the new candy
|
|
||||||
is imported into *new* silos?
|
|
||||||
|
|
||||||
The thing about candy is it stays delicious for a long time -- we can just keep
|
|
||||||
it there without worrying about it too much, imo.
|
|
||||||
|
|
||||||
Thanks for listening."
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "handles multiple paragraphs when parsing html" do
|
|
||||||
expect(test_parse_body(fixture_file("emails/html_paragraphs.eml"))).
|
|
||||||
to eq(
|
|
||||||
"Awesome!
|
|
||||||
|
|
||||||
Pleasure to have you here!
|
|
||||||
|
|
||||||
:boom:"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "handles newlines" do
|
|
||||||
expect(test_parse_body(fixture_file("emails/newlines.eml"))).
|
|
||||||
to eq(
|
|
||||||
"This is my reply.
|
|
||||||
It is my best reply.
|
|
||||||
It will also be my *only* reply."
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "handles inline reply" do
|
it "handles inline reply" do
|
||||||
expect(test_parse_body(fixture_file("emails/inline_reply.eml"))).
|
expect { process(:inline_reply) }.to change { topic.posts.count }
|
||||||
to eq(
|
expect(topic.posts.last.raw).to eq("On Tue, Jan 15, 2016 at 11:12 AM, Bar Foo <info@unconfigured.discourse.org> wrote:\n\n> WAT <https://bar.com/users/wat> November 28\n>\n> This is the previous post.\n\nAnd this is *my* reply :+1:")
|
||||||
"On Wed, Oct 8, 2014 at 11:12 AM, techAPJ <info@unconfigured.discourse.org> wrote:
|
|
||||||
|
|
||||||
> techAPJ <https://meta.discourse.org/users/techapj>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> Test reply.
|
|
||||||
>
|
|
||||||
> First paragraph.
|
|
||||||
>
|
|
||||||
> Second paragraph.
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies codinghorror
|
|
||||||
> <https://meta.discourse.org/users/codinghorror>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> We're testing the latest GitHub email processing library which we are
|
|
||||||
> integrating now.
|
|
||||||
>
|
|
||||||
> https://github.com/github/email_reply_parser
|
|
||||||
>
|
|
||||||
> Go ahead and reply to this topic and I'll reply from various email clients
|
|
||||||
> for testing.
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <https://meta.discourse.org/my/preferences>.
|
|
||||||
>
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog."
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can retrieve the first part of multiple replies" do
|
it "retrieves the first part of multiple replies" do
|
||||||
expect(test_parse_body(fixture_file("emails/inline_mixed.eml"))).to eq(
|
expect { process(:inline_mixed_replies) }.to change { topic.posts.count }
|
||||||
"The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
expect(topic.posts.last.raw).to eq("On Tue, Jan 15, 2016 at 11:12 AM, Bar Foo <info@unconfigured.discourse.org> wrote:\n\n> WAT <https://bar.com/users/wat> November 28\n>\n> This is the previous post.\n\nAnd this is *my* reply :+1:\n\n> This is another post.\n\nAnd this is **another** reply.")
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
> First paragraph.
|
|
||||||
>
|
|
||||||
> Second paragraph.
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown"
|
|
||||||
)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not include previous replies" do
|
it "strips signatures" do
|
||||||
expect(test_parse_body(fixture_file("emails/previous_replies.eml"))).not_to match(/Previous Replies/)
|
expect { process(:iphone_signature) }.to change { topic.posts.count }
|
||||||
end
|
expect(topic.posts.last.raw).to eq("This is not the signature you're looking for.")
|
||||||
|
|
||||||
it "strips iPhone signature" do
|
expect { process(:signature) }.to change { topic.posts.count }
|
||||||
expect(test_parse_body(fixture_file("emails/iphone_signature.eml"))).not_to match(/Sent from my iPhone/)
|
expect(topic.posts.last.raw).to eq("You shall not sign!")
|
||||||
end
|
|
||||||
|
|
||||||
it "strips regular signature" do
|
|
||||||
expect(test_parse_body(fixture_file("emails/signature.eml"))).not_to match(/Arpit/)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "strips 'original message' context" do
|
it "strips 'original message' context" do
|
||||||
expect(test_parse_body(fixture_file("emails/original_message_context.eml"))).not_to match(/Context/)
|
expect { process(:original_message) }.to change { topic.posts.count }
|
||||||
|
expect(topic.posts.last.raw).to eq("This is a reply :)")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "properly renders email reply from gmail web client" do
|
it "supports attachments" do
|
||||||
expect(test_parse_body(fixture_file("emails/gmail_web.eml"))).
|
expect { process(:no_body_with_attachments) }.to change { topic.posts.count }
|
||||||
to eq(
|
expect(topic.posts.last.raw).to match(/<img/)
|
||||||
"### This is a reply from standard GMail in Google Chrome.
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
expect { process(:inline_attachment) }.to change { topic.posts.count }
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
expect(topic.posts.last.raw).to match(/Before\s+<img.+\s+After/m)
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
Here's some **bold** text in Markdown.
|
|
||||||
|
|
||||||
Here's a link http://example.com"
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "properly renders email reply from iOS default mail client" do
|
it "supports liking via email" do
|
||||||
expect(test_parse_body(fixture_file("emails/ios_default.eml"))).
|
expect { process(:like) }.to change(PostAction, :count)
|
||||||
to eq(
|
|
||||||
"### this is a reply from iOS default mail
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
Here's some **bold** markdown text.
|
|
||||||
|
|
||||||
Here's a link http://example.com"
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "properly renders email reply from Android 5 gmail client" do
|
it "ensures posts aren't dated in the future" do
|
||||||
expect(test_parse_body(fixture_file("emails/android_gmail.eml"))).
|
expect { process(:from_the_future) }.to change { topic.posts.count }
|
||||||
to eq(
|
expect(topic.posts.last.created_at).to be_within(1.minute).of(DateTime.now)
|
||||||
"### this is a reply from Android 5 gmail
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
This is **bold** in Markdown.
|
|
||||||
|
|
||||||
This is a link to http://example.com"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "properly renders email reply from Windows 8.1 Metro default mail client" do
|
|
||||||
expect(test_parse_body(fixture_file("emails/windows_8_metro.eml"))).
|
|
||||||
to eq(
|
|
||||||
"### reply from default mail client in Windows 8.1 Metro
|
|
||||||
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
|
|
||||||
This is a **bold** word in Markdown
|
|
||||||
|
|
||||||
|
|
||||||
This is a link http://example.com"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "properly renders email reply from MS Outlook client" do
|
|
||||||
expect(test_parse_body(fixture_file("emails/outlook.eml"))).to eq("Microsoft Outlook 2010")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "converts back to UTF-8 at the end" do
|
|
||||||
result = test_parse_body(fixture_file("emails/big5.eml"))
|
|
||||||
expect(result.encoding).to eq(Encoding::UTF_8)
|
|
||||||
|
|
||||||
# should not throw
|
|
||||||
TextCleaner.normalize_whitespaces(
|
|
||||||
test_parse_body(fixture_file("emails/big5.eml"))
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "posting replies" do
|
|
||||||
let(:reply_key) { raise "Override this in a lower describe block" }
|
|
||||||
let(:email_raw) { raise "Override this in a lower describe block" }
|
|
||||||
# ----
|
|
||||||
let(:to) { SiteSetting.reply_by_email_address.gsub("%{reply_key}", reply_key) }
|
|
||||||
let(:receiver) { Email::Receiver.new(email_raw) }
|
|
||||||
let(:post) { create_post }
|
|
||||||
let(:topic) { post.topic }
|
|
||||||
let(:posting_user) { post.user }
|
|
||||||
let(:replying_user_email) { 'jake@adventuretime.ooo' }
|
|
||||||
let(:replying_user) { Fabricate(:user, email: replying_user_email, trust_level: 2)}
|
|
||||||
let(:email_log) { EmailLog.new(reply_key: reply_key,
|
|
||||||
post: post,
|
|
||||||
post_id: post.id,
|
|
||||||
topic_id: post.topic_id,
|
|
||||||
email_type: 'user_posted',
|
|
||||||
user: replying_user,
|
|
||||||
user_id: replying_user.id,
|
|
||||||
to_address: replying_user_email
|
|
||||||
) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
email_log.save
|
|
||||||
end
|
|
||||||
|
|
||||||
# === Success Posting ===
|
|
||||||
|
|
||||||
describe "valid_reply.eml" do
|
|
||||||
let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' }
|
|
||||||
let!(:email_raw) { fill_email(fixture_file("emails/valid_reply.eml"), replying_user_email, to) }
|
|
||||||
|
|
||||||
it "creates a post with the correct content" do
|
|
||||||
start_count = topic.posts.count
|
|
||||||
|
|
||||||
receiver.process
|
|
||||||
|
|
||||||
expect(topic.posts.count).to eq(start_count + 1)
|
|
||||||
created_post = topic.posts.last
|
|
||||||
expect(created_post.via_email).to eq(true)
|
|
||||||
expect(created_post.cooked.strip).to eq(fixture_file("emails/valid_reply.cooked").strip)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "paragraphs.eml" do
|
|
||||||
let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' }
|
|
||||||
let!(:email_raw) { fixture_file("emails/paragraphs.eml") }
|
|
||||||
|
|
||||||
it "cooks multiple paragraphs with traditional Markdown linebreaks" do
|
|
||||||
start_count = topic.posts.count
|
|
||||||
|
|
||||||
receiver.process
|
|
||||||
|
|
||||||
expect(topic.posts.count).to eq(start_count + 1)
|
|
||||||
expect(topic.posts.last.cooked.strip).to eq(fixture_file("emails/paragraphs.cooked").strip)
|
|
||||||
expect(topic.posts.last.cooked).not_to match(/<br/)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "attachment.eml" do
|
|
||||||
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
|
|
||||||
let!(:email_raw) {
|
|
||||||
fixture_file("emails/attachment.eml")
|
|
||||||
.gsub("TO", "reply+#{reply_key}@appmail.adventuretime.ooo")
|
|
||||||
.gsub("FROM", replying_user_email)
|
|
||||||
}
|
|
||||||
|
|
||||||
let(:upload_sha) { '04df605be528d03876685c52166d4b063aabb78a' }
|
|
||||||
|
|
||||||
it "creates a post with an attachment" do
|
|
||||||
Upload.stubs(:fix_image_orientation)
|
|
||||||
ImageOptim.any_instance.stubs(:optimize_image!)
|
|
||||||
|
|
||||||
start_count = topic.posts.count
|
|
||||||
Upload.find_by(sha1: upload_sha).try(:destroy)
|
|
||||||
|
|
||||||
receiver.process
|
|
||||||
|
|
||||||
expect(topic.posts.count).to eq(start_count + 1)
|
|
||||||
expect(topic.posts.last.cooked).to match(/<img src=['"](\/uploads\/default\/original\/.+\.png)['"] width=['"]289['"] height=['"]126['"]>/)
|
|
||||||
expect(Upload.find_by(sha1: upload_sha)).not_to eq(nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'Liking via email' do
|
|
||||||
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
|
|
||||||
let(:replied_user_like_params) { { user: replying_user, post: post, post_action_type_id: PostActionType.types[:like] } }
|
|
||||||
let(:replied_user_like) { PostAction.find_by(replied_user_like_params) }
|
|
||||||
|
|
||||||
describe "plus_one.eml" do
|
|
||||||
let!(:email_raw) {
|
|
||||||
fixture_file("emails/plus_one.eml")
|
|
||||||
.gsub("TO", "reply+#{reply_key}@appmail.adventuretime.ooo")
|
|
||||||
.gsub("FROM", replying_user_email)
|
|
||||||
}
|
|
||||||
|
|
||||||
it "adds a user like to the post" do
|
|
||||||
expect { receiver.process }.to change { PostAction.count }.by(1)
|
|
||||||
expect(replied_user_like).to be_present
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not create a duplicate like" do
|
|
||||||
PostAction.create(replied_user_like_params)
|
|
||||||
before_count = PostAction.count
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::InvalidPostAction)
|
|
||||||
expect(PostAction.count).to eq before_count
|
|
||||||
expect(replied_user_like).to be_present
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not allow unauthorized happiness" do
|
|
||||||
post.trash!
|
|
||||||
before_count = PostAction.count
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::InvalidPostAction)
|
|
||||||
expect(PostAction.count).to eq before_count
|
|
||||||
expect(replied_user_like).to_not be_present
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "like.eml" do
|
|
||||||
let!(:email_raw) {
|
|
||||||
fixture_file("emails/like.eml")
|
|
||||||
.gsub("TO", "reply+#{reply_key}@appmail.adventuretime.ooo")
|
|
||||||
.gsub("FROM", replying_user_email)
|
|
||||||
}
|
|
||||||
|
|
||||||
it 'adds a user like to the post' do
|
|
||||||
expect { receiver.process }.to change { PostAction.count }.by(1)
|
|
||||||
expect(replied_user_like).to be_present
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# === Failure Conditions ===
|
|
||||||
|
|
||||||
describe "too_short.eml" do
|
|
||||||
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
|
|
||||||
let!(:email_raw) {
|
|
||||||
fixture_file("emails/too_short.eml")
|
|
||||||
.gsub("TO", "reply+#{reply_key}@appmail.adventuretime.ooo")
|
|
||||||
.gsub("FROM", replying_user_email)
|
|
||||||
.gsub("SUBJECT", "re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'")
|
|
||||||
}
|
|
||||||
|
|
||||||
it "raises an InvalidPost error" do
|
|
||||||
SiteSetting.min_post_length = 5
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "too_many_mentions.eml" do
|
|
||||||
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
|
|
||||||
let!(:email_raw) { fixture_file("emails/too_many_mentions.eml") }
|
|
||||||
|
|
||||||
it "raises an InvalidPost error" do
|
|
||||||
SiteSetting.max_mentions_per_post = 10
|
|
||||||
(1..11).each do |i|
|
|
||||||
Fabricate(:user, username: "user#{i}").save
|
|
||||||
end
|
|
||||||
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "auto response email replies should not be accepted" do
|
|
||||||
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
|
|
||||||
let!(:email_raw) { fixture_file("emails/auto_reply.eml") }
|
|
||||||
it "raises a AutoGeneratedEmailError" do
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::AutoGeneratedEmailError)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "posting reply to a closed topic" do
|
context "new message to a group" do
|
||||||
let(:reply_key) { raise "Override this in a lower describe block" }
|
|
||||||
let(:email_raw) { raise "Override this in a lower describe block" }
|
|
||||||
let(:to) { SiteSetting.reply_by_email_address.gsub("%{reply_key}", reply_key) }
|
|
||||||
let(:receiver) { Email::Receiver.new(email_raw) }
|
|
||||||
let(:topic) { Fabricate(:topic, closed: true) }
|
|
||||||
let(:post) { Fabricate(:post, topic: topic, post_number: 1) }
|
|
||||||
let(:replying_user_email) { 'jake@adventuretime.ooo' }
|
|
||||||
let(:replying_user) { Fabricate(:user, email: replying_user_email, trust_level: 2) }
|
|
||||||
let(:email_log) { EmailLog.new(reply_key: reply_key,
|
|
||||||
post: post,
|
|
||||||
post_id: post.id,
|
|
||||||
topic_id: topic.id,
|
|
||||||
email_type: 'user_posted',
|
|
||||||
user: replying_user,
|
|
||||||
user_id: replying_user.id,
|
|
||||||
to_address: replying_user_email
|
|
||||||
) }
|
|
||||||
|
|
||||||
before do
|
let!(:group) { Fabricate(:group, incoming_email: "team@bar.com") }
|
||||||
email_log.save
|
|
||||||
|
it "handles encoded display names" do
|
||||||
|
expect { process(:encoded_display_name) }.to change(Topic, :count)
|
||||||
|
|
||||||
|
topic = Topic.last
|
||||||
|
expect(topic.private_message?).to eq(true)
|
||||||
|
expect(topic.allowed_groups).to include(group)
|
||||||
|
|
||||||
|
user = topic.user
|
||||||
|
expect(user.staged).to eq(true)
|
||||||
|
expect(user.username).to eq("random_name")
|
||||||
|
expect(user.name).to eq("Случайная Имя")
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "should not create post" do
|
it "invites everyone in the chain" do
|
||||||
let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' }
|
expect { process(:cc) }.to change(Topic, :count)
|
||||||
let!(:email_raw) { fill_email(fixture_file("emails/valid_reply.eml"), replying_user_email, to) }
|
emails = Topic.last.allowed_users.pluck(:email)
|
||||||
it "raises a TopicClosedError" do
|
expect(emails.size).to eq(5)
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::TopicClosedError)
|
expect(emails).to include("someone@else.com", "discourse@bar.com", "team@bar.com", "wat@bar.com", "42@bar.com")
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "posting reply to a deleted topic" do
|
|
||||||
let(:reply_key) { raise "Override this in a lower describe block" }
|
|
||||||
let(:email_raw) { raise "Override this in a lower describe block" }
|
|
||||||
let(:to) { SiteSetting.reply_by_email_address.gsub("%{reply_key}", reply_key) }
|
|
||||||
let(:receiver) { Email::Receiver.new(email_raw) }
|
|
||||||
let(:deleted_topic) { Fabricate(:deleted_topic) }
|
|
||||||
let(:post) { Fabricate(:post, topic: deleted_topic, post_number: 1) }
|
|
||||||
let(:replying_user_email) { 'jake@adventuretime.ooo' }
|
|
||||||
let(:replying_user) { Fabricate(:user, email: replying_user_email, trust_level: 2) }
|
|
||||||
let(:email_log) { EmailLog.new(reply_key: reply_key,
|
|
||||||
post: post,
|
|
||||||
post_id: post.id,
|
|
||||||
topic_id: deleted_topic.id,
|
|
||||||
email_type: 'user_posted',
|
|
||||||
user: replying_user,
|
|
||||||
user_id: replying_user.id,
|
|
||||||
to_address: replying_user_email
|
|
||||||
) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
email_log.save
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "should not create post" do
|
|
||||||
let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' }
|
|
||||||
let!(:email_raw) { fill_email(fixture_file("emails/valid_reply.eml"), replying_user_email, to) }
|
|
||||||
it "raises a TopicNotFoundError" do
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::TopicNotFoundError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "posting reply as a inactive user" do
|
|
||||||
let(:reply_key) { raise "Override this in a lower describe block" }
|
|
||||||
let(:email_raw) { raise "Override this in a lower describe block" }
|
|
||||||
let(:to) { SiteSetting.reply_by_email_address.gsub("%{reply_key}", reply_key) }
|
|
||||||
let(:receiver) { Email::Receiver.new(email_raw) }
|
|
||||||
let(:topic) { Fabricate(:topic) }
|
|
||||||
let(:post) { Fabricate(:post, topic: topic, post_number: 1) }
|
|
||||||
let(:replying_user_email) { 'jake@adventuretime.ooo' }
|
|
||||||
let(:replying_user) { Fabricate(:user, email: replying_user_email, trust_level: 2, active: false) }
|
|
||||||
let(:email_log) { EmailLog.new(reply_key: reply_key,
|
|
||||||
post: post,
|
|
||||||
post_id: post.id,
|
|
||||||
topic_id: topic.id,
|
|
||||||
email_type: 'user_posted',
|
|
||||||
user: replying_user,
|
|
||||||
user_id: replying_user.id,
|
|
||||||
to_address: replying_user_email
|
|
||||||
) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
email_log.save
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "should not create post" do
|
|
||||||
let!(:reply_key) { '59d8df8370b7e95c5a49fbf86aeb2c93' }
|
|
||||||
let!(:email_raw) { fill_email(fixture_file("emails/valid_reply.eml"), replying_user_email, to) }
|
|
||||||
it "raises a InactiveUserError" do
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::InactiveUserError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "posting a new topic in a category" do
|
|
||||||
let(:category_destination) { raise "Override this in a lower describe block" }
|
|
||||||
let(:email_raw) { raise "Override this in a lower describe block" }
|
|
||||||
let(:allow_strangers) { false }
|
|
||||||
# ----
|
|
||||||
let(:receiver) { Email::Receiver.new(email_raw) }
|
|
||||||
let(:user_email) { 'jake@adventuretime.ooo' }
|
|
||||||
let(:user) { Fabricate(:user, email: user_email, trust_level: 2)}
|
|
||||||
let(:category) { Fabricate(:category, email_in: category_destination, email_in_allow_strangers: allow_strangers) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.email_in = true
|
|
||||||
user.save
|
|
||||||
category.save
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "too_short.eml" do
|
|
||||||
let!(:category_destination) { 'incoming+amazing@appmail.adventuretime.ooo' }
|
|
||||||
let(:email_raw) {
|
|
||||||
fixture_file("emails/too_short.eml")
|
|
||||||
.gsub("TO", category_destination)
|
|
||||||
.gsub("FROM", user_email)
|
|
||||||
.gsub("SUBJECT", "A long subject that passes the checks")
|
|
||||||
}
|
|
||||||
|
|
||||||
it "does not create a topic if the post fails" do
|
|
||||||
before_topic_count = Topic.count
|
|
||||||
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::InvalidPost)
|
|
||||||
|
|
||||||
expect(Topic.count).to eq(before_topic_count)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "new topic in a category" do
|
||||||
|
|
||||||
|
let!(:category) { Fabricate(:category, email_in: "category@bar.com", email_in_allow_strangers: false) }
|
||||||
|
|
||||||
|
it "raises a StrangersNotAllowedError when 'email_in_allow_strangers' is disabled" do
|
||||||
|
expect { process(:stranger_not_allowed) }.to raise_error(Email::Receiver::StrangersNotAllowedError)
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_email(opts)
|
it "raises an InsufficientTrustLevelError when user's trust level isn't enough" do
|
||||||
incoming_email = fixture_file("emails/valid_incoming.eml")
|
SiteSetting.email_in_min_trust = 4
|
||||||
email = fill_email(incoming_email, opts[:from], opts[:to], opts[:body], opts[:subject], opts[:cc])
|
Fabricate(:user, email: "insufficient@bar.com", trust_level: 3)
|
||||||
Email::Receiver.new(email).process
|
expect { process(:insufficient_trust_level) }.to raise_error(Email::Receiver::InsufficientTrustLevelError)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with a valid email" do
|
it "raises an InvalidAccess when the user is part of a readonly group" do
|
||||||
let(:reply_key) { "59d8df8370b7e95c5a49fbf86aeb2c93" }
|
user = Fabricate(:user, email: "readonly@bar.com", trust_level: SiteSetting.email_in_min_trust)
|
||||||
let(:to) { SiteSetting.reply_by_email_address.gsub("%{reply_key}", reply_key) }
|
group = Fabricate(:group)
|
||||||
let(:user_email) { "test@test.com" }
|
|
||||||
let(:user) { Fabricate(:user, email: user_email, trust_level: 2)}
|
|
||||||
let(:post) { create_post(user: user) }
|
|
||||||
|
|
||||||
let(:valid_reply) {
|
group.add(user)
|
||||||
reply = fixture_file("emails/valid_reply.eml")
|
group.save
|
||||||
fill_email(reply, user.email, to)
|
|
||||||
}
|
|
||||||
|
|
||||||
let(:receiver) { Email::Receiver.new(valid_reply) }
|
category.set_permissions(group => :readonly)
|
||||||
let(:email_log) { EmailLog.new(reply_key: reply_key,
|
|
||||||
post_id: post.id,
|
|
||||||
topic_id: post.topic_id,
|
|
||||||
user_id: post.user_id,
|
|
||||||
post: post,
|
|
||||||
user: user,
|
|
||||||
email_type: 'test',
|
|
||||||
to_address: user.email
|
|
||||||
) }
|
|
||||||
let(:reply_body) {
|
|
||||||
"I could not disagree more. I am obviously biased but adventure time is the
|
|
||||||
greatest show ever created. Everyone should watch it.
|
|
||||||
|
|
||||||
- Jake out" }
|
|
||||||
|
|
||||||
describe "with an email log" do
|
|
||||||
|
|
||||||
it "extracts data" do
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::EmailLogNotFound)
|
|
||||||
|
|
||||||
email_log.save!
|
|
||||||
receiver.process
|
|
||||||
|
|
||||||
expect(receiver.body).to eq(reply_body)
|
|
||||||
expect(receiver.email_log).to eq(email_log)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "with a valid email from a different user" do
|
|
||||||
let(:reply_key) { SecureRandom.hex(16) }
|
|
||||||
let(:to) { SiteSetting.reply_by_email_address.gsub("%{reply_key}", reply_key) }
|
|
||||||
let(:user) { Fabricate(:user, email: "test@test.com", trust_level: 2)}
|
|
||||||
let(:post) { create_post(user: user) }
|
|
||||||
let!(:email_log) { EmailLog.create(reply_key: reply_key,
|
|
||||||
post_id: post.id,
|
|
||||||
topic_id: post.topic_id,
|
|
||||||
user_id: post.user_id,
|
|
||||||
post: post,
|
|
||||||
user: user,
|
|
||||||
email_type: 'test',
|
|
||||||
to_address: user.email) }
|
|
||||||
|
|
||||||
it "raises ReplyUserNotFoundError when user doesn't exist" do
|
|
||||||
reply = fill_email(fixture_file("emails/valid_reply.eml"), "unknown@user.com", to)
|
|
||||||
receiver = Email::Receiver.new(reply)
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::ReplyUserNotFoundError)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "raises ReplyUserNotMatchingError when user is not matching the reply key" do
|
|
||||||
another_user = Fabricate(:user, email: "existing@user.com")
|
|
||||||
reply = fill_email(fixture_file("emails/valid_reply.eml"), another_user.email, to)
|
|
||||||
receiver = Email::Receiver.new(reply)
|
|
||||||
expect { receiver.process }.to raise_error(Email::Receiver::ReplyUserNotMatchingError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "processes an email to a category" do
|
|
||||||
let(:to) { "some@email.com" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.email_in = true
|
|
||||||
SiteSetting.email_in_min_trust = TrustLevel[4].to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
it "correctly can target categories" do
|
|
||||||
Fabricate(:category, email_in_allow_strangers: false, email_in: to)
|
|
||||||
|
|
||||||
# no email in for user
|
|
||||||
expect{
|
|
||||||
process_email(from: "cobb@dob.com", to: "invalid@address.com")
|
|
||||||
}.to raise_error(Email::Receiver::BadDestinationAddress)
|
|
||||||
|
|
||||||
# valid target invalid user
|
|
||||||
expect{
|
|
||||||
process_email(from: "cobb@dob.com", to: to)
|
|
||||||
}.to raise_error(Email::Receiver::UserNotFoundError)
|
|
||||||
|
|
||||||
# untrusted
|
|
||||||
user = Fabricate(:user)
|
|
||||||
expect{
|
|
||||||
process_email(from: user.email, to: to)
|
|
||||||
}.to raise_error(Email::Receiver::UserNotSufficientTrustLevelError)
|
|
||||||
|
|
||||||
# trusted
|
|
||||||
user.trust_level = 4
|
|
||||||
user.save
|
|
||||||
|
|
||||||
process_email(from: user.email, to: to)
|
|
||||||
expect(user.posts.count).to eq(1)
|
|
||||||
|
|
||||||
# email too short
|
|
||||||
message = nil
|
|
||||||
begin
|
|
||||||
process_email(from: user.email, to: to, body: "x", subject: "this is my new topic title")
|
|
||||||
rescue Email::Receiver::InvalidPost => e
|
|
||||||
message = e.message
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(e.message).to include("too short")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
it "blocks user in restricted group from creating topic" do
|
|
||||||
to = "some@email.com"
|
|
||||||
|
|
||||||
restricted_user = Fabricate(:user, trust_level: 4)
|
|
||||||
restricted_group = Fabricate(:group)
|
|
||||||
restricted_group.add(restricted_user)
|
|
||||||
restricted_group.save
|
|
||||||
|
|
||||||
category = Fabricate(:category, email_in_allow_strangers: false, email_in: to)
|
|
||||||
category.set_permissions(restricted_group => :readonly)
|
|
||||||
category.save
|
category.save
|
||||||
|
|
||||||
expect{
|
expect { process(:readonly) }.to raise_error(Discourse::InvalidAccess)
|
||||||
process_email(from: restricted_user.email, to: to)
|
|
||||||
}.to raise_error(Discourse::InvalidAccess)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
it "works" do
|
||||||
|
Fabricate(:user, email: "sufficient@bar.com", trust_level: SiteSetting.email_in_min_trust)
|
||||||
describe "processes an unknown email sender to category" do
|
expect { process(:sufficient_trust_level) }.to change(Topic, :count)
|
||||||
let(:email_in) { "bob@bob.com" }
|
|
||||||
let(:user_email) { "#{SecureRandom.hex(32)}@foobar.com" }
|
|
||||||
let(:body) { "This is a new topic created\n\ninside a category ! :)" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.email_in = true
|
|
||||||
SiteSetting.allow_staged_accounts = true
|
|
||||||
end
|
|
||||||
|
|
||||||
it "rejects anon email" do
|
|
||||||
Fabricate(:category, email_in_allow_strangers: false, email_in: email_in)
|
|
||||||
|
|
||||||
expect {
|
|
||||||
process_email(from: user_email, to: email_in, body: body)
|
|
||||||
}.to raise_error(Email::Receiver::UserNotFoundError)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates a topic for matching category" do
|
|
||||||
Fabricate(:category, email_in_allow_strangers: true, email_in: email_in)
|
|
||||||
process_email(from: user_email, to: email_in, body: body)
|
|
||||||
|
|
||||||
staged_account = User.find_by_email(user_email)
|
|
||||||
expect(staged_account).to be
|
|
||||||
expect(staged_account.staged).to be(true)
|
|
||||||
expect(staged_account.posts.order(id: :desc).limit(1).pluck(:raw).first).to eq(body)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "processes an unknown email sender to group" do
|
|
||||||
let(:incoming_email) { "foo@bar.com" }
|
|
||||||
let(:user_email) { "#{SecureRandom.hex(32)}@foobar.com" }
|
|
||||||
let(:body) { "This is a message to\n\na group ;)" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.email_in = true
|
|
||||||
SiteSetting.allow_staged_accounts = true
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates a message for matching group" do
|
|
||||||
Fabricate(:group, incoming_email: incoming_email)
|
|
||||||
process_email(from: user_email, to: incoming_email, body: body)
|
|
||||||
|
|
||||||
staged_account = User.find_by_email(user_email)
|
|
||||||
expect(staged_account).to be
|
|
||||||
expect(staged_account.name).to eq("Jake the Dog")
|
|
||||||
expect(staged_account.staged).to be(true)
|
|
||||||
|
|
||||||
post = staged_account.posts.order(id: :desc).first
|
|
||||||
expect(post).to be
|
|
||||||
expect(post.raw).to eq(body)
|
|
||||||
expect(post.topic.private_message?).to eq(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "supports incoming mail in CC fields" do
|
|
||||||
|
|
||||||
let(:incoming_email) { "foo@bar.com" }
|
|
||||||
let(:user_email) { "#{SecureRandom.hex(32)}@foobar.com" }
|
|
||||||
let(:body) { "This is a message to\n\na group via CC ;)" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
SiteSetting.email_in = true
|
|
||||||
SiteSetting.allow_staged_accounts = true
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates a message for matching group" do
|
|
||||||
Fabricate(:group, incoming_email: incoming_email)
|
|
||||||
process_email(from: user_email, to: "some@email.com", body: body, cc: incoming_email)
|
|
||||||
|
|
||||||
staged_account = User.find_by_email(user_email)
|
|
||||||
expect(staged_account).to be
|
|
||||||
expect(staged_account.staged).to be(true)
|
|
||||||
|
|
||||||
post = staged_account.posts.order(id: :desc).first
|
|
||||||
expect(post).to be
|
|
||||||
expect(post.raw).to eq(body)
|
|
||||||
expect(post.topic.private_message?).to eq(true)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
177
spec/fixtures/emails/android_gmail.eml
vendored
177
spec/fixtures/emails/android_gmail.eml
vendored
|
@ -1,177 +0,0 @@
|
||||||
Delivered-To: reply@discourse.org
|
|
||||||
Return-Path: <walter.white@googlemail.com>
|
|
||||||
MIME-Version: 1.0
|
|
||||||
In-Reply-To: <topic/22638/86406@meta.discourse.org>
|
|
||||||
References: <topic/22638@meta.discourse.org>
|
|
||||||
<topic/22638/86406@meta.discourse.org>
|
|
||||||
Date: Fri, 28 Nov 2014 12:53:21 -0800
|
|
||||||
Subject: Re: [Discourse Meta] [Lounge] Testing default email replies
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
To: Discourse Meta <reply@discourse.org>
|
|
||||||
Content-Type: multipart/alternative; boundary=089e0149cfa485c6630508f173df
|
|
||||||
|
|
||||||
--089e0149cfa485c6630508f173df
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
|
|
||||||
### this is a reply from Android 5 gmail
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
This is **bold** in Markdown.
|
|
||||||
|
|
||||||
This is a link to http://example.com
|
|
||||||
On Nov 28, 2014 12:36 PM, "Arpit Jalan" <info@discourse.org> wrote:
|
|
||||||
|
|
||||||
> techAPJ <https://meta.discourse.org/users/techapj>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> Test reply.
|
|
||||||
>
|
|
||||||
> First paragraph.
|
|
||||||
>
|
|
||||||
> Second paragraph.
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies codinghorror
|
|
||||||
> <https://meta.discourse.org/users/codinghorror>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> We're testing the latest GitHub email processing library which we are
|
|
||||||
> integrating now.
|
|
||||||
>
|
|
||||||
> https://github.com/github/email_reply_parser
|
|
||||||
>
|
|
||||||
> Go ahead and reply to this topic and I'll reply from various email clients
|
|
||||||
> for testing.
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <https://meta.discourse.org/my/preferences>.
|
|
||||||
>
|
|
||||||
|
|
||||||
--089e0149cfa485c6630508f173df
|
|
||||||
Content-Type: text/html; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
<p dir=3D"ltr">### this is a reply from Android 5 gmail</p>
|
|
||||||
<p dir=3D"ltr">The quick brown fox jumps over the lazy dog. The quick brown=
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. =
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over=
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. </p>
|
|
||||||
<p dir=3D"ltr">This is **bold** in Markdown.</p>
|
|
||||||
<p dir=3D"ltr">This is a link to <a href=3D"http://example.com">http://exam=
|
|
||||||
ple.com</a></p>
|
|
||||||
<div class=3D"gmail_quote">On Nov 28, 2014 12:36 PM, "Arpit Jalan"=
|
|
||||||
; <<a href=3D"mailto:info@discourse.org">info@discourse.org</a>> wrot=
|
|
||||||
e:<br type=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"margi=
|
|
||||||
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px" cellspacing=3D"0" cellpadding=3D"0" bor=
|
|
||||||
der=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/techapj/45/3281.png" title=3D"techAPJ" style=3D"max-wi=
|
|
||||||
dth:100%" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/techapj" style=3D"text-=
|
|
||||||
decoration:none;font-weight:bold;color:#006699;font-size:13px;font-family:&=
|
|
||||||
#39;lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-d=
|
|
||||||
ecoration:none;font-weight:bold" target=3D"_blank">techAPJ</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">November 28</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0;border:0">Test reply.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">First paragraph.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">Second paragraph.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"https://meta.dis=
|
|
||||||
course.org/t/testing-default-email-replies/22638/3" style=3D"text-decoratio=
|
|
||||||
n:none;font-weight:bold;color:#006699;color:#666" target=3D"_blank">https:/=
|
|
||||||
/meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your bro=
|
|
||||||
wser.</p>
|
|
||||||
</div>
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-c=
|
|
||||||
olor:#ddd;min-height:1px;border:1px">
|
|
||||||
<h4>Previous Replies</h4>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px" cellspacing=3D"0" cellpadding=3D"0" b=
|
|
||||||
order=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/codinghorror/45/5297.png" title=3D"codinghorror" style=
|
|
||||||
=3D"max-width:100%" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/codinghorror" style=3D"=
|
|
||||||
text-decoration:none;font-weight:bold;color:#006699;font-size:13px;font-fam=
|
|
||||||
ily:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;t=
|
|
||||||
ext-decoration:none;font-weight:bold" target=3D"_blank">codinghorror</a><br=
|
|
||||||
>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">November 28</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0;border:0">We're testing the latest GitHub emai=
|
|
||||||
l processing library which we are integrating now.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0"><a href=3D"https://github.com/github/ema=
|
|
||||||
il_reply_parser" style=3D"text-decoration:none;font-weight:bold;color:#0066=
|
|
||||||
99" target=3D"_blank">https://github.com/github/email_reply_parser</a></p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">Go ahead and reply to this topic and I&#=
|
|
||||||
39;ll reply from various email clients for testing.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-col=
|
|
||||||
or:#ddd;min-height:1px;border:1px">
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"https://meta.discour=
|
|
||||||
se.org/t/testing-default-email-replies/22638/3" style=3D"text-decoration:no=
|
|
||||||
ne;font-weight:bold;color:#006699;color:#666" target=3D"_blank">https://met=
|
|
||||||
a.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser=
|
|
||||||
.</p>
|
|
||||||
</div>
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href=3D"https://meta.dis=
|
|
||||||
course.org/my/preferences" style=3D"text-decoration:none;font-weight:bold;c=
|
|
||||||
olor:#006699;color:#666" target=3D"_blank">user preferences</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</blockquote></div>
|
|
||||||
|
|
||||||
--089e0149cfa485c6630508f173df--
|
|
351
spec/fixtures/emails/attachment.eml
vendored
351
spec/fixtures/emails/attachment.eml
vendored
|
@ -1,351 +0,0 @@
|
||||||
Message-ID: <51C22E52.1030509@darthvader.ca>
|
|
||||||
Date: Wed, 19 Jun 2013 18:18:58 -0400
|
|
||||||
From: Anakin Skywalker <FROM>
|
|
||||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130510 Thunderbird/17.0.6
|
|
||||||
MIME-Version: 1.0
|
|
||||||
To: Han Solo via Death Star <TO>
|
|
||||||
Subject: Re: [Death Star] [PM] re: Regarding your post in "Site Customization
|
|
||||||
not working"
|
|
||||||
References: <51d23d33f41fb_5f4e4b35d7d60798@xwing.mail>
|
|
||||||
In-Reply-To: <51d23d33f41fb_5f4e4b35d7d60798@xwing.mail>
|
|
||||||
Content-Type: multipart/mixed; boundary=047d7b45041e19c68004eb9f3de8
|
|
||||||
|
|
||||||
--047d7b45041e19c68004eb9f3de8
|
|
||||||
Content-Type: multipart/alternative; boundary=047d7b45041e19c67b04eb9f3de6
|
|
||||||
|
|
||||||
--047d7b45041e19c67b04eb9f3de6
|
|
||||||
Content-Type: text/plain; charset=ISO-8859-1
|
|
||||||
|
|
||||||
here is an image attachment
|
|
||||||
|
|
||||||
|
|
||||||
On Tue, Nov 19, 2013 at 5:11 PM, Neil <info@discourse.org> wrote:
|
|
||||||
|
|
||||||
> Neil <http://meta.discourse.org/users/neil>
|
|
||||||
> November 19
|
|
||||||
>
|
|
||||||
> Actually, deleting a spammer does what it's supposed to. It does mark the
|
|
||||||
> topic as deleted.
|
|
||||||
>
|
|
||||||
> That topic has id 11002, and you're right that the user was deleted.
|
|
||||||
>
|
|
||||||
> @eviltrout <http://users/eviltrout> Any idea why it showed up in
|
|
||||||
> suggested topics?
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> http://meta.discourse.org/t/spam-post-pops-back-up-in-suggested-topics/11005/5in your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies Neil <http://meta.discourse.org/users/neil>
|
|
||||||
> November 19
|
|
||||||
>
|
|
||||||
> Looks like a bug when deleting a spammer. I'll look at it.
|
|
||||||
> riking <http://meta.discourse.org/users/riking>
|
|
||||||
> November 19
|
|
||||||
>
|
|
||||||
> codinghorror:
|
|
||||||
>
|
|
||||||
> I can't even find that topic by name.
|
|
||||||
>
|
|
||||||
> In that case, I'm fairly certain someone used the 'Delete Spammer'
|
|
||||||
> function on the user, which would explain your inability to find it - it's
|
|
||||||
> gone.
|
|
||||||
>
|
|
||||||
> I'm raising this because, well, it's gone and shouldn't be showing up. And
|
|
||||||
> even if it was hanging around, it should be invisible to me, and not
|
|
||||||
> showing up in Suggested Topics.
|
|
||||||
> codinghorror <http://meta.discourse.org/users/codinghorror>
|
|
||||||
> November 19
|
|
||||||
>
|
|
||||||
> Hmm, that's interesting -- can you have a look @eviltrout<http://users/eviltrout>?
|
|
||||||
> I can't even find that topic by name.
|
|
||||||
> riking <http://meta.discourse.org/users/riking>
|
|
||||||
> November 19
|
|
||||||
>
|
|
||||||
> I'm one of the users who flagged this particular spam post, and it was
|
|
||||||
> promptly deleted/hidden, but it just popped up in the Suggested Topics box:
|
|
||||||
>
|
|
||||||
> Pasted image1125x220 27.7 KB
|
|
||||||
> <//cdn.discourse.org/uploads/meta_discourse/2158/50b8b49557cb249e.png>
|
|
||||||
>
|
|
||||||
> We may want to recheck the suppression on these.
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> http://meta.discourse.org/t/spam-post-pops-back-up-in-suggested-topics/11005/5in your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences<http://meta.discourse.org/user_preferences>
|
|
||||||
> .
|
|
||||||
>
|
|
||||||
|
|
||||||
--047d7b45041e19c67b04eb9f3de6
|
|
||||||
Content-Type: text/html; charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
<div dir=3D"ltr">here is an image attachment</div><div class=3D"gmail_extra=
|
|
||||||
"><br><br><div class=3D"gmail_quote">On Tue, Nov 19, 2013 at 5:11 PM, Neil =
|
|
||||||
<span dir=3D"ltr"><<a href=3D"mailto:info@discourse.org" target=3D"_blan=
|
|
||||||
k">info@discourse.org</a>></span> wrote:<br>
|
|
||||||
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
|
|
||||||
x #ccc solid;padding-left:1ex"><div>
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cellp=
|
|
||||||
adding=3D"0" border=3D"0"><tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"http://www.gravatar.com/avatar/42776c4982dff1fa45ee8248=
|
|
||||||
532f8ad0.png?s=3D45&r=3Dpg&d=3Didenticon" title=3D"Neil" style=3D"m=
|
|
||||||
ax-width:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"http://meta.discourse.org/users/neil" style=3D"font-size=
|
|
||||||
:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;c=
|
|
||||||
olor:#3b5998;text-decoration:none;font-weight:bold" target=3D"_blank">Neil<=
|
|
||||||
/a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;font-family=
|
|
||||||
:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">No=
|
|
||||||
vember 19</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0">Actually, deleting a spammer does what it's s=
|
|
||||||
upposed to. It does mark the topic as deleted.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0">That topic has id 11002, and you're right tha=
|
|
||||||
t the user was deleted.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0"><a href=3D"http://users/eviltrout" target=3D"_bla=
|
|
||||||
nk">@eviltrout</a> Any idea why it showed up in suggested topics? </p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"http://meta.disc=
|
|
||||||
ourse.org/t/spam-post-pops-back-up-in-suggested-topics/11005/5" style=3D"co=
|
|
||||||
lor:#666" target=3D"_blank">http://meta.discourse.org/t/spam-post-pops-back=
|
|
||||||
-up-in-suggested-topics/11005/5</a> in your browser.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px">
|
|
||||||
<h4>Previous Replies</h4>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cel=
|
|
||||||
lpadding=3D"0" border=3D"0"><tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"http://www.gravatar.com/avatar/42776c4982dff1fa45ee8248=
|
|
||||||
532f8ad0.png?s=3D45&r=3Dpg&d=3Didenticon" title=3D"Neil" style=3D"m=
|
|
||||||
ax-width:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"http://meta.discourse.org/users/neil" style=3D"font-size=
|
|
||||||
:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;c=
|
|
||||||
olor:#3b5998;text-decoration:none;font-weight:bold" target=3D"_blank">Neil<=
|
|
||||||
/a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;font-family=
|
|
||||||
:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">No=
|
|
||||||
vember 19</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2"><p style=3D"margin-top:0">Looks=
|
|
||||||
like a bug when deleting a spammer. I'll look at it.</p></td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cellp=
|
|
||||||
adding=3D"0" border=3D"0"><tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"http://www.gravatar.com/avatar/5120fc4e345db0d1a9648882=
|
|
||||||
72073819.png?s=3D45&r=3Dpg&d=3Didenticon" title=3D"riking" style=3D=
|
|
||||||
"max-width:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"http://meta.discourse.org/users/riking" style=3D"font-si=
|
|
||||||
ze:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif=
|
|
||||||
;color:#3b5998;text-decoration:none;font-weight:bold" target=3D"_blank">rik=
|
|
||||||
ing</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;font-family=
|
|
||||||
:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">No=
|
|
||||||
vember 19</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0"><u></u></p><div>
|
|
||||||
<div></div>
|
|
||||||
<img width=3D"20" height=3D"20" src=3D"http://www.gravatar.com/avatar/51d62=
|
|
||||||
3f33f8b83095db84ff35e15dbe8.png?s=3D40&r=3Dpg&d=3Didenticon" style=
|
|
||||||
=3D"max-width:694px">codinghorror:</div>
|
|
||||||
<blockquote><p style=3D"margin-top:0">I can't even find that topic by n=
|
|
||||||
ame.</p></blockquote><u></u><p></p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0">In that case, I'm fairly certain someone used=
|
|
||||||
the 'Delete Spammer' function on the user, which would explain you=
|
|
||||||
r inability to find it - it's gone.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0">I'm raising this because, well, it's gone=
|
|
||||||
and shouldn't be showing up. And even if it was hanging around, it sho=
|
|
||||||
uld be invisible to me, and not showing up in Suggested Topics.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cellp=
|
|
||||||
adding=3D"0" border=3D"0"><tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"http://www.gravatar.com/avatar/51d623f33f8b83095db84ff3=
|
|
||||||
5e15dbe8.png?s=3D45&r=3Dpg&d=3Didenticon" title=3D"codinghorror" st=
|
|
||||||
yle=3D"max-width:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"http://meta.discourse.org/users/codinghorror" style=3D"f=
|
|
||||||
ont-size:13px;font-family:'lucida grande',tahoma,verdana,arial,sans=
|
|
||||||
-serif;color:#3b5998;text-decoration:none;font-weight:bold" target=3D"_blan=
|
|
||||||
k">codinghorror</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;font-family=
|
|
||||||
:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">No=
|
|
||||||
vember 19</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2"><p style=3D"margin-top:0">Hmm, =
|
|
||||||
that's interesting -- can you have a look <a href=3D"http://users/evilt=
|
|
||||||
rout" target=3D"_blank">@eviltrout</a>? I can't even find that topic by=
|
|
||||||
name. </p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cellp=
|
|
||||||
adding=3D"0" border=3D"0"><tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"http://www.gravatar.com/avatar/5120fc4e345db0d1a9648882=
|
|
||||||
72073819.png?s=3D45&r=3Dpg&d=3Didenticon" title=3D"riking" style=3D=
|
|
||||||
"max-width:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"http://meta.discourse.org/users/riking" style=3D"font-si=
|
|
||||||
ze:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif=
|
|
||||||
;color:#3b5998;text-decoration:none;font-weight:bold" target=3D"_blank">rik=
|
|
||||||
ing</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;font-family=
|
|
||||||
:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">No=
|
|
||||||
vember 19</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0">I'm one of the users who flagged this particu=
|
|
||||||
lar spam post, and it was promptly deleted/hidden, but it just popped up in=
|
|
||||||
the Suggested Topics box:</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0"></p>
|
|
||||||
<div><a href=3D"//cdn.discourse.org/uploads/meta_discourse/2158/50b8b49557c=
|
|
||||||
b249e.png" target=3D"_blank"><img src=3D"http://cdn.discourse.org/uploads/m=
|
|
||||||
eta_discourse/_optimized/ab1/c92/acd2c33402_584x134.png" width=3D"584" heig=
|
|
||||||
ht=3D"134" style=3D"max-width:694px"><div>
|
|
||||||
|
|
||||||
<span>Pasted image</span><span>1125x220 27.7 KB</span><span></span>
|
|
||||||
</div></a></div>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0">We may want to recheck the suppression on these.<=
|
|
||||||
/p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody></table>
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px">
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"http://meta.discours=
|
|
||||||
e.org/t/spam-post-pops-back-up-in-suggested-topics/11005/5" style=3D"color:=
|
|
||||||
#666" target=3D"_blank">http://meta.discourse.org/t/spam-post-pops-back-up-=
|
|
||||||
in-suggested-topics/11005/5</a> in your browser.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href=3D"http://meta.disc=
|
|
||||||
ourse.org/user_preferences" style=3D"color:#666" target=3D"_blank">user pre=
|
|
||||||
ferences</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div></blockquote></div><br></div>
|
|
||||||
|
|
||||||
--047d7b45041e19c67b04eb9f3de6--
|
|
||||||
--047d7b45041e19c68004eb9f3de8
|
|
||||||
Content-Type: image/png; name="bricks.png"
|
|
||||||
Content-Disposition: attachment; filename="bricks.png"
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
X-Attachment-Id: f_ho8uteve0
|
|
||||||
|
|
||||||
iVBORw0KGgoAAAANSUhEUgAAASEAAAB+CAIAAADk0DDaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
|
|
||||||
bWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdp
|
|
||||||
bj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6
|
|
||||||
eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEz
|
|
||||||
NDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJo
|
|
||||||
dHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlw
|
|
||||||
dGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAv
|
|
||||||
IiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RS
|
|
||||||
ZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpD
|
|
||||||
cmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNl
|
|
||||||
SUQ9InhtcC5paWQ6MDYxQjcyOUUzMDM1MTFFM0JFRTFBOTQ1RUY4QUU4MDIiIHhtcE1NOkRvY3Vt
|
|
||||||
ZW50SUQ9InhtcC5kaWQ6MDYxQjcyOUYzMDM1MTFFM0JFRTFBOTQ1RUY4QUU4MDIiPiA8eG1wTU06
|
|
||||||
RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowNjFCNzI5QzMwMzUxMUUzQkVF
|
|
||||||
MUE5NDVFRjhBRTgwMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowNjFCNzI5RDMwMzUxMUUz
|
|
||||||
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
|
|
||||||
AAAAAElFTkSuQmCC
|
|
||||||
--047d7b45041e19c68004eb9f3de8--
|
|
8
spec/fixtures/emails/auto_generated_header.eml
vendored
Normal file
8
spec/fixtures/emails/auto_generated_header.eml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Return-Path: <foo@bar.com>
|
||||||
|
From: Foo Bar <foo@bar.com>
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <3@foo.bar.mail>
|
||||||
|
Auto-Submitted: auto-generated
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
8
spec/fixtures/emails/auto_generated_precedence.eml
vendored
Normal file
8
spec/fixtures/emails/auto_generated_precedence.eml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Return-Path: <foo@bar.com>
|
||||||
|
From: Foo Bar <foo@bar.com>
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <2@foo.bar.mail>
|
||||||
|
Precedence: list
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
21
spec/fixtures/emails/auto_reply.eml
vendored
21
spec/fixtures/emails/auto_reply.eml
vendored
|
@ -1,21 +0,0 @@
|
||||||
Return-Path: <jake@adventuretime.ooo>
|
|
||||||
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@discourse.example.com>; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@discourse.example.com>; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Date: Thu, 13 Jun 2013 17:03:48 -0400
|
|
||||||
From: Jake the Dog <jake@adventuretime.ooo>
|
|
||||||
To: reply+636ca428858779856c226bb145ef4fad@appmail.adventuretime.ooo
|
|
||||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
|
||||||
Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'
|
|
||||||
Mime-Version: 1.0
|
|
||||||
Content-Type: text/plain;
|
|
||||||
charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
Auto-Submitted: auto-generated
|
|
||||||
X-Sieve: CMU Sieve 2.2
|
|
||||||
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
|
|
||||||
13 Jun 2013 14:03:48 -0700 (PDT)
|
|
||||||
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
|
|
||||||
|
|
||||||
Test reply to Discourse email digest
|
|
11
spec/fixtures/emails/bad_destinations.eml
vendored
Normal file
11
spec/fixtures/emails/bad_destinations.eml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Return-Path: <staged@bar.com>
|
||||||
|
From: Foo Bar <staged@bar.com>
|
||||||
|
To: wat@bar.com
|
||||||
|
Cc: foofoo@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <9@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
26
spec/fixtures/emails/big5.eml
vendored
26
spec/fixtures/emails/big5.eml
vendored
|
@ -1,26 +0,0 @@
|
||||||
|
|
||||||
Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org
|
|
||||||
Received: by 10.194.216.104 with SMTP id op8csp80593wjc;
|
|
||||||
Wed, 24 Jul 2013 07:59:14 -0700 (PDT)
|
|
||||||
Return-Path: <walter.white@googlemail.com>
|
|
||||||
References: <topic/5043@discourse.org> <51efeb9b36c34_66dc2dfce6811866@discourse.mail>
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail>
|
|
||||||
Mime-Version: 1.0 (1.0)
|
|
||||||
Date: Wed, 24 Jul 2013 15:59:10 +0100
|
|
||||||
Message-ID: <4597127794206131679@unknownmsgid>
|
|
||||||
Subject: Re: [Discourse] new reply to your post in 'Crystal Blue'
|
|
||||||
To: walter via Discourse <reply+cd480e301683c9902891f15968bf07a5@appmail.adventuretime.ooo>
|
|
||||||
Content-Type: multipart/alternative; boundary=20cf301cc47ada510404f040b262
|
|
||||||
|
|
||||||
--20cf301cc47ada510404f040b262
|
|
||||||
Content-Type: text/plain; charset=Big5
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
tv2hSafapFe5cbX4pEahSQ0K
|
|
||||||
--20cf301cc47ada510404f040b262
|
|
||||||
Content-Type: text/html; charset=Big5
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
PGRpdiBkaXI9Imx0ciI+tv2hSafapFe5cbX4pEahSTxicj48L2Rpdj4NCg==
|
|
||||||
--20cf301cc47ada510404f040b262--
|
|
160
spec/fixtures/emails/bottom_reply.eml
vendored
160
spec/fixtures/emails/bottom_reply.eml
vendored
|
@ -1,160 +0,0 @@
|
||||||
Received: by 10.107.19.29 with SMTP id b29csp111716ioj;
|
|
||||||
Wed, 30 Jul 2014 17:52:05 -0700 (PDT)
|
|
||||||
X-Received: by 10.194.238.6 with SMTP id vg6mr11340975wjc.24.1406767925330;
|
|
||||||
Wed, 30 Jul 2014 17:52:05 -0700 (PDT)
|
|
||||||
Received: from localhost (localhost [127.0.0.1])
|
|
||||||
by bendel.debian.org (Postfix) with QMQP
|
|
||||||
id 18F5C417; Thu, 31 Jul 2014 00:52:04 +0000 (UTC)
|
|
||||||
Old-Return-Path: <vorlon@debian.org>
|
|
||||||
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on bendel.debian.org
|
|
||||||
X-Spam-Level:
|
|
||||||
X-Spam-Status: No, score=-25.9 required=4.0 tests=FOURLA,LDOSUBSCRIBER,
|
|
||||||
LDO_WHITELIST,MURPHY_DEBIAN_MESSAGE,PGPSIGNATURE autolearn=unavailable
|
|
||||||
version=3.3.2
|
|
||||||
X-Original-To: lists-debian-ctte@bendel.debian.org
|
|
||||||
Delivered-To: lists-debian-ctte@bendel.debian.org
|
|
||||||
Received: from localhost (localhost [127.0.0.1])
|
|
||||||
by bendel.debian.org (Postfix) with ESMTP id CE6CDEE
|
|
||||||
for <lists-debian-ctte@bendel.debian.org>; Thu, 31 Jul 2014 00:51:52 +0000 (UTC)
|
|
||||||
X-Virus-Scanned: at lists.debian.org with policy bank en-lt
|
|
||||||
X-Amavis-Spam-Status: No, score=-11.9 tagged_above=-10000 required=5.3
|
|
||||||
tests=[BAYES_00=-2, FOURLA=0.1, LDO_WHITELIST=-5, PGPSIGNATURE=-5]
|
|
||||||
autolearn=ham
|
|
||||||
Received: from bendel.debian.org ([127.0.0.1])
|
|
||||||
by localhost (lists.debian.org [127.0.0.1]) (amavisd-new, port 2525)
|
|
||||||
with ESMTP id SB451DwGZCOe for <lists-debian-ctte@bendel.debian.org>;
|
|
||||||
Thu, 31 Jul 2014 00:51:47 +0000 (UTC)
|
|
||||||
X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_BL_NJABL=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .debian. - helo: .becquer.dodds. - helo-domain: .dodds.) FROM/MX_MATCHES_NOT_HELO(DOMAIN)=0; rate: -5
|
|
||||||
Received: from becquer.dodds.net (becquer.dodds.net [207.224.24.209])
|
|
||||||
by bendel.debian.org (Postfix) with ESMTP id 8E89A2B4
|
|
||||||
for <debian-ctte@lists.debian.org>; Thu, 31 Jul 2014 00:51:47 +0000 (UTC)
|
|
||||||
Received: from virgil.dodds.net (unknown [192.168.15.59])
|
|
||||||
by becquer.dodds.net (Postfix) with ESMTPA id 9B0A9256EB
|
|
||||||
for <debian-ctte@lists.debian.org>; Wed, 30 Jul 2014 17:51:19 -0700 (PDT)
|
|
||||||
Received: by virgil.dodds.net (Postfix, from userid 1000)
|
|
||||||
id 942FB60199; Wed, 30 Jul 2014 17:51:15 -0700 (PDT)
|
|
||||||
Date: Wed, 30 Jul 2014 17:51:15 -0700
|
|
||||||
From: Jake <jake@adventuretime.ooo>
|
|
||||||
To: incoming+amazing@appmail.adventuretime.ooo
|
|
||||||
Subject: Re: Next Debian CTTE IRC Meeting at date -d'Thu Jul 31 17:00:00 UTC
|
|
||||||
2014'
|
|
||||||
Message-ID: <20140731005115.GA19044@virgil.dodds.net>
|
|
||||||
Mail-Followup-To: debian-ctte@lists.debian.org
|
|
||||||
References: <20140730213924.GA12356@teltox.donarmstrong.com>
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: multipart/signed; micalg=pgp-sha256;
|
|
||||||
protocol="application/pgp-signature"; boundary="qMm9M+Fa2AknHoGS"
|
|
||||||
Content-Disposition: inline
|
|
||||||
In-Reply-To: <20140730213924.GA12356@teltox.donarmstrong.com>
|
|
||||||
User-Agent: Mutt/1.5.23 (2014-03-12)
|
|
||||||
X-Debian-Message: Signature check passed for Debian member
|
|
||||||
X-Rc-Virus: 2007-09-13_01
|
|
||||||
X-Rc-Spam: 2008-11-04_01
|
|
||||||
Resent-Message-ID: <c_LGA2C2wUK.A.URD.zMZ2TB@bendel>
|
|
||||||
Resent-From: debian-ctte@lists.debian.org
|
|
||||||
X-Mailing-List: <debian-ctte@lists.debian.org> archive/latest/4791
|
|
||||||
X-Loop: debian-ctte@lists.debian.org
|
|
||||||
List-Id: <debian-ctte.lists.debian.org>
|
|
||||||
List-Post: <mailto:debian-ctte@lists.debian.org>
|
|
||||||
List-Help: <mailto:debian-ctte-request@lists.debian.org?subject=help>
|
|
||||||
List-Subscribe: <mailto:debian-ctte-request@lists.debian.org?subject=subscribe>
|
|
||||||
List-Unsubscribe: <mailto:debian-ctte-request@lists.debian.org?subject=unsubscribe>
|
|
||||||
Precedence: list
|
|
||||||
Resent-Sender: debian-ctte-request@lists.debian.org
|
|
||||||
Resent-Date: Thu, 31 Jul 2014 00:52:04 +0000 (UTC)
|
|
||||||
|
|
||||||
|
|
||||||
--qMm9M+Fa2AknHoGS
|
|
||||||
Content-Type: text/plain; charset=us-ascii
|
|
||||||
Content-Disposition: inline
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
On Wed, Jul 30, 2014 at 02:39:24PM -0700, Don Armstrong wrote:
|
|
||||||
> The next Debian CTTE IRC meeting is at=20
|
|
||||||
|
|
||||||
> date -d 'Thu Jul 31 17:00:00 UTC 2014' on irc.debian.org in
|
|
||||||
> #debian-ctte.
|
|
||||||
|
|
||||||
> The current meeting agenda is here, and more up-to-date ones may be
|
|
||||||
> found in the git repository.
|
|
||||||
|
|
||||||
> #startmeeting
|
|
||||||
|
|
||||||
> #topic Who is here?
|
|
||||||
|
|
||||||
> #topic Next Meeting?
|
|
||||||
|
|
||||||
> #topic #717076 Decide between libjpeg-turbo and libjpeg8 et al.
|
|
||||||
|
|
||||||
This has been voted on; should probably be removed from the agenda, someone
|
|
||||||
just needs to confirm the vote results and get it on the website. (AIUI the
|
|
||||||
archive has already begun moving on accordingly.)
|
|
||||||
|
|
||||||
> #topic #636783 constitution: super-majority bug
|
|
||||||
|
|
||||||
> #topic #636783 constitution: casting vote
|
|
||||||
|
|
||||||
> #topic #636783 constitution: minimum discussion period
|
|
||||||
|
|
||||||
> #topic #636783 constitution: TC member retirement/rollover
|
|
||||||
|
|
||||||
> #topic #636783 constitution: TC chair retirement/rollover
|
|
||||||
|
|
||||||
> #topic #681419 Depends: foo | foo-nonfree
|
|
||||||
|
|
||||||
> #topic #741573 menu systems and mime-support
|
|
||||||
|
|
||||||
> #topic #746715 init system fallout
|
|
||||||
|
|
||||||
Also voted and just needs to be confirmed.
|
|
||||||
|
|
||||||
> #topic #750135 Maintainer of aptitude package
|
|
||||||
>=20
|
|
||||||
> #topic #752400 Advice on util-linux
|
|
||||||
|
|
||||||
This has been closed by mutual agreement of the people involved and doesn't
|
|
||||||
require any action from the TC. Removed from the agenda.
|
|
||||||
|
|
||||||
There's also bug #744246, which was assigned to the TC at my request but
|
|
||||||
without any preamble so it may have escaped notice. However, that situation
|
|
||||||
has been evolving constructively among the related parties (apparently, an
|
|
||||||
informal comment from a member of the release team was mistaken for a
|
|
||||||
release team position, so that's now being revisited), so I don't believe
|
|
||||||
this is anything we need to put on the agenda for tomorrow despite being on
|
|
||||||
the open bug list.
|
|
||||||
|
|
||||||
--=20
|
|
||||||
Steve Langasek Give me a lever long enough and a Free OS
|
|
||||||
Debian Developer to set it on, and I can move the world.
|
|
||||||
Ubuntu Developer http://www.debian.org/
|
|
||||||
slangasek@ubuntu.com vorlon@debian.org
|
|
||||||
|
|
||||||
--qMm9M+Fa2AknHoGS
|
|
||||||
Content-Type: application/pgp-signature; name="signature.asc"
|
|
||||||
Content-Description: Digital signature
|
|
||||||
|
|
||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
Version: GnuPG v1
|
|
||||||
|
|
||||||
iQIcBAEBCAAGBQJT2ZMDAAoJEFaNMPMhshM9GLsP/244S3wtYZEeVgJWIdB5PE0A
|
|
||||||
sZVezEA692y++/0oVZVecwV67yBOyfSjPPetdAph2UDMRtfurwxfj2BkbOFA2+Y6
|
|
||||||
++MErbmC3V7IGpd/L/fFGdXgvMQT2MNBpw0fnMA7bLpNjCvoj+Hr1HXRUcWoJSlj
|
|
||||||
WmHWwWSTVRcHg8a3iWYJzY6XfLyEEgHlahrlKvJExsTx/9mc1qg7g8KGdnhzHFBl
|
|
||||||
ttdH2fxpAk/624dReCcw5RKmOLfZ1HsEl9XcVe1cb4K+MDaQiXmoEK5v3xaNz1tS
|
|
||||||
NK5v2D5gDs229zoxKzQnnzOPLHxqI5E0L9PpI/mu4T9z7H2bHR3U5BvhnT99t5uw
|
|
||||||
ydf2cZNGY0uFCV3Rvn07BfAIW5WSXhOfN/5IymRKmdhjsTiwZ/wFjFrK8tVjtERu
|
|
||||||
yeyA7RIYiblGCEKYIYLWSxhoXeEdmAdfp6EA2/IA1CpgMB+ZdSfaeMgFY7xosgmG
|
|
||||||
ax3NTnaKyhr1QEUJ2gjAwHnKjuGbRVDAinYrSvP0o8Bh9sAs2BN2negWBCZVwwkN
|
|
||||||
S9hWTjVqsBmpaPOt5SEDwDo9O9dfzkmaamDsxOuUEz9F7v5jYg0mxA/WbogGty9R
|
|
||||||
vOMKxdxRkzflL/CferVbkzL/EkZRDfWDp9SleZggrpz7miiNDbS7jdRzJ4EttmJ8
|
|
||||||
gHBAVrOzcnbIPOIkk9pw
|
|
||||||
=KXIu
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
|
|
||||||
--qMm9M+Fa2AknHoGS--
|
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
To UNSUBSCRIBE, email to debian-ctte-REQUEST@lists.debian.org
|
|
||||||
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
|
|
||||||
Archive: https://lists.debian.org/20140731005115.GA19044@virgil.dodds.net
|
|
61
spec/fixtures/emails/boundary.eml
vendored
61
spec/fixtures/emails/boundary.eml
vendored
|
@ -1,61 +0,0 @@
|
||||||
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Received: by 10.64.14.41 with HTTP; Wed, 19 Jun 2013 06:29:41 -0700 (PDT)
|
|
||||||
In-Reply-To: <51c19490e928a_13442dd8ae892548@tree.mail>
|
|
||||||
References: <51c19490e928a_13442dd8ae892548@tree.mail>
|
|
||||||
Date: Wed, 19 Jun 2013 09:29:41 -0400
|
|
||||||
Delivered-To: finn@adventuretime.ooo
|
|
||||||
Message-ID: <CADkmRcL=2aPV7jOcs2i00QGZNwmjYj3qMaJTsKnB7DTP5sgyFQ@mail.gmail.com>
|
|
||||||
Subject: Re: [Adventure Time] jake mentioned you in 'peppermint butler is
|
|
||||||
missing'
|
|
||||||
From: Finn the Human <finn@adventuretime.ooo>
|
|
||||||
To: jake via Adventure Time <reply+96dcd9072ba9072d06226009d4223a6e@appmail.adventuretime.ooo>
|
|
||||||
Content-Type: multipart/alternative; boundary=001a11c206a073876a04df81d2a9
|
|
||||||
|
|
||||||
--001a11c206a073876a04df81d2a9
|
|
||||||
Content-Type: text/plain; charset=ISO-8859-1
|
|
||||||
|
|
||||||
I'll look into it, thanks!
|
|
||||||
|
|
||||||
|
|
||||||
On Wednesday, June 19, 2013, jake via Discourse wrote:
|
|
||||||
|
|
||||||
> jake mentioned you in 'peppermint butler is missing' on Adventure
|
|
||||||
> Time:
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> yeah, just noticed this cc @jake
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> Please visit this link to respond:
|
|
||||||
> http://adventuretime.ooo/t/peppermint-butler-is-missing/7628/2
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <http://adventuretime.ooo/user_preferences>.
|
|
||||||
>
|
|
||||||
|
|
||||||
--001a11c206a073876a04df81d2a9
|
|
||||||
Content-Type: text/html; charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
I'll look into it, thanks!<span></span><br><br>On Wednesday, June 19, 2=
|
|
||||||
013, jake via Adventure Time wrote:<br><blockquote class=3D"gmail_quote" st=
|
|
||||||
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><p>sa=
|
|
||||||
m mentioned you in 'Duplicate message are shown in profile' on Adve=
|
|
||||||
nture Time</p>
|
|
||||||
|
|
||||||
|
|
||||||
<hr><p>yeah, just noticed this cc <a href=3D"http://users/eviltrout" target=
|
|
||||||
=3D"_blank">@eviltrout</a> </p>
|
|
||||||
|
|
||||||
<hr><p>Please visit this link to respond: <a href=3D"http://adventuretime.oo=
|
|
||||||
o/t/duplicate-message-are-shown-in-profile/7628/2" target=3D"_blank">http=
|
|
||||||
://adventuretime.ooo/t/peppermint-butler-is-missing/7628/2</a></=
|
|
||||||
p>
|
|
||||||
|
|
||||||
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href=3D"http://adventuret=
|
|
||||||
ime.ooo/user_preferences" target=3D"_blank">user preferences</a>.</p>
|
|
||||||
</blockquote>
|
|
||||||
|
|
||||||
--001a11c206a073876a04df81d2a9--
|
|
12
spec/fixtures/emails/cc.eml
vendored
Normal file
12
spec/fixtures/emails/cc.eml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: someone@else.com
|
||||||
|
CC: team@bar.com, wat@bar.com, 42@bar.com
|
||||||
|
Subject: The more, the merrier
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <30@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
It is more fun with more people.
|
10
spec/fixtures/emails/chinese_reply.eml
vendored
Normal file
10
spec/fixtures/emails/chinese_reply.eml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <17@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=Big5
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
5oKo5aW977yBIOS9oOS7iuWkqeWlveWQl++8nw==
|
20
spec/fixtures/emails/dutch.eml
vendored
20
spec/fixtures/emails/dutch.eml
vendored
|
@ -1,20 +0,0 @@
|
||||||
|
|
||||||
Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org
|
|
||||||
Received: by 10.194.216.104 with SMTP id op8csp80593wjc;
|
|
||||||
Wed, 24 Jul 2013 07:59:14 -0700 (PDT)
|
|
||||||
Return-Path: <walter.white@googlemail.com>
|
|
||||||
References: <topic/5043@discourse.org> <51efeb9b36c34_66dc2dfce6811866@discourse.mail>
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail>
|
|
||||||
Mime-Version: 1.0 (1.0)
|
|
||||||
Date: Wed, 24 Jul 2013 15:59:10 +0100
|
|
||||||
Message-ID: <4597127794206131679@unknownmsgid>
|
|
||||||
Subject: Re: [Discourse] new reply to your post in 'Crystal Blue'
|
|
||||||
To: walter via Discourse <reply+cd480e301683c9902891f15968bf07a5@appmail.adventuretime.ooo>
|
|
||||||
Content-Type: multipart/alternative; boundary=001a11c20edc15a39304e2432790
|
|
||||||
|
|
||||||
Dit is een antwoord in het Nederlands.
|
|
||||||
|
|
||||||
Op 18 juli 2013 10:23 schreef Sander Datema het volgende:
|
|
||||||
|
|
||||||
Dit is de originele post.
|
|
21
spec/fixtures/emails/empty.eml
vendored
21
spec/fixtures/emails/empty.eml
vendored
|
@ -1,21 +0,0 @@
|
||||||
Return-Path: <jake@adventuretime.ooo>
|
|
||||||
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@discourse.example.com>; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@discourse.example.com>; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Date: Thu, 13 Jun 2013 17:03:48 -0400
|
|
||||||
From: Jake the Dog <jake@adventuretime.ooo>
|
|
||||||
To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo
|
|
||||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
|
||||||
Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'
|
|
||||||
Mime-Version: 1.0
|
|
||||||
Content-Type: text/plain;
|
|
||||||
charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
X-Sieve: CMU Sieve 2.2
|
|
||||||
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
|
|
||||||
13 Jun 2013 14:03:48 -0700 (PDT)
|
|
||||||
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
11
spec/fixtures/emails/encoded_display_name.eml
vendored
Normal file
11
spec/fixtures/emails/encoded_display_name.eml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Return-Path: <random.name@bar.ru>
|
||||||
|
From: =?UTF-8?B?0KHQu9GD0YfQsNC50L3QsNGP?= =?UTF-8?B?INCY0LzRjw==?= <random.name@bar.ru>
|
||||||
|
To: team@bar.com
|
||||||
|
Subject: I need help
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <29@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
Будьте здоровы!
|
10
spec/fixtures/emails/from_the_future.eml
vendored
Normal file
10
spec/fixtures/emails/from_the_future.eml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Wed, 01 Jan 3000 00:00:00 +0100
|
||||||
|
Message-ID: <4@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
Back to the future!
|
181
spec/fixtures/emails/gmail_web.eml
vendored
181
spec/fixtures/emails/gmail_web.eml
vendored
|
@ -1,181 +0,0 @@
|
||||||
Delivered-To: reply@discourse.org
|
|
||||||
Return-Path: <walter.white@googlemail.com>
|
|
||||||
MIME-Version: 1.0
|
|
||||||
In-Reply-To: <topic/22638/86406@meta.discourse.org>
|
|
||||||
References: <topic/22638@meta.discourse.org>
|
|
||||||
<topic/22638/86406@meta.discourse.org>
|
|
||||||
Date: Fri, 28 Nov 2014 12:36:49 -0800
|
|
||||||
Subject: Re: [Discourse Meta] [Lounge] Testing default email replies
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
To: Discourse Meta <reply@discourse.org>
|
|
||||||
Content-Type: multipart/alternative; boundary=001a11c2e04e6544f30508f138ba
|
|
||||||
|
|
||||||
--001a11c2e04e6544f30508f138ba
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
|
|
||||||
### This is a reply from standard GMail in Google Chrome.
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
Here's some **bold** text in Markdown.
|
|
||||||
|
|
||||||
Here's a link http://example.com
|
|
||||||
|
|
||||||
On Fri, Nov 28, 2014 at 12:35 PM, Arpit Jalan <info@discourse.org> wrote:
|
|
||||||
|
|
||||||
> techAPJ <https://meta.discourse.org/users/techapj>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> Test reply.
|
|
||||||
>
|
|
||||||
> First paragraph.
|
|
||||||
>
|
|
||||||
> Second paragraph.
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies codinghorror
|
|
||||||
> <https://meta.discourse.org/users/codinghorror>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> We're testing the latest GitHub email processing library which we are
|
|
||||||
> integrating now.
|
|
||||||
>
|
|
||||||
> https://github.com/github/email_reply_parser
|
|
||||||
>
|
|
||||||
> Go ahead and reply to this topic and I'll reply from various email clients
|
|
||||||
> for testing.
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <https://meta.discourse.org/my/preferences>.
|
|
||||||
>
|
|
||||||
|
|
||||||
--001a11c2e04e6544f30508f138ba
|
|
||||||
Content-Type: text/html; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
<div dir=3D"ltr"><div>### This is a reply from standard GMail in Google Chr=
|
|
||||||
ome.</div><div><br></div><div>The quick brown fox jumps over the lazy dog. =
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over=
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown=
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. =
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over=
|
|
||||||
the lazy dog.=C2=A0</div><div><br></div><div>Here's some **bold** text=
|
|
||||||
in Markdown.</div><div><br></div><div>Here's a link <a href=3D"http://=
|
|
||||||
example.com">http://example.com</a></div></div><div class=3D"gmail_extra"><=
|
|
||||||
br><div class=3D"gmail_quote">On Fri, Nov 28, 2014 at 12:35 PM, Arpit Jalan=
|
|
||||||
<span dir=3D"ltr"><<a href=3D"mailto:info@discourse.org" target=3D"_bla=
|
|
||||||
nk">info@discourse.org</a>></span> wrote:<br><blockquote class=3D"gmail_=
|
|
||||||
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
|
|
||||||
ex"><div>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px" cellspacing=3D"0" cellpadding=3D"0" bor=
|
|
||||||
der=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/techapj/45/3281.png" title=3D"techAPJ" style=3D"max-wi=
|
|
||||||
dth:100%" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/techapj" style=3D"text-=
|
|
||||||
decoration:none;font-weight:bold;color:#006699;font-size:13px;font-family:&=
|
|
||||||
#39;lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-d=
|
|
||||||
ecoration:none;font-weight:bold" target=3D"_blank">techAPJ</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">November 28</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0;border:0">Test reply.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">First paragraph.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">Second paragraph.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"https://meta.dis=
|
|
||||||
course.org/t/testing-default-email-replies/22638/3" style=3D"text-decoratio=
|
|
||||||
n:none;font-weight:bold;color:#006699;color:#666" target=3D"_blank">https:/=
|
|
||||||
/meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your bro=
|
|
||||||
wser.</p>
|
|
||||||
</div>
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-c=
|
|
||||||
olor:#ddd;min-height:1px;border:1px">
|
|
||||||
<h4>Previous Replies</h4>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px" cellspacing=3D"0" cellpadding=3D"0" b=
|
|
||||||
order=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/codinghorror/45/5297.png" title=3D"codinghorror" style=
|
|
||||||
=3D"max-width:100%" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/codinghorror" style=3D"=
|
|
||||||
text-decoration:none;font-weight:bold;color:#006699;font-size:13px;font-fam=
|
|
||||||
ily:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;t=
|
|
||||||
ext-decoration:none;font-weight:bold" target=3D"_blank">codinghorror</a><br=
|
|
||||||
>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">November 28</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0;border:0">We're testing the latest GitHub emai=
|
|
||||||
l processing library which we are integrating now.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0"><a href=3D"https://github.com/github/ema=
|
|
||||||
il_reply_parser" style=3D"text-decoration:none;font-weight:bold;color:#0066=
|
|
||||||
99" target=3D"_blank">https://github.com/github/email_reply_parser</a></p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">Go ahead and reply to this topic and I&#=
|
|
||||||
39;ll reply from various email clients for testing.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-col=
|
|
||||||
or:#ddd;min-height:1px;border:1px">
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"https://meta.discour=
|
|
||||||
se.org/t/testing-default-email-replies/22638/3" style=3D"text-decoration:no=
|
|
||||||
ne;font-weight:bold;color:#006699;color:#666" target=3D"_blank">https://met=
|
|
||||||
a.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser=
|
|
||||||
.</p>
|
|
||||||
</div>
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href=3D"https://meta.dis=
|
|
||||||
course.org/my/preferences" style=3D"text-decoration:none;font-weight:bold;c=
|
|
||||||
olor:#006699;color:#666" target=3D"_blank">user preferences</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</blockquote></div><br></div>
|
|
||||||
|
|
||||||
--001a11c2e04e6544f30508f138ba--
|
|
17
spec/fixtures/emails/hebrew.eml
vendored
17
spec/fixtures/emails/hebrew.eml
vendored
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org
|
|
||||||
Received: by 10.194.216.104 with SMTP id op8csp80593wjc;
|
|
||||||
Wed, 24 Jul 2013 07:59:14 -0700 (PDT)
|
|
||||||
Return-Path: <walter.white@googlemail.com>
|
|
||||||
References: <topic/5043@discourse.org> <51efeb9b36c34_66dc2dfce6811866@discourse.mail>
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail>
|
|
||||||
Mime-Version: 1.0 (1.0)
|
|
||||||
Date: Wed, 24 Jul 2013 15:59:10 +0100
|
|
||||||
Message-ID: <4597127794206131679@unknownmsgid>
|
|
||||||
Subject: Re: [Discourse] new reply to your post in 'Crystal Blue'
|
|
||||||
To: walter via Discourse <reply+cd480e301683c9902891f15968bf07a5@appmail.adventuretime.ooo>
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
16nXnNeV150=
|
|
10
spec/fixtures/emails/hebrew_reply.eml
vendored
Normal file
10
spec/fixtures/emails/hebrew_reply.eml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <16@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
16nXnNeV150hINee15Qg16nXnNeV157XmiDXlNeZ15XXnT8=
|
93
spec/fixtures/emails/html_only.eml
vendored
93
spec/fixtures/emails/html_only.eml
vendored
|
@ -1,93 +0,0 @@
|
||||||
|
|
||||||
Delivered-To: walter@breakingbad.com
|
|
||||||
Received: by 10.64.13.41 with SMTP id m9csp29769iec;
|
|
||||||
Thu, 20 Jun 2013 08:53:22 -0700 (PDT)
|
|
||||||
X-Received: by 10.252.23.9 with SMTP id p9mr4055675lag.4.1371743601980;
|
|
||||||
Thu, 20 Jun 2013 08:53:21 -0700 (PDT)
|
|
||||||
Received: from mail-la0-x229.google.com (mail-la0-x229.google.com [2a00:1450:4010:c03::229])
|
|
||||||
by mx.google.com with ESMTPS id u4si430203lae.48.2013.06.20.08.53.20
|
|
||||||
for <walter@breakingbad.com>
|
|
||||||
(version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
|
|
||||||
Thu, 20 Jun 2013 08:53:21 -0700 (PDT)
|
|
||||||
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
|
|
||||||
d=google.com; s=20120113;
|
|
||||||
h=x-forwarded-to:x-forwarded-for:delivered-to:x-return-path
|
|
||||||
:content-type:mime-version:content-transfer-encoding:x-mailer
|
|
||||||
:message-id:date:subject:from:in-reply-to:to:resent-date:resent-from
|
|
||||||
:resent-to:resent-subject:resent-message-id:resent-user-agent
|
|
||||||
:x-scanned-by:x-gm-message-state;
|
|
||||||
bh=9O67r74ofh9WkEaKTRB/frQ3MKOtQlbCac2mz0/MiyY=;
|
|
||||||
b=YVAo2/JDMP53RxDmqDEKNcEMtggtfaVyq2DoseZ6vBAfB7G6NtHC9ZEkRs4oGhk6LU
|
|
||||||
fnyAPe0wnz5d9WINoMAuuTRIhplLxzcqysduSnAJAQ2qqR7mFBnlj9wJeVEKltNwmUME
|
|
||||||
nPwxsf8go20VBzrZCtECPedcLi60wbl32NCXVn0qwt2LvKiy6ktSS5Xgb4zY8i4dfXAP
|
|
||||||
6Y5gu32boooWIb9DkH1TJkn3C0RrEugNlw/DUnXrnkFefgxWF3pt/zcoW/wYRyikOdx+
|
|
||||||
smBClgR9my6QmsS2KsQrMvWJZUva7fddTiZ6FC22e4hW+8Wha0RaZOZu5O7hjg6G4/1g
|
|
||||||
IEyg==
|
|
||||||
X-Received: by 10.112.55.9 with SMTP id n9mr5916187lbp.5.1371743600857;
|
|
||||||
Thu, 20 Jun 2013 08:53:20 -0700 (PDT)
|
|
||||||
X-Forwarded-To: walter@breakingbad.com
|
|
||||||
X-Forwarded-For: walter@breakingbad.com
|
|
||||||
Delivered-To: walter@breakingbad.com
|
|
||||||
Content-Type: text/html; charset="us-ascii"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
X-Mailer: BlackBerry Email (10.1.0.1720)
|
|
||||||
Message-ID: <20130619231548.6307981.74194.2379@breakingbad.com>
|
|
||||||
Date: Wed, 19 Jun 2013 19:15:48 -0400
|
|
||||||
Subject: Re: [Discourse Meta] [PM] re: Regarding your post in "Site
|
|
||||||
Customization not working"
|
|
||||||
From: aaron@breakingbad.com
|
|
||||||
In-Reply-To: <51c238655a394_5f4e3ce6690667bd@tiefighter2.mail>
|
|
||||||
To: reply+20c1b0a8bd1a63c0163cc7e7641ca06b@appmail.adventuretime.ooo
|
|
||||||
ReSent-Date: Thu, 20 Jun 2013 11:53:08 -0400 (EDT)
|
|
||||||
ReSent-From: Aaron <aaron@breakingbad.com>
|
|
||||||
ReSent-Subject: Re: [Discourse Meta] [PM] re: Regarding your post in "Site
|
|
||||||
Customization not working"
|
|
||||||
X-Gm-Message-State: ALoCoQl1BtN83rAX7At808XAPv1yCqUK3Du2IvK7eCyY3jsI77u4e5cak28307pYYHAo1JlO/Eu9
|
|
||||||
|
|
||||||
<html><head></head><body data-blackberry-caret-color=3D"#00a8df" style=3D"b=
|
|
||||||
ackground-color: rgb(255, 255, 255); line-height: initial;"><div id=3D"BB10=
|
|
||||||
_response_div" style=3D"width: 100%; font-size: initial; font-family: Calib=
|
|
||||||
ri, 'Slate Pro', sans-serif; color: rgb(31, 73, 125); text-align: initial; =
|
|
||||||
background-color: rgb(255, 255, 255);">The EC2 instance - I've seen that th=
|
|
||||||
ere tends to be odd and unrecommended settings on the Bitnami installs that=
|
|
||||||
I've checked out.</div> =
|
|
||||||
=
|
|
||||||
<div id=3D"response_div_spacer" style=3D"width: 100%; font-size: ini=
|
|
||||||
tial; font-family: Calibri, 'Slate Pro', sans-serif; color: rgb(31, 73, 125=
|
|
||||||
); text-align: initial; background-color: rgb(255, 255, 255);"><br style=3D=
|
|
||||||
"display:initial"></div> =
|
|
||||||
=
|
|
||||||
<div id=3D"_signaturePlaceholder" style=3D"font-size: initial; font-=
|
|
||||||
family: Calibri, 'Slate Pro', sans-serif; color: rgb(31, 73, 125); text-ali=
|
|
||||||
gn: initial; background-color: rgb(255, 255, 255);"></div> =
|
|
||||||
=
|
|
||||||
=
|
|
||||||
<table width=3D"100%" style=3D"background-color:white;bord=
|
|
||||||
er-spacing:0px;"> <tbody><tr><td id=3D"_persistentHeaderContainer" colspan=
|
|
||||||
=3D"2" style=3D"font-size: initial; text-align: initial; background-color: =
|
|
||||||
rgb(255, 255, 255);"> <div id=
|
|
||||||
=3D"_persistentHeader" style=3D"border-style: solid none none; border-top-c=
|
|
||||||
olor: rgb(181, 196, 223); border-top-width: 1pt; padding: 3pt 0in 0in; font=
|
|
||||||
-family: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-size: 10pt;"> <div><b>=
|
|
||||||
From: </b>Grizzly B via Discourse Meta</div><div><b>Sent: </b>Wednesday, J=
|
|
||||||
une 19, 2013 19:02</div><div><b>To: </b>aaron@breakingbad.com</div><div><b>=
|
|
||||||
Reply To: </b>Grizzly B via Discourse Meta</div><div><b>Subject: </b>[Disc=
|
|
||||||
ourse Meta] [PM] re: Regarding your post in "Site Customization<br> not wor=
|
|
||||||
king"</div></div></td></tr></tbody></table><div id=3D"_persistentHeaderEnd"=
|
|
||||||
style=3D"border-style: solid none none; border-top-color: rgb(186, 188, 20=
|
|
||||||
9); border-top-width: 1pt; font-size: initial; text-align: initial; backgro=
|
|
||||||
und-color: rgb(255, 255, 255);"></div><br><div id=3D"_originalContent" styl=
|
|
||||||
e=3D""><p>Grizzly B just sent you a private message</p>
|
|
||||||
|
|
||||||
<hr><p>Log in to our EC2 instance -or- log into a new DigitalOcean instanc=
|
|
||||||
e?</p>
|
|
||||||
|
|
||||||
<hr><p>Please visit this link to respond: <a href=3D"http://meta.discourse.=
|
|
||||||
org/t/regarding-your-post-in-site-customization-not-working/7641/5">http://=
|
|
||||||
meta.discourse.org/t/regarding-your-post-in-site-customization-not-working/=
|
|
||||||
7641/5</a></p>
|
|
||||||
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href=3D"http://meta.disc=
|
|
||||||
ourse.org/user_preferences">user preferences</a>.</p>
|
|
||||||
<br><!--end of _originalContent --></div></body></html>
|
|
205
spec/fixtures/emails/html_paragraphs.eml
vendored
205
spec/fixtures/emails/html_paragraphs.eml
vendored
|
@ -1,205 +0,0 @@
|
||||||
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Received: by 10.25.161.144 with HTTP; Tue, 7 Oct 2014 22:17:17 -0700 (PDT)
|
|
||||||
X-Originating-IP: [117.207.85.84]
|
|
||||||
In-Reply-To: <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail>
|
|
||||||
References: <topic/35@discourse.techapj.com>
|
|
||||||
<5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail>
|
|
||||||
Date: Wed, 8 Oct 2014 10:47:17 +0530
|
|
||||||
Delivered-To: arpit@techapj.com
|
|
||||||
Message-ID: <CAOJeqne=SJ_LwN4sb-0Y95ejc2OpreVhdmcPn0TnmwSvTCYzzQ@mail.gmail.com>
|
|
||||||
Subject: Re: [Discourse] [Meta] Welcome to techAPJ's Discourse!
|
|
||||||
From: Arpit Jalan <arpit@techapj.com>
|
|
||||||
To: Discourse <mail+e1c7f2a380e33840aeb654f075490bad@arpitjalan.com>
|
|
||||||
Content-Type: multipart/alternative; boundary=001a114119d8f4e46e0504e26d5b
|
|
||||||
|
|
||||||
--001a114119d8f4e46e0504e26d5b
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
Awesome!
|
|
||||||
|
|
||||||
Pleasure to have you here!
|
|
||||||
|
|
||||||
:boom:
|
|
||||||
|
|
||||||
On Wed, Oct 8, 2014 at 10:46 AM, ajalan <info@unconfigured.discourse.org>
|
|
||||||
wrote:
|
|
||||||
|
|
||||||
> ajalan
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoiVXgxTTZ3eHpuRWF2QXVoZGRJZVN5MWI0WnhrIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL3VzZXJzXFxcL2FqYWxhblwiLFwiaWRcIjpcIjgyNWI5MDYzZWNmMDRkMjk5OTE4Nzk1MmU=
|
|
||||||
5YjY2YjE3XCIsXCJ1cmxfaWRzXCI6W1wiNzA3MTNjNTg4MDI3YWQyM2RiM2QwOTVhOGQwYmY4ZT=
|
|
||||||
YyMzNjYThiMFwiXX0ifQ>
|
|
||||||
> October 8
|
|
||||||
>
|
|
||||||
> Nice to be here! Thanks! [image: smile]
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> http://discourse.techapj.com/t/welcome-to-techapjs-discourse/35/2
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoid1IyWnVqVGRPU2RwLUlFR0Q5QnI1a203eVNjIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL3RcXFwvd2VsY29tZS10by10ZWNoYXBqcy1kaXNjb3Vyc2VcXFwvMzVcXFwvMlwiLFwiaWR=
|
|
||||||
cIjpcIjgyNWI5MDYzZWNmMDRkMjk5OTE4Nzk1MmU5YjY2YjE3XCIsXCJ1cmxfaWRzXCI6W1wiY2=
|
|
||||||
RkYzFlZjc5OThhNzE1ODA4Yjg0MGFlNzVlZmNiYmYzYmViODk4Y1wiXX0ifQ>
|
|
||||||
> in your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies techAPJ
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoia2x3LUxac2RSX25uWEFYYWcwVDVha3pIY3RjIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL3VzZXJzXFxcL3RlY2hhcGpcIixcImlkXCI6XCI4MjViOTA2M2VjZjA0ZDI5OTkxODc5NTJ=
|
|
||||||
lOWI2NmIxN1wiLFwidXJsX2lkc1wiOltcIjk2ZjAyMzVhNmM2NzIyNmU1NjhhMzU1NDE1OTAxNz=
|
|
||||||
AyYTkxNjM1NzJcIl19In0>
|
|
||||||
> October 8
|
|
||||||
>
|
|
||||||
> Welcome to techAPJ's Discourse!
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> http://discourse.techapj.com/t/welcome-to-techapjs-discourse/35/2
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoid1IyWnVqVGRPU2RwLUlFR0Q5QnI1a203eVNjIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL3RcXFwvd2VsY29tZS10by10ZWNoYXBqcy1kaXNjb3Vyc2VcXFwvMzVcXFwvMlwiLFwiaWR=
|
|
||||||
cIjpcIjgyNWI5MDYzZWNmMDRkMjk5OTE4Nzk1MmU5YjY2YjE3XCIsXCJ1cmxfaWRzXCI6W1wiY2=
|
|
||||||
RkYzFlZjc5OThhNzE1ODA4Yjg0MGFlNzVlZmNiYmYzYmViODk4Y1wiXX0ifQ>
|
|
||||||
> in your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoiVTNudkpobl9lUUl0cmdsVVRrcm5iaHpyN0JZIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL215XFxcL3ByZWZlcmVuY2VzXCIsXCJpZFwiOlwiODI1YjkwNjNlY2YwNGQyOTk5MTg3OTU=
|
|
||||||
yZTliNjZiMTdcIixcInVybF9pZHNcIjpbXCI0OTIyMmMyZDgyNzUwMmQyMGZjYzU4MTZkNjhmYT=
|
|
||||||
k3NzFkY2YzZDllXCJdfSJ9>
|
|
||||||
> .
|
|
||||||
>
|
|
||||||
|
|
||||||
--001a114119d8f4e46e0504e26d5b
|
|
||||||
Content-Type: text/html; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
<div dir=3D"ltr">Awesome!<div><br></div><div>Pleasure to have you here!</di=
|
|
||||||
v><div><br></div><div>:boom:</div></div><div class=3D"gmail_extra"><br><div=
|
|
||||||
class=3D"gmail_quote">On Wed, Oct 8, 2014 at 10:46 AM, ajalan <span dir=3D=
|
|
||||||
"ltr"><<a href=3D"mailto:info@unconfigured.discourse.org" target=3D"_bla=
|
|
||||||
nk">info@unconfigured.discourse.org</a>></span> wrote:<br><blockquote cl=
|
|
||||||
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
|
|
||||||
adding-left:1ex"><div>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cellp=
|
|
||||||
adding=3D"0" border=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"http://discourse.techapj.com/user_avatar/discourse.tech=
|
|
||||||
apj.com/ajalan/45/35.png" title=3D"ajalan" style=3D"max-width:694px" width=
|
|
||||||
=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"http://mandrillapp.com/track/click/30081177/discourse.te=
|
|
||||||
chapj.com?p=3DeyJzIjoiVXgxTTZ3eHpuRWF2QXVoZGRJZVN5MWI0WnhrIiwidiI6MSwicCI6I=
|
|
||||||
ntcInVcIjozMDA4MTE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNl=
|
|
||||||
LnRlY2hhcGouY29tXFxcL3VzZXJzXFxcL2FqYWxhblwiLFwiaWRcIjpcIjgyNWI5MDYzZWNmMDR=
|
|
||||||
kMjk5OTE4Nzk1MmU5YjY2YjE3XCIsXCJ1cmxfaWRzXCI6W1wiNzA3MTNjNTg4MDI3YWQyM2RiM2=
|
|
||||||
QwOTVhOGQwYmY4ZTYyMzNjYThiMFwiXX0ifQ" style=3D"font-size:13px;font-family:&=
|
|
||||||
#39;lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-d=
|
|
||||||
ecoration:none;font-weight:bold;text-decoration:none;font-weight:bold;color=
|
|
||||||
:#006699" target=3D"_blank">ajalan</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">October 8</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2"><p style=3D"margin-top:0;=
|
|
||||||
border:0">Nice to be here! Thanks! <img src=3D"http://discourse.techapj.com=
|
|
||||||
/plugins/emoji/images/smile.png" title=3D":smile:" alt=3D"smile" width=3D"2=
|
|
||||||
0" height=3D"20"></p></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"http://mandrilla=
|
|
||||||
pp.com/track/click/30081177/discourse.techapj.com?p=3DeyJzIjoid1IyWnVqVGRPU=
|
|
||||||
2RwLUlFR0Q5QnI1a203eVNjIiwidiI6MSwicCI6IntcInVcIjozMDA4MTE3NyxcInZcIjoxLFwi=
|
|
||||||
dXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29tXFxcL3RcXFwvd2VsY29=
|
|
||||||
tZS10by10ZWNoYXBqcy1kaXNjb3Vyc2VcXFwvMzVcXFwvMlwiLFwiaWRcIjpcIjgyNWI5MDYzZW=
|
|
||||||
NmMDRkMjk5OTE4Nzk1MmU5YjY2YjE3XCIsXCJ1cmxfaWRzXCI6W1wiY2RkYzFlZjc5OThhNzE1O=
|
|
||||||
DA4Yjg0MGFlNzVlZmNiYmYzYmViODk4Y1wiXX0ifQ" style=3D"color:#666;text-decorat=
|
|
||||||
ion:none;font-weight:bold;color:#006699" target=3D"_blank">http://discourse=
|
|
||||||
.techapj.com/t/welcome-to-techapjs-discourse/35/2</a> in your browser.</p>
|
|
||||||
</div>
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-c=
|
|
||||||
olor:#ddd;min-height:1px;border:1px">
|
|
||||||
<h4>Previous Replies</h4>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cel=
|
|
||||||
lpadding=3D"0" border=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"http://discourse.techapj.com/user_avatar/discourse.tech=
|
|
||||||
apj.com/techapj/45/34.png" title=3D"techAPJ" style=3D"max-width:694px" widt=
|
|
||||||
h=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"http://mandrillapp.com/track/click/30081177/discourse.te=
|
|
||||||
chapj.com?p=3DeyJzIjoia2x3LUxac2RSX25uWEFYYWcwVDVha3pIY3RjIiwidiI6MSwicCI6I=
|
|
||||||
ntcInVcIjozMDA4MTE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNl=
|
|
||||||
LnRlY2hhcGouY29tXFxcL3VzZXJzXFxcL3RlY2hhcGpcIixcImlkXCI6XCI4MjViOTA2M2VjZjA=
|
|
||||||
0ZDI5OTkxODc5NTJlOWI2NmIxN1wiLFwidXJsX2lkc1wiOltcIjk2ZjAyMzVhNmM2NzIyNmU1Nj=
|
|
||||||
hhMzU1NDE1OTAxNzAyYTkxNjM1NzJcIl19In0" style=3D"font-size:13px;font-family:=
|
|
||||||
'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-=
|
|
||||||
decoration:none;font-weight:bold;text-decoration:none;font-weight:bold;colo=
|
|
||||||
r:#006699" target=3D"_blank">techAPJ</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">October 8</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2"><p style=3D"margin-top:0;=
|
|
||||||
border:0">Welcome to techAPJ's Discourse!</p></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-col=
|
|
||||||
or:#ddd;min-height:1px;border:1px">
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"http://mandrillapp.c=
|
|
||||||
om/track/click/30081177/discourse.techapj.com?p=3DeyJzIjoid1IyWnVqVGRPU2RwL=
|
|
||||||
UlFR0Q5QnI1a203eVNjIiwidiI6MSwicCI6IntcInVcIjozMDA4MTE3NyxcInZcIjoxLFwidXJs=
|
|
||||||
XCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29tXFxcL3RcXFwvd2VsY29tZS1=
|
|
||||||
0by10ZWNoYXBqcy1kaXNjb3Vyc2VcXFwvMzVcXFwvMlwiLFwiaWRcIjpcIjgyNWI5MDYzZWNmMD=
|
|
||||||
RkMjk5OTE4Nzk1MmU5YjY2YjE3XCIsXCJ1cmxfaWRzXCI6W1wiY2RkYzFlZjc5OThhNzE1ODA4Y=
|
|
||||||
jg0MGFlNzVlZmNiYmYzYmViODk4Y1wiXX0ifQ" style=3D"color:#666;text-decoration:=
|
|
||||||
none;font-weight:bold;color:#006699" target=3D"_blank">http://discourse.tec=
|
|
||||||
hapj.com/t/welcome-to-techapjs-discourse/35/2</a> in your browser.</p>
|
|
||||||
</div><span class=3D"">
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href=3D"http://mandrilla=
|
|
||||||
pp.com/track/click/30081177/discourse.techapj.com?p=3DeyJzIjoiVTNudkpobl9lU=
|
|
||||||
Ul0cmdsVVRrcm5iaHpyN0JZIiwidiI6MSwicCI6IntcInVcIjozMDA4MTE3NyxcInZcIjoxLFwi=
|
|
||||||
dXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29tXFxcL215XFxcL3ByZWZ=
|
|
||||||
lcmVuY2VzXCIsXCJpZFwiOlwiODI1YjkwNjNlY2YwNGQyOTk5MTg3OTUyZTliNjZiMTdcIixcIn=
|
|
||||||
VybF9pZHNcIjpbXCI0OTIyMmMyZDgyNzUwMmQyMGZjYzU4MTZkNjhmYTk3NzFkY2YzZDllXCJdf=
|
|
||||||
SJ9" style=3D"color:#666;text-decoration:none;font-weight:bold;color:#00669=
|
|
||||||
9" target=3D"_blank">user preferences</a>.</p>
|
|
||||||
</div>
|
|
||||||
</span></div>
|
|
||||||
|
|
||||||
<img src=3D"http://mandrillapp.com/track/open.php?u=3D30081177&id=3D825=
|
|
||||||
b9063ecf04d2999187952e9b66b17" height=3D"1" width=3D"1"></blockquote></div>=
|
|
||||||
<br></div>
|
|
||||||
|
|
||||||
--001a114119d8f4e46e0504e26d5b--
|
|
10
spec/fixtures/emails/html_reply.eml
vendored
Normal file
10
spec/fixtures/emails/html_reply.eml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <18@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/html; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
<div dir="ltr">This is a <b>HTML</b> reply ;)</div>
|
9
spec/fixtures/emails/inactive_sender.eml
vendored
Normal file
9
spec/fixtures/emails/inactive_sender.eml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Return-Path: <inactive@bar.com>
|
||||||
|
From: Foo Bar <inactive@bar.com>
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <8@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
76
spec/fixtures/emails/inline_attachment.eml
vendored
Normal file
76
spec/fixtures/emails/inline_attachment.eml
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <28@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: multipart/related; boundary=001a114b2eccff183a052998ec68
|
||||||
|
|
||||||
|
--001a114b2eccff183a052998ec68
|
||||||
|
Content-Type: multipart/alternative; boundary=001a114b2eccff1836052998ec67
|
||||||
|
|
||||||
|
--001a114b2eccff1836052998ec67
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
Before
|
||||||
|
|
||||||
|
[image: 内嵌图片 1]
|
||||||
|
|
||||||
|
After
|
||||||
|
|
||||||
|
--001a114b2eccff1836052998ec67
|
||||||
|
Content-Type: text/html; charset=UTF-8
|
||||||
|
|
||||||
|
<div dir="ltr">Before<div><br></div><div><img src="cid:ii_1525434659ddb4cb" alt="内嵌图片 1" style="margin-right: 0px;"><br>
|
||||||
|
<div><br></div><div>After</div></div></div>
|
||||||
|
|
||||||
|
--001a114b2eccff1836052998ec67--
|
||||||
|
--001a114b2eccff183a052998ec68
|
||||||
|
Content-Type: image/png; name="logo.png"
|
||||||
|
Content-Disposition: inline; filename="logo.png"
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
Content-ID: <ii_1525434659ddb4cb>
|
||||||
|
X-Attachment-Id: ii_1525434659ddb4cb
|
||||||
|
|
||||||
|
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
|
||||||
|
uIDrr6oAAAAASUVORK5CYII=
|
||||||
|
--001a114b2eccff183a052998ec68--
|
37
spec/fixtures/emails/inline_mixed.eml
vendored
37
spec/fixtures/emails/inline_mixed.eml
vendored
|
@ -1,37 +0,0 @@
|
||||||
In-Reply-To: <reply@discourse-app.mail>
|
|
||||||
References: <topic/36@discourse.techapj.com>
|
|
||||||
<5434ced4ee0f9_663fb0b5f76070593b@discourse-app.mail>
|
|
||||||
Date: Mon, 1 Dec 2014 20:48:40 +0530
|
|
||||||
Delivered-To: someone@googlemail.com
|
|
||||||
Subject: Re: [Discourse] [Meta] Testing reply via email
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
To: Discourse <reply@mail.com>
|
|
||||||
Content-Type: multipart/alternative; boundary=20cf30363f8522466905092920a6
|
|
||||||
|
|
||||||
--20cf30363f8522466905092920a6
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
On Wed, Oct 8, 2014 at 11:12 AM, techAPJ <info@unconfigured> wrote:
|
|
||||||
|
|
||||||
> techAPJ <https://meta.discourse.org/users/techapj>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> Test reply.
|
|
||||||
>
|
|
||||||
> First paragraph.
|
|
||||||
>
|
|
||||||
> Second paragraph.
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
> First paragraph.
|
|
||||||
>
|
|
||||||
> Second paragraph.
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
|
19
spec/fixtures/emails/inline_mixed_replies.eml
vendored
Normal file
19
spec/fixtures/emails/inline_mixed_replies.eml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <24@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
On Tue, Jan 15, 2016 at 11:12 AM, Bar Foo <info@unconfigured.discourse.org> wrote:
|
||||||
|
|
||||||
|
> WAT <https://bar.com/users/wat> November 28
|
||||||
|
>
|
||||||
|
> This is the previous post.
|
||||||
|
|
||||||
|
And this is *my* reply :+1:
|
||||||
|
|
||||||
|
> This is another post.
|
||||||
|
|
||||||
|
And this is **another** reply.
|
65
spec/fixtures/emails/inline_reply.eml
vendored
65
spec/fixtures/emails/inline_reply.eml
vendored
|
@ -1,60 +1,15 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
MIME-Version: 1.0
|
From: Foo Bar <discourse@bar.com>
|
||||||
In-Reply-To: <reply@discourse-app.mail>
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
References: <topic/36@discourse.techapj.com>
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
<5434ced4ee0f9_663fb0b5f76070593b@discourse-app.mail>
|
Message-ID: <23@foo.bar.mail>
|
||||||
Date: Mon, 1 Dec 2014 20:48:40 +0530
|
Mime-Version: 1.0
|
||||||
Delivered-To: someone@googlemail.com
|
|
||||||
Subject: Re: [Discourse] [Meta] Testing reply via email
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
To: Discourse <reply@mail.com>
|
|
||||||
Content-Type: multipart/alternative; boundary=20cf30363f8522466905092920a6
|
|
||||||
|
|
||||||
--20cf30363f8522466905092920a6
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
Content-Type: text/plain; charset=UTF-8
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
On Wed, Oct 8, 2014 at 11:12 AM, techAPJ <info@unconfigured.discourse.org>
|
On Tue, Jan 15, 2016 at 11:12 AM, Bar Foo <info@unconfigured.discourse.org> wrote:
|
||||||
wrote:
|
|
||||||
|
|
||||||
> techAPJ <https://meta.discourse.org/users/techapj>
|
> WAT <https://bar.com/users/wat> November 28
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> Test reply.
|
|
||||||
>
|
|
||||||
> First paragraph.
|
|
||||||
>
|
|
||||||
> Second paragraph.
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies codinghorror
|
|
||||||
> <https://meta.discourse.org/users/codinghorror>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> We're testing the latest GitHub email processing library which we are
|
|
||||||
> integrating now.
|
|
||||||
>
|
|
||||||
> https://github.com/github/email_reply_parser
|
|
||||||
>
|
|
||||||
> Go ahead and reply to this topic and I'll reply from various email clients
|
|
||||||
> for testing.
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <https://meta.discourse.org/my/preferences>.
|
|
||||||
>
|
>
|
||||||
|
> This is the previous post.
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
And this is *my* reply :+1:
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog.
|
|
||||||
|
|
||||||
--20cf30363f8522466905092920a6--
|
|
||||||
|
|
11
spec/fixtures/emails/insufficient_trust_level.eml
vendored
Normal file
11
spec/fixtures/emails/insufficient_trust_level.eml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Return-Path: <insufficient@bar.com>
|
||||||
|
From: Foo Bar <insufficient@bar.com>
|
||||||
|
To: category@bar.com
|
||||||
|
Subject: This is a topic from a complete stranger
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <32@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
Hey, this is a topic from a complete stranger ;)
|
136
spec/fixtures/emails/ios_default.eml
vendored
136
spec/fixtures/emails/ios_default.eml
vendored
|
@ -1,136 +0,0 @@
|
||||||
Delivered-To: reply@discourse.org
|
|
||||||
Return-Path: <walter.white@googlemail.com>
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
Content-Type: multipart/alternative;
|
|
||||||
boundary=Apple-Mail-B41C7F8E-3639-49B0-A5D5-440E125A7105
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
Mime-Version: 1.0 (1.0)
|
|
||||||
Subject: Re: [Discourse Meta] [Lounge] Testing default email replies
|
|
||||||
Date: Fri, 28 Nov 2014 12:41:41 -0800
|
|
||||||
References: <topic/22638@meta.discourse.org> <topic/22638/86406@meta.discourse.org>
|
|
||||||
In-Reply-To: <topic/22638/86406@meta.discourse.org>
|
|
||||||
To: Discourse Meta <reply@discourse.org>
|
|
||||||
X-Mailer: iPhone Mail (12B436)
|
|
||||||
|
|
||||||
|
|
||||||
--Apple-Mail-B41C7F8E-3639-49B0-A5D5-440E125A7105
|
|
||||||
Content-Type: text/plain;
|
|
||||||
charset=us-ascii
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
### this is a reply from iOS default mail
|
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over t=
|
|
||||||
he lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fo=
|
|
||||||
x jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The q=
|
|
||||||
uick brown fox jumps over the lazy dog. The quick brown fox jumps over the l=
|
|
||||||
azy dog.=20
|
|
||||||
|
|
||||||
Here's some **bold** markdown text.
|
|
||||||
|
|
||||||
Here's a link http://example.com
|
|
||||||
|
|
||||||
|
|
||||||
> On Nov 28, 2014, at 12:35 PM, Arpit Jalan <info@discourse.org> wrote:
|
|
||||||
>=20
|
|
||||||
>=20
|
|
||||||
> techAPJ
|
|
||||||
> November 28
|
|
||||||
> Test reply.
|
|
||||||
>=20
|
|
||||||
> First paragraph.
|
|
||||||
>=20
|
|
||||||
> Second paragraph.
|
|
||||||
>=20
|
|
||||||
> To respond, reply to this email or visit https://meta.discourse.org/t/test=
|
|
||||||
ing-default-email-replies/22638/3 in your browser.
|
|
||||||
>=20
|
|
||||||
> Previous Replies
|
|
||||||
>=20
|
|
||||||
> codinghorror
|
|
||||||
> November 28
|
|
||||||
> We're testing the latest GitHub email processing library which we are inte=
|
|
||||||
grating now.
|
|
||||||
>=20
|
|
||||||
> https://github.com/github/email_reply_parser
|
|
||||||
>=20
|
|
||||||
> Go ahead and reply to this topic and I'll reply from various email clients=
|
|
||||||
for testing.
|
|
||||||
>=20
|
|
||||||
> To respond, reply to this email or visit https://meta.discourse.org/t/test=
|
|
||||||
ing-default-email-replies/22638/3 in your browser.
|
|
||||||
>=20
|
|
||||||
> To unsubscribe from these emails, visit your user preferences.
|
|
||||||
|
|
||||||
--Apple-Mail-B41C7F8E-3639-49B0-A5D5-440E125A7105
|
|
||||||
Content-Type: text/html;
|
|
||||||
charset=utf-8
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
|
|
||||||
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>### this is a reply from iOS default mail</div><div><br></div><div>The quick brown fox jumps over the lazy dog. <span style="background-color: rgba(255, 255, 255, 0);">The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. </span></div><div><br></div><div>Here's some **bold** markdown text.</div><div><br></div><div>Here's a link <a href="http://example.com">http://example.com</a><br><br></div><div><br>On Nov 28, 2014, at 12:35 PM, Arpit Jalan <<a href="mailto:info@discourse.org">info@discourse.org</a>> wrote:<br><br></div><blockquote type="cite"><div><div>
|
|
||||||
|
|
||||||
<table style="margin-bottom:25px;" cellspacing="0" cellpadding="0" border="0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align:top;width:55px;">
|
|
||||||
<img src="https://meta-discourse.global.ssl.fastly.net/user_avatar/meta.discourse.org/techapj/45/3281.png" title="techAPJ" style="max-width:100%;" width="45" height="45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://meta.discourse.org/users/techapj" target="_blank" style="text-decoration: none; font-weight: bold; color: #006699;; font-size:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-decoration:none;font-weight:bold">techAPJ</a><br>
|
|
||||||
<span style="text-align:right;color:#999999;padding-right:5px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">November 28</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="padding-top:5px;" colspan="2">
|
|
||||||
<p style="margin-top:0; border: 0;">Test reply.</p>
|
|
||||||
|
|
||||||
<p style="margin-top:0; border: 0;">First paragraph.</p>
|
|
||||||
|
|
||||||
<p style="margin-top:0; border: 0;">Second paragraph.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<div style="color:#666;">
|
|
||||||
<p>To respond, reply to this email or visit <a href="https://meta.discourse.org/t/testing-default-email-replies/22638/3" style="text-decoration: none; font-weight: bold; color: #006699;; color:#666;">https://meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser.</p>
|
|
||||||
</div>
|
|
||||||
<hr style="background-color: #ddd; height: 1px; border: 1px;; background-color: #ddd; height: 1px; border: 1px;">
|
|
||||||
<h4>Previous Replies</h4>
|
|
||||||
|
|
||||||
<table style="margin-bottom:25px;" cellspacing="0" cellpadding="0" border="0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align:top;width:55px;">
|
|
||||||
<img src="https://meta-discourse.global.ssl.fastly.net/user_avatar/meta.discourse.org/codinghorror/45/5297.png" title="codinghorror" style="max-width:100%;" width="45" height="45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://meta.discourse.org/users/codinghorror" target="_blank" style="text-decoration: none; font-weight: bold; color: #006699;; font-size:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-decoration:none;font-weight:bold">codinghorror</a><br>
|
|
||||||
<span style="text-align:right;color:#999999;padding-right:5px;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px">November 28</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="padding-top:5px;" colspan="2">
|
|
||||||
<p style="margin-top:0; border: 0;">We're testing the latest GitHub email processing library which we are integrating now.</p>
|
|
||||||
|
|
||||||
<p style="margin-top:0; border: 0;"><a href="https://github.com/github/email_reply_parser" target="_blank" style="text-decoration: none; font-weight: bold; color: #006699;">https://github.com/github/email_reply_parser</a></p>
|
|
||||||
|
|
||||||
<p style="margin-top:0; border: 0;">Go ahead and reply to this topic and I'll reply from various email clients for testing.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<hr style="background-color: #ddd; height: 1px; border: 1px;; background-color: #ddd; height: 1px; border: 1px;">
|
|
||||||
|
|
||||||
<div style="color:#666;">
|
|
||||||
<p>To respond, reply to this email or visit <a href="https://meta.discourse.org/t/testing-default-email-replies/22638/3" style="text-decoration: none; font-weight: bold; color: #006699;; color:#666;">https://meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser.</p>
|
|
||||||
</div>
|
|
||||||
<div style="color:#666;">
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href="https://meta.discourse.org/my/preferences" style="text-decoration: none; font-weight: bold; color: #006699;; color:#666;">user preferences</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div></blockquote></body></html>
|
|
||||||
--Apple-Mail-B41C7F8E-3639-49B0-A5D5-440E125A7105--
|
|
36
spec/fixtures/emails/iphone_signature.eml
vendored
36
spec/fixtures/emails/iphone_signature.eml
vendored
|
@ -1,29 +1,11 @@
|
||||||
Delivered-To: test@mail.com
|
Return-Path: <discourse@bar.com>
|
||||||
Return-Path: <walter.white@googlemail.com>
|
From: Foo Bar <discourse@bar.com>
|
||||||
From: Walter White <walter.white@googlemail.com>
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
Content-Type: multipart/alternative;
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
boundary=Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975
|
Message-ID: <25@foo.bar.mail>
|
||||||
Content-Transfer-Encoding: 7bit
|
Mime-Version: 1.0
|
||||||
Mime-Version: 1.0 (1.0)
|
Content-Type: text/plain; charset=UTF-8
|
||||||
Subject: Re: Signature in email replies!
|
|
||||||
Date: Thu, 23 Oct 2014 14:43:49 +0530
|
|
||||||
References: <1234@mail.gmail.com>
|
|
||||||
In-Reply-To: <1234@mail.gmail.com>
|
|
||||||
To: Arpit Jalan <test@mail.com>
|
|
||||||
X-Mailer: iPhone Mail (12A405)
|
|
||||||
|
|
||||||
|
This is not the signature you're looking for.
|
||||||
|
|
||||||
--Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975
|
Sent from my iMachine
|
||||||
Content-Type: text/plain;
|
|
||||||
charset=us-ascii
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
|
|
||||||
This post should not include signature.
|
|
||||||
|
|
||||||
Sent from my iPhone
|
|
||||||
|
|
||||||
> On 23-Oct-2014, at 9:45 am, Arpit Jalan <test@mail.com> wrote:
|
|
||||||
>
|
|
||||||
> Signature in email replies!
|
|
||||||
|
|
||||||
--Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975
|
|
||||||
|
|
41
spec/fixtures/emails/like.eml
vendored
41
spec/fixtures/emails/like.eml
vendored
|
@ -1,37 +1,10 @@
|
||||||
Return-Path: <FROM>
|
Return-Path: <discourse@bar.com>
|
||||||
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
|
From: Foo Bar <discourse@bar.com>
|
||||||
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
|
Message-ID: <13@foo.bar.mail>
|
||||||
Date: Thu, 13 Jun 2013 17:03:48 -0400
|
|
||||||
From: FROM
|
|
||||||
To: TO
|
|
||||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
|
||||||
Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'
|
|
||||||
Mime-Version: 1.0
|
Mime-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain
|
||||||
charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
X-Sieve: CMU Sieve 2.2
|
|
||||||
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
|
|
||||||
13 Jun 2013 14:03:48 -0700 (PDT)
|
|
||||||
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
|
|
||||||
|
|
||||||
LIKE
|
+1
|
||||||
|
|
||||||
|
|
||||||
On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta
|
|
||||||
<reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo> wrote:
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> eviltrout posted in 'Adventure Time Sux' on Discourse Meta:
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> hey guys everyone knows adventure time sucks!
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences).
|
|
||||||
>
|
|
||||||
|
|
5
spec/fixtures/emails/missing_message_id.eml
vendored
Normal file
5
spec/fixtures/emails/missing_message_id.eml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
From: Foo Bar <foo@bar.com>
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
40
spec/fixtures/emails/multiple_destinations.eml
vendored
40
spec/fixtures/emails/multiple_destinations.eml
vendored
|
@ -1,40 +0,0 @@
|
||||||
Return-Path: <jake@adventuretime.ooo>
|
|
||||||
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Date: Thu, 13 Jun 2013 17:03:48 -0400
|
|
||||||
From: Jake the Dog <jake@adventuretime.ooo>
|
|
||||||
To: finn@adventuretime.ooo, reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo
|
|
||||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
|
||||||
Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'
|
|
||||||
Mime-Version: 1.0
|
|
||||||
Content-Type: text/plain;
|
|
||||||
charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
X-Sieve: CMU Sieve 2.2
|
|
||||||
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
|
|
||||||
13 Jun 2013 14:03:48 -0700 (PDT)
|
|
||||||
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
|
|
||||||
|
|
||||||
I could not disagree more. I am obviously biased but adventure time is the
|
|
||||||
greatest show ever created. Everyone should watch it.
|
|
||||||
|
|
||||||
- Jake out
|
|
||||||
|
|
||||||
|
|
||||||
On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta
|
|
||||||
<reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo> wrote:
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> eviltrout posted in 'Adventure Time Sux' on Discourse Meta:
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> hey guys everyone knows adventure time sucks!
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences).
|
|
||||||
>
|
|
84
spec/fixtures/emails/newlines.eml
vendored
84
spec/fixtures/emails/newlines.eml
vendored
|
@ -1,84 +0,0 @@
|
||||||
In-Reply-To: <test@discourse-app.mail>
|
|
||||||
Date: Wed, 8 Oct 2014 10:36:19 +0530
|
|
||||||
Delivered-To: walter.white@googlemail.com
|
|
||||||
Subject: Re: [Discourse] Welcome to Discourse
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
To: Discourse <mail@arpitjalan.com>
|
|
||||||
Content-Type: multipart/alternative; boundary=bcaec554078cc3d0c10504e24661
|
|
||||||
|
|
||||||
--bcaec554078cc3d0c10504e24661
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
This is my reply.
|
|
||||||
It is my best reply.
|
|
||||||
It will also be my *only* reply.
|
|
||||||
|
|
||||||
On Wed, Oct 8, 2014 at 10:33 AM, ajalan <info@unconfigured.discourse.org>
|
|
||||||
wrote:
|
|
||||||
|
|
||||||
> ajalan
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoiMGM3a1pGT250VG5sb242RVNTdFdjS1FUSHdzIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL3VzZXJzXFxcL2FqYWxhblwiLFwiaWRcIjpcImQxOWYxYjQ5NTdkODRkMGNhZWY1NDEzZGN=
|
|
||||||
hODA4YTRhXCIsXCJ1cmxfaWRzXCI6W1wiNzA3MTNjNTg4MDI3YWQyM2RiM2QwOTVhOGQwYmY4ZT=
|
|
||||||
YyMzNjYThiMFwiXX0ifQ>
|
|
||||||
> October 8
|
|
||||||
>
|
|
||||||
> Awesome! Thank You! [image: +1]
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> http://discourse.techapj.com/t/welcome-to-discourse/8/2
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoibzNWaXFDRDdxSFNCbVRkUmdONlRJVW1ENU8wIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL3RcXFwvd2VsY29tZS10by1kaXNjb3Vyc2VcXFwvOFxcXC8yXCIsXCJpZFwiOlwiZDE5ZjF=
|
|
||||||
iNDk1N2Q4NGQwY2FlZjU0MTNkY2E4MDhhNGFcIixcInVybF9pZHNcIjpbXCIwYmFkNjE2NDJkNm=
|
|
||||||
M2NzJhNGU0ZjYzMGU2ZDA5M2I3MzU3NzQ4MzYxXCJdfSJ9>
|
|
||||||
> in your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies system
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoicjFZQm8ySTJjUEtNclpvekZ5ZmFqYmdpTVFNIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL3VzZXJzXFxcL3N5c3RlbVwiLFwiaWRcIjpcImQxOWYxYjQ5NTdkODRkMGNhZWY1NDEzZGN=
|
|
||||||
hODA4YTRhXCIsXCJ1cmxfaWRzXCI6W1wiMTcxNWU2OTE1M2UzMjk4YmM2Y2NhMWEyM2E5N2ViMW=
|
|
||||||
U5N2IwMWYyNFwiXX0ifQ>
|
|
||||||
> October 8
|
|
||||||
>
|
|
||||||
> The first paragraph of this pinned topic will be visible as a welcome
|
|
||||||
> message to all new visitors on your homepage. It's important!
|
|
||||||
>
|
|
||||||
> *Edit this* into a brief description of your community:
|
|
||||||
>
|
|
||||||
> - Who is it for?
|
|
||||||
> - What can they find here?
|
|
||||||
> - Why should they come here?
|
|
||||||
> - Where can they read more (links, resources, etc)?
|
|
||||||
>
|
|
||||||
> You may want to close this topic via the wrench icon at the upper right,
|
|
||||||
> so that replies don't pile up on an announcement.
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> http://discourse.techapj.com/t/welcome-to-discourse/8/2
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoibzNWaXFDRDdxSFNCbVRkUmdONlRJVW1ENU8wIiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL3RcXFwvd2VsY29tZS10by1kaXNjb3Vyc2VcXFwvOFxcXC8yXCIsXCJpZFwiOlwiZDE5ZjF=
|
|
||||||
iNDk1N2Q4NGQwY2FlZjU0MTNkY2E4MDhhNGFcIixcInVybF9pZHNcIjpbXCIwYmFkNjE2NDJkNm=
|
|
||||||
M2NzJhNGU0ZjYzMGU2ZDA5M2I3MzU3NzQ4MzYxXCJdfSJ9>
|
|
||||||
> in your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <http://mandrillapp.com/track/click/30081177/discourse.techapj.com?p=3Dey=
|
|
||||||
JzIjoiaFdWSWtiRGIybjJOeWc0VHRrenAzbnhraU93IiwidiI6MSwicCI6IntcInVcIjozMDA4M=
|
|
||||||
TE3NyxcInZcIjoxLFwidXJsXCI6XCJodHRwOlxcXC9cXFwvZGlzY291cnNlLnRlY2hhcGouY29t=
|
|
||||||
XFxcL215XFxcL3ByZWZlcmVuY2VzXCIsXCJpZFwiOlwiZDE5ZjFiNDk1N2Q4NGQwY2FlZjU0MTN=
|
|
||||||
kY2E4MDhhNGFcIixcInVybF9pZHNcIjpbXCI0OTIyMmMyZDgyNzUwMmQyMGZjYzU4MTZkNjhmYT=
|
|
||||||
k3NzFkY2YzZDllXCJdfSJ9>
|
|
||||||
> .
|
|
||||||
>
|
|
||||||
|
|
||||||
--bcaec554078cc3d0c10504e24661
|
|
7
spec/fixtures/emails/no_body.eml
vendored
Normal file
7
spec/fixtures/emails/no_body.eml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Return-Path: <foo@bar.com>
|
||||||
|
From: Foo Bar <foo@bar.com>
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <5@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
75
spec/fixtures/emails/no_body_with_attachments.eml
vendored
Normal file
75
spec/fixtures/emails/no_body_with_attachments.eml
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <6@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: multipart/mixed;
|
||||||
|
boundary="--==_mimepart_56990c8d3f66c_7cb53ffbb98602004746e";
|
||||||
|
charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
|
||||||
|
----==_mimepart_56990c8d3f66c_7cb53ffbb98602004746e
|
||||||
|
Content-Type: image/png;
|
||||||
|
charset=UTF-8;
|
||||||
|
filename=logo.png
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
Content-Disposition: attachment;
|
||||||
|
filename=logo.png
|
||||||
|
Content-ID: <56990c92d6c64_7cb53ffbb986020047616@foo.bar.mail>
|
||||||
|
|
||||||
|
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
|
||||||
|
YII=
|
||||||
|
|
||||||
|
----==_mimepart_56990c8d3f66c_7cb53ffbb98602004746e--
|
34
spec/fixtures/emails/no_content_reply.eml
vendored
34
spec/fixtures/emails/no_content_reply.eml
vendored
|
@ -1,34 +0,0 @@
|
||||||
Return-Path: <jake@adventuretime.ooo>
|
|
||||||
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Date: Thu, 13 Jun 2013 17:03:48 -0400
|
|
||||||
From: Jake the Dog <jake@adventuretime.ooo>
|
|
||||||
To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo
|
|
||||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
|
||||||
Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'
|
|
||||||
Mime-Version: 1.0
|
|
||||||
Content-Type: text/plain;
|
|
||||||
charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
X-Sieve: CMU Sieve 2.2
|
|
||||||
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
|
|
||||||
13 Jun 2013 14:03:48 -0700 (PDT)
|
|
||||||
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
|
|
||||||
|
|
||||||
On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta
|
|
||||||
<reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo> wrote:
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> eviltrout posted in 'Adventure Time Sux' on Discourse Meta:
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> hey guys everyone knows adventure time sucks!
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences).
|
|
||||||
>
|
|
7
spec/fixtures/emails/no_return_path.eml
vendored
Normal file
7
spec/fixtures/emails/no_return_path.eml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
From: Foo Bar <foo@bar.com>
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <1@foo.bar.mail>
|
||||||
|
Precedence: list
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: 7bit
|
19
spec/fixtures/emails/on_date_contact_wrote.eml
vendored
Normal file
19
spec/fixtures/emails/on_date_contact_wrote.eml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <20@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
This is the actual reply.
|
||||||
|
|
||||||
|
On Tue, Jan 14, 2016 at 0:42 AM, Bar Foo <wat@discourse.org> wrote:
|
||||||
|
|
||||||
|
> This is the previous email.
|
||||||
|
> And it had
|
||||||
|
>
|
||||||
|
> a lot
|
||||||
|
>
|
||||||
|
>
|
||||||
|
> of lines ;)
|
277
spec/fixtures/emails/on_wrote.eml
vendored
277
spec/fixtures/emails/on_wrote.eml
vendored
|
@ -1,277 +0,0 @@
|
||||||
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Received: by 10.107.9.17 with HTTP; Tue, 9 Sep 2014 16:18:19 -0700 (PDT)
|
|
||||||
In-Reply-To: <540f16d4c08d9_4a3f9ff6d61890391c@tiefighter4-meta.mail>
|
|
||||||
References: <topic/18058@meta.discourse.org>
|
|
||||||
<540f16d4c08d9_4a3f9ff6d61890391c@tiefighter4-meta.mail>
|
|
||||||
Date: Tue, 9 Sep 2014 16:18:19 -0700
|
|
||||||
Delivered-To: kanepyork@gmail.com
|
|
||||||
Message-ID: <CABeNrKXxfb8YJUWxO5L_oPTGrFsiZfQOpWudk+44Mh=yuUEHNQ@mail.gmail.com>
|
|
||||||
Subject: Re: [Discourse Meta] Badge icons - where to find them?
|
|
||||||
From: Kane York <jake@adventuretime.ooo>
|
|
||||||
To: Discourse Meta <reply+8305e3604ae4d1485dc12b6af6a8446c@appmail.adventuretime.ooo>
|
|
||||||
Content-Type: multipart/alternative; boundary=001a11c34c389e728f0502aa26a0
|
|
||||||
|
|
||||||
--001a11c34c389e728f0502aa26a0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
Sure, all you need to do is frobnicate the foobar and you'll be all set!
|
|
||||||
|
|
||||||
On Tue, Sep 9, 2014 at 8:03 AM, gordon_ryan <info@discourse.org> wrote:
|
|
||||||
|
|
||||||
> gordon_ryan <https://meta.discourse.org/users/gordon_ryan>
|
|
||||||
> September 9
|
|
||||||
>
|
|
||||||
> @riking <https://meta.discourse.org/users/riking>- willing to step by
|
|
||||||
> step of the custom icon method for an admittedly ignorant admin? Seriousl=
|
|
||||||
y
|
|
||||||
> confused.
|
|
||||||
>
|
|
||||||
> Or anyone else who knows how to do this [image: smiley]
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/badge-icons-where-to-find-them/18058/9 in
|
|
||||||
> your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies riking <https://meta.discourse.org/users/riking>
|
|
||||||
> July 25
|
|
||||||
>
|
|
||||||
> Check out the "HTML Head" section in the "Content" tab of the admin panel=
|
|
||||||
.
|
|
||||||
> meglio <https://meta.discourse.org/users/meglio>
|
|
||||||
> July 25
|
|
||||||
>
|
|
||||||
> How will it load the related custom font?
|
|
||||||
> riking <https://meta.discourse.org/users/riking>
|
|
||||||
> July 25
|
|
||||||
>
|
|
||||||
> Here's an example of the styles that FA applies. I'll use <i class=3D"fa
|
|
||||||
> fa-heart"></i> as the example.
|
|
||||||
>
|
|
||||||
> .fa {
|
|
||||||
> display: inline-block;
|
|
||||||
> font-family: FontAwesome;
|
|
||||||
> font-style: normal;
|
|
||||||
> font-weight: normal;
|
|
||||||
> line-height: 1;
|
|
||||||
> -webkit-font-smoothing: antialiased;
|
|
||||||
> -moz-osx-font-smoothing: grayscale;
|
|
||||||
> }
|
|
||||||
> .fa-heart:before {
|
|
||||||
> content: "\f004";
|
|
||||||
> }
|
|
||||||
>
|
|
||||||
> So you could do this in your site stylesheet:
|
|
||||||
>
|
|
||||||
> .fa-custom-burger:before {
|
|
||||||
> content: "\01f354";
|
|
||||||
> font-family: inherit;
|
|
||||||
> }
|
|
||||||
>
|
|
||||||
> And get =F0=9F=8D=94 as your badge icon when you enter custom-burger.
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/badge-icons-where-to-find-them/18058/9 in
|
|
||||||
> your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <https://meta.discourse.org/my/preferences>.
|
|
||||||
>
|
|
||||||
|
|
||||||
--001a11c34c389e728f0502aa26a0
|
|
||||||
Content-Type: text/html; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
<div dir=3D"ltr"><span style=3D"font-family:arial,sans-serif;font-size:13px=
|
|
||||||
">Sure, all you need to do is frobnicate the foobar and you'll be all s=
|
|
||||||
et!</span><br><div class=3D"gmail_extra"><br clear=3D"all"><div><br>=
|
|
||||||
<br><div class=3D"gmail_quote">On Tue, Sep 9, 2014 at 8:03 AM, gordon_ryan =
|
|
||||||
<span dir=3D"ltr"><<a href=3D"mailto:info@discourse.org" target=3D"_blan=
|
|
||||||
k">info@discourse.org</a>></span> wrote:<br><blockquote class=3D"gmail_q=
|
|
||||||
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
|
|
||||||
x"><div>
|
|
||||||
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cellp=
|
|
||||||
adding=3D"0" border=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/gordon_ryan/45/34017.png" title=3D"gordon_ryan" style=
|
|
||||||
=3D"max-width:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/gordon_ryan" style=3D"f=
|
|
||||||
ont-size:13px;font-family:'lucida grande',tahoma,verdana,arial,sans=
|
|
||||||
-serif;color:#3b5998;text-decoration:none;font-weight:bold;text-decoration:=
|
|
||||||
none;font-weight:bold;color:#006699" target=3D"_blank">gordon_ryan</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">September 9</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0;border:0"><a href=3D"https://meta.discourse.org/us=
|
|
||||||
ers/riking" style=3D"text-decoration:none;font-weight:bold;color:#006699" t=
|
|
||||||
arget=3D"_blank">@riking</a>- willing to step by step of the custom icon me=
|
|
||||||
thod for an admittedly ignorant admin? Seriously confused.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">Or anyone else who knows how to do this =
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/plugins/emoji/imag=
|
|
||||||
es/smiley.png" title=3D":smiley:" alt=3D"smiley" width=3D"20" height=3D"20"=
|
|
||||||
></p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"https://meta.dis=
|
|
||||||
course.org/t/badge-icons-where-to-find-them/18058/9" style=3D"color:#666;te=
|
|
||||||
xt-decoration:none;font-weight:bold;color:#006699" target=3D"_blank">https:=
|
|
||||||
//meta.discourse.org/t/badge-icons-where-to-find-them/18058/9</a> in your b=
|
|
||||||
rowser.</p>
|
|
||||||
</div>
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-c=
|
|
||||||
olor:#ddd;min-height:1px;border:1px">
|
|
||||||
<h4>Previous Replies</h4>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cel=
|
|
||||||
lpadding=3D"0" border=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/riking/45/9779.png" title=3D"riking" style=3D"max-widt=
|
|
||||||
h:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/riking" style=3D"font-s=
|
|
||||||
ize:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-seri=
|
|
||||||
f;color:#3b5998;text-decoration:none;font-weight:bold;text-decoration:none;=
|
|
||||||
font-weight:bold;color:#006699" target=3D"_blank">riking</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">July 25</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2"><p style=3D"margin-top:0;=
|
|
||||||
border:0">Check out the "HTML Head" section in the "Content&=
|
|
||||||
quot; tab of the admin panel.</p></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cel=
|
|
||||||
lpadding=3D"0" border=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/meglio/45/33480.png" title=3D"meglio" style=3D"max-wid=
|
|
||||||
th:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/meglio" style=3D"font-s=
|
|
||||||
ize:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-seri=
|
|
||||||
f;color:#3b5998;text-decoration:none;font-weight:bold;text-decoration:none;=
|
|
||||||
font-weight:bold;color:#006699" target=3D"_blank">meglio</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">July 25</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2"><p style=3D"margin-top:0;=
|
|
||||||
border:0">How will it load the related custom font?</p></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px;max-width:761px" cellspacing=3D"0" cel=
|
|
||||||
lpadding=3D"0" border=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/riking/45/9779.png" title=3D"riking" style=3D"max-widt=
|
|
||||||
h:694px" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/riking" style=3D"font-s=
|
|
||||||
ize:13px;font-family:'lucida grande',tahoma,verdana,arial,sans-seri=
|
|
||||||
f;color:#3b5998;text-decoration:none;font-weight:bold;text-decoration:none;=
|
|
||||||
font-weight:bold;color:#006699" target=3D"_blank">riking</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">July 25</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0;border:0">Here's an example of the styles that=
|
|
||||||
FA applies. I'll use <code style=3D"background-color:#f1f1ff;padding:2=
|
|
||||||
px 5px"><i class=3D"fa fa-heart"></i></code> as the e=
|
|
||||||
xample.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0"></p>
|
|
||||||
<pre style=3D"word-wrap:break-word;max-width:694px"><code style=3D"backgrou=
|
|
||||||
nd-color:#f1f1ff;padding:2px 5px;display:block;background-color:#f1f1ff;pad=
|
|
||||||
ding:5px">.fa {
|
|
||||||
display: inline-block;
|
|
||||||
font-family: FontAwesome;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
line-height: 1;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
.fa-heart:before {
|
|
||||||
content: "\f004";
|
|
||||||
}</code></pre>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">So you could do this in your site styles=
|
|
||||||
heet:</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0"></p>
|
|
||||||
<pre style=3D"word-wrap:break-word;max-width:694px"><code style=3D"backgrou=
|
|
||||||
nd-color:#f1f1ff;padding:2px 5px;display:block;background-color:#f1f1ff;pad=
|
|
||||||
ding:5px">.fa-custom-burger:before {
|
|
||||||
content: "\01f354";
|
|
||||||
font-family: inherit;
|
|
||||||
}</code></pre>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">And get =F0=9F=8D=94 as your badge icon =
|
|
||||||
when you enter <code style=3D"background-color:#f1f1ff;padding:2px 5px">cus=
|
|
||||||
tom-burger</code>.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-col=
|
|
||||||
or:#ddd;min-height:1px;border:1px">
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"https://meta.discour=
|
|
||||||
se.org/t/badge-icons-where-to-find-them/18058/9" style=3D"color:#666;text-d=
|
|
||||||
ecoration:none;font-weight:bold;color:#006699" target=3D"_blank">https://me=
|
|
||||||
ta.discourse.org/t/badge-icons-where-to-find-them/18058/9</a> in your brows=
|
|
||||||
er.</p>
|
|
||||||
</div>
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href=3D"https://meta.dis=
|
|
||||||
course.org/my/preferences" style=3D"color:#666;text-decoration:none;font-we=
|
|
||||||
ight:bold;color:#006699" target=3D"_blank">user preferences</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</blockquote></div><br></div></div>
|
|
||||||
|
|
||||||
--001a11c34c389e728f0502aa26a0--
|
|
12
spec/fixtures/emails/original_message.eml
vendored
Normal file
12
spec/fixtures/emails/original_message.eml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Return-Path: <discourse@bar.com>
|
||||||
|
From: Foo Bar <discourse@bar.com>
|
||||||
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <27@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
This is a reply :)
|
||||||
|
|
||||||
|
---Original Message---
|
||||||
|
This part should not be included
|
|
@ -1,30 +0,0 @@
|
||||||
Delivered-To: test@mail.com
|
|
||||||
Return-Path: <walter.white@googlemail.com>
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
Content-Type: multipart/alternative;
|
|
||||||
boundary=Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
Mime-Version: 1.0 (1.0)
|
|
||||||
Subject: Re: Signature in email replies!
|
|
||||||
Date: Thu, 23 Oct 2014 14:43:49 +0530
|
|
||||||
References: <1234@mail.gmail.com>
|
|
||||||
In-Reply-To: <1234@mail.gmail.com>
|
|
||||||
To: Arpit Jalan <test@mail.com>
|
|
||||||
X-Mailer: iPhone Mail (12A405)
|
|
||||||
|
|
||||||
|
|
||||||
--Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975
|
|
||||||
Content-Type: text/plain;
|
|
||||||
charset=us-ascii
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
|
|
||||||
This post should not include signature.
|
|
||||||
----Original Message----
|
|
||||||
|
|
||||||
Context here.
|
|
||||||
|
|
||||||
> On 23-Oct-2014, at 9:45 am, Arpit Jalan <test@mail.com> wrote:
|
|
||||||
>
|
|
||||||
> Signature in email replies!
|
|
||||||
|
|
||||||
--Apple-Mail-8E182EEF-9DBC-41DE-A593-DF2E5EBD3975
|
|
188
spec/fixtures/emails/outlook.eml
vendored
188
spec/fixtures/emails/outlook.eml
vendored
|
@ -1,188 +0,0 @@
|
||||||
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Received: by 10.25.161.144 with HTTP; Tue, 7 Oct 2014 22:17:17 -0700 (PDT)
|
|
||||||
X-Originating-IP: [117.207.85.84]
|
|
||||||
In-Reply-To: <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail>
|
|
||||||
References: <topic/35@discourse.techapj.com>
|
|
||||||
<5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail>
|
|
||||||
Date: Wed, 8 Oct 2014 10:47:17 +0530
|
|
||||||
Delivered-To: arpit@techapj.com
|
|
||||||
Message-ID: <CAOJeqne=SJ_LwN4sb-0Y95ejc2OpreVhdmcPn0TnmwSvTCYzzQ@mail.gmail.com>
|
|
||||||
Subject: Re: [Discourse] [Meta] Welcome to techAPJ's Discourse!
|
|
||||||
From: Arpit Jalan <arpit@techapj.com>
|
|
||||||
To: Discourse <mail+e1c7f2a380e33840aeb654f075490bad@arpitjalan.com>Accept-Language: en-US
|
|
||||||
Content-Language: en-US
|
|
||||||
X-MS-Has-Attach:
|
|
||||||
X-MS-TNEF-Correlator:
|
|
||||||
x-originating-ip: [134.68.31.227]
|
|
||||||
Content-Type: multipart/alternative;
|
|
||||||
boundary="_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
|
|
||||||
--_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_
|
|
||||||
Content-Type: text/plain; charset="utf-8"
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
TWljcm9zb2Z0IE91dGxvb2sgMjAxMA0KDQpGcm9tOiBtaWNoYWVsIFttYWlsdG86dGFsa0BvcGVu
|
|
||||||
bXJzLm9yZ10NClNlbnQ6IE1vbmRheSwgT2N0b2JlciAxMywgMjAxNCA5OjM4IEFNDQpUbzogUG93
|
|
||||||
ZXIsIENocmlzDQpTdWJqZWN0OiBbUE1dIFlvdXIgcG9zdCBpbiAiQnVyZ2VyaGF1czogTmV3IHJl
|
|
||||||
c3RhdXJhbnQgLyBsdW5jaCB2ZW51ZSINCg0KDQptaWNoYWVsPGh0dHA6Ly9jbC5vcGVubXJzLm9y
|
|
||||||
Zy90cmFjay9jbGljay8zMDAzOTkwNS90YWxrLm9wZW5tcnMub3JnP3A9ZXlKeklqb2liR2xaYTFW
|
|
||||||
MGVYaENZMDFNUlRGc1VESm1ZelZRTTBabGVqRTRJaXdpZGlJNk1Td2ljQ0k2SW50Y0luVmNJam96
|
|
||||||
TURBek9Ua3dOU3hjSW5aY0lqb3hMRndpZFhKc1hDSTZYQ0pvZEhSd2N6cGNYRnd2WEZ4Y0wzUmhi
|
|
||||||
R3N1YjNCbGJtMXljeTV2Y21kY1hGd3ZkWE5sY25OY1hGd3ZiV2xqYUdGbGJGd2lMRndpYVdSY0lq
|
|
||||||
cGNJbVExWW1Nd04yTmtORFJqWkRRNE1HTTRZVGcyTXpsalpXSTFOemd6WW1ZMlhDSXNYQ0oxY214
|
|
||||||
ZmFXUnpYQ0k2VzF3aVlqaGtPRGcxTWprNU56ZG1aalkxWldZeU5URTNPV1JpTkdZeU1XSTNOekZq
|
|
||||||
TnpoalpqaGtPRndpWFgwaWZRPg0KT2N0b2JlciAxMw0KDQpodHRwczovL3RhbGsub3Blbm1ycy5v
|
|
||||||
cmcvdC9idXJnZXJoYXVzLW5ldy1yZXN0YXVyYW50LWx1bmNoLXZlbnVlLzY3Mi8zPGh0dHA6Ly9j
|
|
||||||
bC5vcGVubXJzLm9yZy90cmFjay9jbGljay8zMDAzOTkwNS90YWxrLm9wZW5tcnMub3JnP3A9ZXlK
|
|
||||||
eklqb2lVRVJJU1VOeVIzbFZNRGRCVlZocFduUjNXV3g0TVdOc1RXNVpJaXdpZGlJNk1Td2ljQ0k2
|
|
||||||
SW50Y0luVmNJam96TURBek9Ua3dOU3hjSW5aY0lqb3hMRndpZFhKc1hDSTZYQ0pvZEhSd2N6cGNY
|
|
||||||
Rnd2WEZ4Y0wzUmhiR3N1YjNCbGJtMXljeTV2Y21kY1hGd3ZkRnhjWEM5aWRYSm5aWEpvWVhWekxX
|
|
||||||
NWxkeTF5WlhOMFlYVnlZVzUwTFd4MWJtTm9MWFpsYm5WbFhGeGNMelkzTWx4Y1hDOHpYQ0lzWENK
|
|
||||||
cFpGd2lPbHdpWkRWaVl6QTNZMlEwTkdOa05EZ3dZemhoT0RZek9XTmxZalUzT0ROaVpqWmNJaXhj
|
|
||||||
SW5WeWJGOXBaSE5jSWpwYlhDSmlOelppWWprMFpURmlOekk1WlRrMlpUUmxaV000TkdSbU1qUTRN
|
|
||||||
RE13WWpZeVlXWXlNR00wWENKZGZTSjk+DQoNCkxvb2tzIGxpa2UgeW91ciByZXBseS1ieS1lbWFp
|
|
||||||
bCB3YXNuJ3QgcHJvY2Vzc2VkIGNvcnJlY3RseSBieSBvdXIgc29mdHdhcmUuIENhbiB5b3UgbGV0
|
|
||||||
IG1lIGtub3cgd2hhdCB2ZXJzaW9uL09TIG9mIHdoYXQgZW1haWwgcHJvZ3JhbSB5b3UncmUgdXNp
|
|
||||||
bmc/IFdlIHdpbGwgd2FudCB0byB0cnkgdG8gZml4IHRoZSBidWcuIDpzbWlsZToNCg0KVGhhbmtz
|
|
||||||
IQ0KDQoNCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoNClRvIHJlc3BvbmQsIHJl
|
|
||||||
cGx5IHRvIHRoaXMgZW1haWwgb3IgdmlzaXQgaHR0cHM6Ly90YWxrLm9wZW5tcnMub3JnL3QveW91
|
|
||||||
ci1wb3N0LWluLWJ1cmdlcmhhdXMtbmV3LXJlc3RhdXJhbnQtbHVuY2gtdmVudWUvNjc0LzE8aHR0
|
|
||||||
cDovL2NsLm9wZW5tcnMub3JnL3RyYWNrL2NsaWNrLzMwMDM5OTA1L3RhbGsub3Blbm1ycy5vcmc/
|
|
||||||
cD1leUp6SWpvaWVYaDJWbnBGTUhSMU1uRm5aRWR1TlhFd01GcFFPVlp0VFZvNElpd2lkaUk2TVN3
|
|
||||||
aWNDSTZJbnRjSW5WY0lqb3pNREF6T1Rrd05TeGNJblpjSWpveExGd2lkWEpzWENJNlhDSm9kSFJ3
|
|
||||||
Y3pwY1hGd3ZYRnhjTDNSaGJHc3ViM0JsYm0xeWN5NXZjbWRjWEZ3dmRGeGNYQzk1YjNWeUxYQnZj
|
|
||||||
M1F0YVc0dFluVnlaMlZ5YUdGMWN5MXVaWGN0Y21WemRHRjFjbUZ1ZEMxc2RXNWphQzEyWlc1MVpW
|
|
||||||
eGNYQzgyTnpSY1hGd3ZNVndpTEZ3aWFXUmNJanBjSW1RMVltTXdOMk5rTkRSalpEUTRNR000WVRn
|
|
||||||
Mk16bGpaV0kxTnpnelltWTJYQ0lzWENKMWNteGZhV1J6WENJNlcxd2lZamMyWW1JNU5HVXhZamN5
|
|
||||||
T1dVNU5tVTBaV1ZqT0RSa1pqSTBPREF6TUdJMk1tRm1NakJqTkZ3aVhYMGlmUT4gaW4geW91ciBi
|
|
||||||
cm93c2VyLg0KDQpUbyB1bnN1YnNjcmliZSBmcm9tIHRoZXNlIGVtYWlscywgdmlzaXQgeW91ciB1
|
|
||||||
c2VyIHByZWZlcmVuY2VzPGh0dHA6Ly9jbC5vcGVubXJzLm9yZy90cmFjay9jbGljay8zMDAzOTkw
|
|
||||||
NS90YWxrLm9wZW5tcnMub3JnP3A9ZXlKeklqb2lkVXh1V2xnNVZGYzBPV1pXUzBZNGJGZExkbWx5
|
|
||||||
V0dzeFRWOXpJaXdpZGlJNk1Td2ljQ0k2SW50Y0luVmNJam96TURBek9Ua3dOU3hjSW5aY0lqb3hM
|
|
||||||
RndpZFhKc1hDSTZYQ0pvZEhSd2N6cGNYRnd2WEZ4Y0wzUmhiR3N1YjNCbGJtMXljeTV2Y21kY1hG
|
|
||||||
d3ZiWGxjWEZ3dmNISmxabVZ5Wlc1alpYTmNJaXhjSW1sa1hDSTZYQ0prTldKak1EZGpaRFEwWTJR
|
|
||||||
ME9EQmpPR0U0TmpNNVkyVmlOVGM0TTJKbU5sd2lMRndpZFhKc1gybGtjMXdpT2x0Y0ltSTRNV1V3
|
|
||||||
WmpBMU5EWTVORE0wTnpneU0yRm1NakEyTmpGalpqYzNaR05pTjJOaFl6ZG1NakpjSWwxOUluMD4u
|
|
||||||
DQoNCg==
|
|
||||||
|
|
||||||
--_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_
|
|
||||||
Content-Type: text/html; charset="utf-8"
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
PGh0bWwgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIHhtbG5zOm89InVy
|
|
||||||
bjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6dz0idXJuOnNjaGVt
|
|
||||||
YXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6d29yZCIgeG1sbnM6bT0iaHR0cDovL3NjaGVtYXMubWlj
|
|
||||||
cm9zb2Z0LmNvbS9vZmZpY2UvMjAwNC8xMi9vbW1sIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
|
|
||||||
VFIvUkVDLWh0bWw0MCI+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIg
|
|
||||||
Y29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4NCjxtZXRhIG5hbWU9IkdlbmVyYXRv
|
|
||||||
ciIgY29udGVudD0iTWljcm9zb2Z0IFdvcmQgMTQgKGZpbHRlcmVkIG1lZGl1bSkiPg0KPCEtLVtp
|
|
||||||
ZiAhbXNvXT48c3R5bGU+dlw6KiB7YmVoYXZpb3I6dXJsKCNkZWZhdWx0I1ZNTCk7fQ0Kb1w6KiB7
|
|
||||||
YmVoYXZpb3I6dXJsKCNkZWZhdWx0I1ZNTCk7fQ0Kd1w6KiB7YmVoYXZpb3I6dXJsKCNkZWZhdWx0
|
|
||||||
I1ZNTCk7fQ0KLnNoYXBlIHtiZWhhdmlvcjp1cmwoI2RlZmF1bHQjVk1MKTt9DQo8L3N0eWxlPjwh
|
|
||||||
W2VuZGlmXS0tPjxzdHlsZT48IS0tDQovKiBGb250IERlZmluaXRpb25zICovDQpAZm9udC1mYWNl
|
|
||||||
DQoJe2ZvbnQtZmFtaWx5OkNhbGlicmk7DQoJcGFub3NlLTE6MiAxNSA1IDIgMiAyIDQgMyAyIDQ7
|
|
||||||
fQ0KQGZvbnQtZmFjZQ0KCXtmb250LWZhbWlseTpUYWhvbWE7DQoJcGFub3NlLTE6MiAxMSA2IDQg
|
|
||||||
MyA1IDQgNCAyIDQ7fQ0KLyogU3R5bGUgRGVmaW5pdGlvbnMgKi8NCnAuTXNvTm9ybWFsLCBsaS5N
|
|
||||||
c29Ob3JtYWwsIGRpdi5Nc29Ob3JtYWwNCgl7bWFyZ2luOjBpbjsNCgltYXJnaW4tYm90dG9tOi4w
|
|
||||||
MDAxcHQ7DQoJZm9udC1zaXplOjEyLjBwdDsNCglmb250LWZhbWlseToiVGltZXMgTmV3IFJvbWFu
|
|
||||||
Iiwic2VyaWYiO30NCmE6bGluaywgc3Bhbi5Nc29IeXBlcmxpbmsNCgl7bXNvLXN0eWxlLXByaW9y
|
|
||||||
aXR5Ojk5Ow0KCWNvbG9yOmJsdWU7DQoJdGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZTt9DQphOnZp
|
|
||||||
c2l0ZWQsIHNwYW4uTXNvSHlwZXJsaW5rRm9sbG93ZWQNCgl7bXNvLXN0eWxlLXByaW9yaXR5Ojk5
|
|
||||||
Ow0KCWNvbG9yOnB1cnBsZTsNCgl0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lO30NCnANCgl7bXNv
|
|
||||||
LXN0eWxlLXByaW9yaXR5Ojk5Ow0KCW1zby1tYXJnaW4tdG9wLWFsdDphdXRvOw0KCW1hcmdpbi1y
|
|
||||||
aWdodDowaW47DQoJbXNvLW1hcmdpbi1ib3R0b20tYWx0OmF1dG87DQoJbWFyZ2luLWxlZnQ6MGlu
|
|
||||||
Ow0KCWZvbnQtc2l6ZToxMi4wcHQ7DQoJZm9udC1mYW1pbHk6IlRpbWVzIE5ldyBSb21hbiIsInNl
|
|
||||||
cmlmIjt9DQpzcGFuLkVtYWlsU3R5bGUxOA0KCXttc28tc3R5bGUtdHlwZTpwZXJzb25hbC1yZXBs
|
|
||||||
eTsNCglmb250LWZhbWlseToiQ2FsaWJyaSIsInNhbnMtc2VyaWYiOw0KCWNvbG9yOiMxRjQ5N0Q7
|
|
||||||
fQ0KLk1zb0NocERlZmF1bHQNCgl7bXNvLXN0eWxlLXR5cGU6ZXhwb3J0LW9ubHk7DQoJZm9udC1m
|
|
||||||
YW1pbHk6IkNhbGlicmkiLCJzYW5zLXNlcmlmIjt9DQpAcGFnZSBXb3JkU2VjdGlvbjENCgl7c2l6
|
|
||||||
ZTo4LjVpbiAxMS4waW47DQoJbWFyZ2luOjEuMGluIDEuMGluIDEuMGluIDEuMGluO30NCmRpdi5X
|
|
||||||
b3JkU2VjdGlvbjENCgl7cGFnZTpXb3JkU2VjdGlvbjE7fQ0KLS0+PC9zdHlsZT48IS0tW2lmIGd0
|
|
||||||
ZSBtc28gOV0+PHhtbD4NCjxvOnNoYXBlZGVmYXVsdHMgdjpleHQ9ImVkaXQiIHNwaWRtYXg9IjEw
|
|
||||||
MjYiIC8+DQo8L3htbD48IVtlbmRpZl0tLT48IS0tW2lmIGd0ZSBtc28gOV0+PHhtbD4NCjxvOnNo
|
|
||||||
YXBlbGF5b3V0IHY6ZXh0PSJlZGl0Ij4NCjxvOmlkbWFwIHY6ZXh0PSJlZGl0IiBkYXRhPSIxIiAv
|
|
||||||
Pg0KPC9vOnNoYXBlbGF5b3V0PjwveG1sPjwhW2VuZGlmXS0tPg0KPC9oZWFkPg0KPGJvZHkgbGFu
|
|
||||||
Zz0iRU4tVVMiIGxpbms9ImJsdWUiIHZsaW5rPSJwdXJwbGUiPg0KPGRpdiBjbGFzcz0iV29yZFNl
|
|
||||||
Y3Rpb24xIj4NCjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTEu
|
|
||||||
MHB0O2ZvbnQtZmFtaWx5OiZxdW90O0NhbGlicmkmcXVvdDssJnF1b3Q7c2Fucy1zZXJpZiZxdW90
|
|
||||||
Oztjb2xvcjojMUY0OTdEIj5NaWNyb3NvZnQgT3V0bG9vayAyMDEwPG86cD48L286cD48L3NwYW4+
|
|
||||||
PC9wPg0KPHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxMS4wcHQ7
|
|
||||||
Zm9udC1mYW1pbHk6JnF1b3Q7Q2FsaWJyaSZxdW90OywmcXVvdDtzYW5zLXNlcmlmJnF1b3Q7O2Nv
|
|
||||||
bG9yOiMxRjQ5N0QiPjxvOnA+Jm5ic3A7PC9vOnA+PC9zcGFuPjwvcD4NCjxwIGNsYXNzPSJNc29O
|
|
||||||
b3JtYWwiPjxiPjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTAuMHB0O2ZvbnQtZmFtaWx5OiZxdW90
|
|
||||||
O1RhaG9tYSZxdW90OywmcXVvdDtzYW5zLXNlcmlmJnF1b3Q7Ij5Gcm9tOjwvc3Bhbj48L2I+PHNw
|
|
||||||
YW4gc3R5bGU9ImZvbnQtc2l6ZToxMC4wcHQ7Zm9udC1mYW1pbHk6JnF1b3Q7VGFob21hJnF1b3Q7
|
|
||||||
LCZxdW90O3NhbnMtc2VyaWYmcXVvdDsiPiBtaWNoYWVsIFttYWlsdG86dGFsa0BvcGVubXJzLm9y
|
|
||||||
Z10NCjxicj4NCjxiPlNlbnQ6PC9iPiBNb25kYXksIE9jdG9iZXIgMTMsIDIwMTQgOTozOCBBTTxi
|
|
||||||
cj4NCjxiPlRvOjwvYj4gUG93ZXIsIENocmlzPGJyPg0KPGI+U3ViamVjdDo8L2I+IFtQTV0gWW91
|
|
||||||
ciBwb3N0IGluICZxdW90O0J1cmdlcmhhdXM6IE5ldyByZXN0YXVyYW50IC8gbHVuY2ggdmVudWUm
|
|
||||||
cXVvdDs8bzpwPjwvbzpwPjwvc3Bhbj48L3A+DQo8cCBjbGFzcz0iTXNvTm9ybWFsIj48bzpwPiZu
|
|
||||||
YnNwOzwvbzpwPjwvcD4NCjxkaXY+DQo8dGFibGUgY2xhc3M9Ik1zb05vcm1hbFRhYmxlIiBib3Jk
|
|
||||||
ZXI9IjAiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMCI+DQo8dGJvZHk+DQo8dHI+DQo8
|
|
||||||
dGQgdmFsaWduPSJ0b3AiIHN0eWxlPSJwYWRkaW5nOjBpbiAwaW4gMGluIDBpbiI+PC90ZD4NCjx0
|
|
||||||
ZCBzdHlsZT0icGFkZGluZzowaW4gMGluIDBpbiAwaW4iPg0KPHAgY2xhc3M9Ik1zb05vcm1hbCIg
|
|
||||||
c3R5bGU9Im1hcmdpbi1ib3R0b206MTguNzVwdCI+PGEgaHJlZj0iaHR0cDovL2NsLm9wZW5tcnMu
|
|
||||||
b3JnL3RyYWNrL2NsaWNrLzMwMDM5OTA1L3RhbGsub3Blbm1ycy5vcmc/cD1leUp6SWpvaWJHbFph
|
|
||||||
MVYwZVhoQ1kwMU1SVEZzVURKbVl6VlFNMFpsZWpFNElpd2lkaUk2TVN3aWNDSTZJbnRjSW5WY0lq
|
|
||||||
b3pNREF6T1Rrd05TeGNJblpjSWpveExGd2lkWEpzWENJNlhDSm9kSFJ3Y3pwY1hGd3ZYRnhjTDNS
|
|
||||||
aGJHc3ViM0JsYm0xeWN5NXZjbWRjWEZ3dmRYTmxjbk5jWEZ3dmJXbGphR0ZsYkZ3aUxGd2lhV1Jj
|
|
||||||
SWpwY0ltUTFZbU13TjJOa05EUmpaRFE0TUdNNFlUZzJNemxqWldJMU56Z3pZbVkyWENJc1hDSjFj
|
|
||||||
bXhmYVdSelhDSTZXMXdpWWpoa09EZzFNams1TnpkbVpqWTFaV1l5TlRFM09XUmlOR1l5TVdJM056
|
|
||||||
RmpOemhqWmpoa09Gd2lYWDBpZlEiIHRhcmdldD0iX2JsYW5rIj48Yj48c3BhbiBzdHlsZT0iZm9u
|
|
||||||
dC1zaXplOjEwLjBwdDtmb250LWZhbWlseTomcXVvdDtUYWhvbWEmcXVvdDssJnF1b3Q7c2Fucy1z
|
|
||||||
ZXJpZiZxdW90Oztjb2xvcjojMDA2Njk5O3RleHQtZGVjb3JhdGlvbjpub25lIj5taWNoYWVsPC9z
|
|
||||||
cGFuPjwvYj48L2E+PGJyPg0KPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZTo4LjVwdDtmb250LWZhbWls
|
|
||||||
eTomcXVvdDtUYWhvbWEmcXVvdDssJnF1b3Q7c2Fucy1zZXJpZiZxdW90Oztjb2xvcjojOTk5OTk5
|
|
||||||
Ij5PY3RvYmVyIDEzPC9zcGFuPg0KPG86cD48L286cD48L3A+DQo8L3RkPg0KPC90cj4NCjx0cj4N
|
|
||||||
Cjx0ZCBjb2xzcGFuPSIyIiBzdHlsZT0icGFkZGluZzozLjc1cHQgMGluIDBpbiAwaW4iPg0KPHAg
|
|
||||||
Y2xhc3M9Ik1zb05vcm1hbCIgc3R5bGU9Im1hcmdpbi1ib3R0b206MTguNzVwdCI+PGEgaHJlZj0i
|
|
||||||
aHR0cDovL2NsLm9wZW5tcnMub3JnL3RyYWNrL2NsaWNrLzMwMDM5OTA1L3RhbGsub3Blbm1ycy5v
|
|
||||||
cmc/cD1leUp6SWpvaVVFUklTVU55UjNsVk1EZEJWVmhwV25SM1dXeDRNV05zVFc1Wklpd2lkaUk2
|
|
||||||
TVN3aWNDSTZJbnRjSW5WY0lqb3pNREF6T1Rrd05TeGNJblpjSWpveExGd2lkWEpzWENJNlhDSm9k
|
|
||||||
SFJ3Y3pwY1hGd3ZYRnhjTDNSaGJHc3ViM0JsYm0xeWN5NXZjbWRjWEZ3dmRGeGNYQzlpZFhKblpY
|
|
||||||
Sm9ZWFZ6TFc1bGR5MXlaWE4wWVhWeVlXNTBMV3gxYm1Ob0xYWmxiblZsWEZ4Y0x6WTNNbHhjWEM4
|
|
||||||
elhDSXNYQ0pwWkZ3aU9sd2laRFZpWXpBM1kyUTBOR05rTkRnd1l6aGhPRFl6T1dObFlqVTNPRE5p
|
|
||||||
WmpaY0lpeGNJblZ5YkY5cFpITmNJanBiWENKaU56WmlZamswWlRGaU56STVaVGsyWlRSbFpXTTRO
|
|
||||||
R1JtTWpRNE1ETXdZall5WVdZeU1HTTBYQ0pkZlNKOSI+PGI+PHNwYW4gc3R5bGU9ImNvbG9yOiMw
|
|
||||||
MDY2OTk7dGV4dC1kZWNvcmF0aW9uOm5vbmUiPmh0dHBzOi8vdGFsay5vcGVubXJzLm9yZy90L2J1
|
|
||||||
cmdlcmhhdXMtbmV3LXJlc3RhdXJhbnQtbHVuY2gtdmVudWUvNjcyLzM8L3NwYW4+PC9iPjwvYT4N
|
|
||||||
CjxvOnA+PC9vOnA+PC9wPg0KPHAgc3R5bGU9Im1hcmdpbi10b3A6MGluIj5Mb29rcyBsaWtlIHlv
|
|
||||||
dXIgcmVwbHktYnktZW1haWwgd2Fzbid0IHByb2Nlc3NlZCBjb3JyZWN0bHkgYnkgb3VyIHNvZnR3
|
|
||||||
YXJlLiBDYW4geW91IGxldCBtZSBrbm93IHdoYXQgdmVyc2lvbi9PUyBvZiB3aGF0IGVtYWlsIHBy
|
|
||||||
b2dyYW0geW91J3JlIHVzaW5nPyBXZSB3aWxsIHdhbnQgdG8gdHJ5IHRvIGZpeCB0aGUgYnVnLiA6
|
|
||||||
c21pbGU6PG86cD48L286cD48L3A+DQo8cCBzdHlsZT0ibWFyZ2luLXRvcDowaW4iPlRoYW5rcyE8
|
|
||||||
bzpwPjwvbzpwPjwvcD4NCjwvdGQ+DQo8L3RyPg0KPC90Ym9keT4NCjwvdGFibGU+DQo8ZGl2IGNs
|
|
||||||
YXNzPSJNc29Ob3JtYWwiIGFsaWduPSJjZW50ZXIiIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+
|
|
||||||
DQo8aHIgc2l6ZT0iMSIgd2lkdGg9IjEwMCUiIGFsaWduPSJjZW50ZXIiPg0KPC9kaXY+DQo8ZGl2
|
|
||||||
Pg0KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiM2NjY2NjYiPlRvIHJlc3BvbmQsIHJlcGx5IHRvIHRo
|
|
||||||
aXMgZW1haWwgb3IgdmlzaXQgPGEgaHJlZj0iaHR0cDovL2NsLm9wZW5tcnMub3JnL3RyYWNrL2Ns
|
|
||||||
aWNrLzMwMDM5OTA1L3RhbGsub3Blbm1ycy5vcmc/cD1leUp6SWpvaWVYaDJWbnBGTUhSMU1uRm5a
|
|
||||||
RWR1TlhFd01GcFFPVlp0VFZvNElpd2lkaUk2TVN3aWNDSTZJbnRjSW5WY0lqb3pNREF6T1Rrd05T
|
|
||||||
eGNJblpjSWpveExGd2lkWEpzWENJNlhDSm9kSFJ3Y3pwY1hGd3ZYRnhjTDNSaGJHc3ViM0JsYm0x
|
|
||||||
eWN5NXZjbWRjWEZ3dmRGeGNYQzk1YjNWeUxYQnZjM1F0YVc0dFluVnlaMlZ5YUdGMWN5MXVaWGN0
|
|
||||||
Y21WemRHRjFjbUZ1ZEMxc2RXNWphQzEyWlc1MVpWeGNYQzgyTnpSY1hGd3ZNVndpTEZ3aWFXUmNJ
|
|
||||||
anBjSW1RMVltTXdOMk5rTkRSalpEUTRNR000WVRnMk16bGpaV0kxTnpnelltWTJYQ0lzWENKMWNt
|
|
||||||
eGZhV1J6WENJNlcxd2lZamMyWW1JNU5HVXhZamN5T1dVNU5tVTBaV1ZqT0RSa1pqSTBPREF6TUdJ
|
|
||||||
Mk1tRm1NakJqTkZ3aVhYMGlmUSI+DQo8Yj48c3BhbiBzdHlsZT0iY29sb3I6IzAwNjY5OTt0ZXh0
|
|
||||||
LWRlY29yYXRpb246bm9uZSI+aHR0cHM6Ly90YWxrLm9wZW5tcnMub3JnL3QveW91ci1wb3N0LWlu
|
|
||||||
LWJ1cmdlcmhhdXMtbmV3LXJlc3RhdXJhbnQtbHVuY2gtdmVudWUvNjc0LzE8L3NwYW4+PC9iPjwv
|
|
||||||
YT4gaW4geW91ciBicm93c2VyLjxvOnA+PC9vOnA+PC9zcGFuPjwvcD4NCjwvZGl2Pg0KPGRpdj4N
|
|
||||||
CjxwPjxzcGFuIHN0eWxlPSJjb2xvcjojNjY2NjY2Ij5UbyB1bnN1YnNjcmliZSBmcm9tIHRoZXNl
|
|
||||||
IGVtYWlscywgdmlzaXQgeW91ciA8YSBocmVmPSJodHRwOi8vY2wub3Blbm1ycy5vcmcvdHJhY2sv
|
|
||||||
Y2xpY2svMzAwMzk5MDUvdGFsay5vcGVubXJzLm9yZz9wPWV5SnpJam9pZFV4dVdsZzVWRmMwT1da
|
|
||||||
V1MwWTRiRmRMZG1seVdHc3hUVjl6SWl3aWRpSTZNU3dpY0NJNkludGNJblZjSWpvek1EQXpPVGt3
|
|
||||||
TlN4Y0luWmNJam94TEZ3aWRYSnNYQ0k2WENKb2RIUndjenBjWEZ3dlhGeGNMM1JoYkdzdWIzQmxi
|
|
||||||
bTF5Y3k1dmNtZGNYRnd2YlhsY1hGd3ZjSEpsWm1WeVpXNWpaWE5jSWl4Y0ltbGtYQ0k2WENKa05X
|
|
||||||
SmpNRGRqWkRRMFkyUTBPREJqT0dFNE5qTTVZMlZpTlRjNE0ySm1ObHdpTEZ3aWRYSnNYMmxrYzF3
|
|
||||||
aU9sdGNJbUk0TVdVd1pqQTFORFk1TkRNME56Z3lNMkZtTWpBMk5qRmpaamMzWkdOaU4yTmhZemRt
|
|
||||||
TWpKY0lsMTlJbjAiPg0KPGI+PHNwYW4gc3R5bGU9ImNvbG9yOiMwMDY2OTk7dGV4dC1kZWNvcmF0
|
|
||||||
aW9uOm5vbmUiPnVzZXIgcHJlZmVyZW5jZXM8L3NwYW4+PC9iPjwvYT4uPG86cD48L286cD48L3Nw
|
|
||||||
YW4+PC9wPg0KPC9kaXY+DQo8L2Rpdj4NCjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxpbWcgYm9yZGVy
|
|
||||||
PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBpZD0iX3gwMDAwX2kxMDI2IiBzcmM9Imh0dHA6Ly9j
|
|
||||||
bC5vcGVubXJzLm9yZy90cmFjay9vcGVuLnBocD91PTMwMDM5OTA1JmFtcDtpZD1kNWJjMDdjZDQ0
|
|
||||||
Y2Q0ODBjOGE4NjM5Y2ViNTc4M2JmNiI+PG86cD48L286cD48L3A+DQo8L2Rpdj4NCjwvYm9keT4N
|
|
||||||
CjwvaHRtbD4NCg==
|
|
||||||
|
|
||||||
--_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_--
|
|
7
spec/fixtures/emails/paragraphs.cooked
vendored
7
spec/fixtures/emails/paragraphs.cooked
vendored
|
@ -1,7 +0,0 @@
|
||||||
<p>Is there any reason the <em>old</em> candy can't be be kept in silos while the new candy
|
|
||||||
is imported into <em>new</em> silos?</p>
|
|
||||||
|
|
||||||
<p>The thing about candy is it stays delicious for a long time -- we can just keep
|
|
||||||
it there without worrying about it too much, imo.</p>
|
|
||||||
|
|
||||||
<p>Thanks for listening.</p>
|
|
48
spec/fixtures/emails/paragraphs.eml
vendored
48
spec/fixtures/emails/paragraphs.eml
vendored
|
@ -1,42 +1,12 @@
|
||||||
Return-Path: <jake@adventuretime.ooo>
|
Return-Path: <discourse@bar.com>
|
||||||
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
|
From: Foo Bar <discourse@bar.com>
|
||||||
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
|
Message-ID: <22@foo.bar.mail>
|
||||||
Date: Thu, 13 Jun 2013 17:03:48 -0400
|
|
||||||
From: Jake the Dog <jake@adventuretime.ooo>
|
|
||||||
To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo
|
|
||||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
|
||||||
Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'
|
|
||||||
Mime-Version: 1.0
|
Mime-Version: 1.0
|
||||||
Content-Type: text/plain;
|
Content-Type: text/plain; charset=UTF-8
|
||||||
charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
X-Sieve: CMU Sieve 2.2
|
|
||||||
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
|
|
||||||
13 Jun 2013 14:03:48 -0700 (PDT)
|
|
||||||
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
|
|
||||||
|
|
||||||
Is there any reason the *old* candy can't be be kept in silos while the new candy
|
Do you like liquorice?
|
||||||
is imported into *new* silos?
|
|
||||||
|
|
||||||
The thing about candy is it stays delicious for a long time -- we can just keep
|
I really like them. One could even say that I am *addicted* to liquorice. Anf if
|
||||||
it there without worrying about it too much, imo.
|
you can mix it up with some anise, then I'm in heaven ;)
|
||||||
|
|
||||||
Thanks for listening.
|
|
||||||
|
|
||||||
On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta
|
|
||||||
<reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo> wrote:
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> eviltrout posted in 'Adventure Time Sux' on Discourse Meta:
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> hey guys everyone knows adventure time sucks!
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences).
|
|
||||||
>
|
|
||||||
|
|
37
spec/fixtures/emails/plus_one.eml
vendored
37
spec/fixtures/emails/plus_one.eml
vendored
|
@ -1,37 +0,0 @@
|
||||||
Return-Path: <FROM>
|
|
||||||
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
|
|
||||||
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
|
|
||||||
Date: Thu, 13 Jun 2013 17:03:48 -0400
|
|
||||||
From: FROM
|
|
||||||
To: TO
|
|
||||||
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
|
|
||||||
Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux'
|
|
||||||
Mime-Version: 1.0
|
|
||||||
Content-Type: text/plain;
|
|
||||||
charset=ISO-8859-1
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
X-Sieve: CMU Sieve 2.2
|
|
||||||
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
|
|
||||||
13 Jun 2013 14:03:48 -0700 (PDT)
|
|
||||||
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
|
|
||||||
|
|
||||||
+1
|
|
||||||
|
|
||||||
|
|
||||||
On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta
|
|
||||||
<reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo> wrote:
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> eviltrout posted in 'Adventure Time Sux' on Discourse Meta:
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> hey guys everyone knows adventure time sucks!
|
|
||||||
>
|
|
||||||
> ---
|
|
||||||
> Please visit this link to respond: http://localhost:3000/t/adventure-time-sux/1234/3
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your [user preferences](http://localhost:3000/user_preferences).
|
|
||||||
>
|
|
38
spec/fixtures/emails/previous.eml
vendored
38
spec/fixtures/emails/previous.eml
vendored
|
@ -1,38 +0,0 @@
|
||||||
|
|
||||||
Delivered-To: discourse-reply+cd480e301683c9902891f15968bf07a5@discourse.org
|
|
||||||
Received: by 10.194.216.104 with SMTP id op8csp80593wjc;
|
|
||||||
Wed, 24 Jul 2013 07:59:14 -0700 (PDT)
|
|
||||||
Return-Path: <walter.white@googlemail.com>
|
|
||||||
References: <topic/5043@discourse.org> <51efeb9b36c34_66dc2dfce6811866@discourse.mail>
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
In-Reply-To: <51efeb9b36c34_66dc2dfce6811866@discourse.mail>
|
|
||||||
Mime-Version: 1.0 (1.0)
|
|
||||||
Date: Wed, 24 Jul 2013 15:59:10 +0100
|
|
||||||
Message-ID: <4597127794206131679@unknownmsgid>
|
|
||||||
Subject: Re: [Discourse] new reply to your post in 'Crystal Blue'
|
|
||||||
To: walter via Discourse <reply+cd480e301683c9902891f15968bf07a5@appmail.adventuretime.ooo>
|
|
||||||
Content-Type: multipart/alternative; boundary=001a11c20edc15a39304e2432790
|
|
||||||
|
|
||||||
This will not include the previous discussion that is present in this email.
|
|
||||||
------------------------------
|
|
||||||
Previous discussion
|
|
||||||
skylerwhite<http://discourse.org/users/skylerwhite> July 24
|
|
||||||
|
|
||||||
This is a reply.
|
|
||||||
fring <http://discourse.org/users/fring> July 24
|
|
||||||
|
|
||||||
This is an older reply.
|
|
||||||
hank_schrader <http://discourse.org/users/hank_schrader> July 24
|
|
||||||
|
|
||||||
Of course another reply here.
|
|
||||||
walterwhite <http://discourse.org/users/walterwhite> July 24
|
|
||||||
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
To respond, reply to this email or visit
|
|
||||||
http://discourse.org/t/crystal-blue/5043/10in
|
|
||||||
your browser.
|
|
||||||
|
|
||||||
To unsubscribe from these emails, visit your user
|
|
||||||
preferences<http://discourse.org/user_preferences>
|
|
||||||
.
|
|
189
spec/fixtures/emails/previous_replies.eml
vendored
189
spec/fixtures/emails/previous_replies.eml
vendored
|
@ -1,180 +1,23 @@
|
||||||
Delivered-To: reply@discourse.org
|
Return-Path: <discourse@bar.com>
|
||||||
MIME-Version: 1.0
|
From: Foo Bar <discourse@bar.com>
|
||||||
In-Reply-To: <topic/22638/86406@meta.discourse.org>
|
To: reply+4f97315cc828096c9cb34c6f1a0d6fe8@bar.com
|
||||||
References: <topic/22638@meta.discourse.org>
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
<topic/22638/86406@meta.discourse.org>
|
Message-ID: <21@foo.bar.mail>
|
||||||
Date: Fri, 28 Nov 2014 12:55:32 -0800
|
Mime-Version: 1.0
|
||||||
Subject: Re: [Discourse Meta] [Lounge] Testing default email replies
|
|
||||||
From: Walter White <walter.white@googlemail.com>
|
|
||||||
To: Discourse Meta <reply@discourse.org>
|
|
||||||
Content-Type: multipart/alternative; boundary=001a1137c9285318bb0508f17bc5
|
|
||||||
|
|
||||||
--001a1137c9285318bb0508f17bc5
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
### this is a reply from iOS Gmail app
|
This will not include the previous discussion that is present in this email.
|
||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over
|
---
|
||||||
the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown
|
*Previous Replies*
|
||||||
fox jumps over the lazy dog. The quick brown fox jumps over the lazy
|
|
||||||
dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps
|
|
||||||
over the lazy dog.
|
|
||||||
|
|
||||||
This is **bold** text in Markdown.
|
This is previous reply #1.
|
||||||
|
|
||||||
This is a link to http://example.com
|
Posted by foo bar on 01/15/2016
|
||||||
|
|
||||||
On Friday, November 28, 2014, Arpit Jalan <info@discourse.org> wrote:
|
---
|
||||||
|
[Visit the Topic](https://bar.com/t/wat/1/1) to respond.
|
||||||
|
|
||||||
> techAPJ <https://meta.discourse.org/users/techapj>
|
To stop receiving notifications for this particular topic, [click here](h=
|
||||||
> November 28
|
ttps://bar.com/t/wat/1/unsubscribe). To unsubscribe from these emails, ch=
|
||||||
>
|
ange your [user preferences](https://bar.com/my/preferences).
|
||||||
> Test reply.
|
|
||||||
>
|
|
||||||
> First paragraph.
|
|
||||||
>
|
|
||||||
> Second paragraph.
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
> ------------------------------
|
|
||||||
> Previous Replies codinghorror
|
|
||||||
> <https://meta.discourse.org/users/codinghorror>
|
|
||||||
> November 28
|
|
||||||
>
|
|
||||||
> We're testing the latest GitHub email processing library which we are
|
|
||||||
> integrating now.
|
|
||||||
>
|
|
||||||
> https://github.com/github/email_reply_parser
|
|
||||||
>
|
|
||||||
> Go ahead and reply to this topic and I'll reply from various email clients
|
|
||||||
> for testing.
|
|
||||||
> ------------------------------
|
|
||||||
>
|
|
||||||
> To respond, reply to this email or visit
|
|
||||||
> https://meta.discourse.org/t/testing-default-email-replies/22638/3 in
|
|
||||||
> your browser.
|
|
||||||
>
|
|
||||||
> To unsubscribe from these emails, visit your user preferences
|
|
||||||
> <https://meta.discourse.org/my/preferences>.
|
|
||||||
>
|
|
||||||
|
|
||||||
--001a1137c9285318bb0508f17bc5
|
|
||||||
Content-Type: text/html; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
### this is a reply from iOS Gmail app<div><br></div><div>The quick brown f=
|
|
||||||
ox jumps over the lazy dog.=C2=A0<font><span style=3D"background-color:rgba=
|
|
||||||
(255,255,255,0)">The quick brown fox jumps over the lazy dog.=C2=A0The quic=
|
|
||||||
k brown fox jumps over the lazy dog.=C2=A0The quick brown fox jumps over th=
|
|
||||||
e lazy dog.=C2=A0The quick brown fox jumps over the lazy dog.=C2=A0The quic=
|
|
||||||
k brown fox jumps over the lazy dog.=C2=A0The quick brown fox jumps over th=
|
|
||||||
e lazy dog.=C2=A0</span></font></div><div><font><span style><br></span></fo=
|
|
||||||
nt></div><div><font><span style>This is **bold** text in Markdown.</span></=
|
|
||||||
font></div><div><font><span style><br></span></font></div><div><font><span =
|
|
||||||
style>This is a link to <a href=3D"http://example.com">http://example.com</=
|
|
||||||
a><br></span></font><br>On Friday, November 28, 2014, Arpit Jalan <<a hr=
|
|
||||||
ef=3D"mailto:info@discourse.org">info@discourse.org</a>> wrote:<br><bloc=
|
|
||||||
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
|
|
||||||
c solid;padding-left:1ex"><div>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px" cellspacing=3D"0" cellpadding=3D"0" bor=
|
|
||||||
der=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/techapj/45/3281.png" title=3D"techAPJ" style=3D"max-wi=
|
|
||||||
dth:100%" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/techapj" style=3D"text-=
|
|
||||||
decoration:none;font-weight:bold;color:#006699;font-size:13px;font-family:&=
|
|
||||||
#39;lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;text-d=
|
|
||||||
ecoration:none;font-weight:bold" target=3D"_blank">techAPJ</a><br>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">November 28</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0;border:0">Test reply.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">First paragraph.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">Second paragraph.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"https://meta.dis=
|
|
||||||
course.org/t/testing-default-email-replies/22638/3" style=3D"text-decoratio=
|
|
||||||
n:none;font-weight:bold;color:#006699;color:#666" target=3D"_blank">https:/=
|
|
||||||
/meta.discourse.org/t/testing-default-email-replies/22638/3</a> in your bro=
|
|
||||||
wser.</p>
|
|
||||||
</div>
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-c=
|
|
||||||
olor:#ddd;min-height:1px;border:1px">
|
|
||||||
<h4>Previous Replies</h4>
|
|
||||||
|
|
||||||
<table style=3D"margin-bottom:25px" cellspacing=3D"0" cellpadding=3D"0" b=
|
|
||||||
order=3D"0">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"vertical-align:top;width:55px">
|
|
||||||
<img src=3D"https://meta-discourse.global.ssl.fastly.net/user_avata=
|
|
||||||
r/meta.discourse.org/codinghorror/45/5297.png" title=3D"codinghorror" style=
|
|
||||||
=3D"max-width:100%" width=3D"45" height=3D"45">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href=3D"https://meta.discourse.org/users/codinghorror" style=3D"=
|
|
||||||
text-decoration:none;font-weight:bold;color:#006699;font-size:13px;font-fam=
|
|
||||||
ily:'lucida grande',tahoma,verdana,arial,sans-serif;color:#3b5998;t=
|
|
||||||
ext-decoration:none;font-weight:bold" target=3D"_blank">codinghorror</a><br=
|
|
||||||
>
|
|
||||||
<span style=3D"text-align:right;color:#999999;padding-right:5px;fon=
|
|
||||||
t-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:=
|
|
||||||
11px">November 28</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style=3D"padding-top:5px" colspan=3D"2">
|
|
||||||
<p style=3D"margin-top:0;border:0">We're testing the latest GitHub emai=
|
|
||||||
l processing library which we are integrating now.</p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0"><a href=3D"https://github.com/github/ema=
|
|
||||||
il_reply_parser" style=3D"text-decoration:none;font-weight:bold;color:#0066=
|
|
||||||
99" target=3D"_blank">https://github.com/github/email_reply_parser</a></p>
|
|
||||||
|
|
||||||
<p style=3D"margin-top:0;border:0">Go ahead and reply to this topic and I&#=
|
|
||||||
39;ll reply from various email clients for testing.</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<hr style=3D"background-color:#ddd;min-height:1px;border:1px;background-col=
|
|
||||||
or:#ddd;min-height:1px;border:1px">
|
|
||||||
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To respond, reply to this email or visit <a href=3D"https://meta.discour=
|
|
||||||
se.org/t/testing-default-email-replies/22638/3" style=3D"text-decoration:no=
|
|
||||||
ne;font-weight:bold;color:#006699;color:#666" target=3D"_blank">https://met=
|
|
||||||
a.discourse.org/t/testing-default-email-replies/22638/3</a> in your browser=
|
|
||||||
.</p>
|
|
||||||
</div>
|
|
||||||
<div style=3D"color:#666">
|
|
||||||
<p>To unsubscribe from these emails, visit your <a href=3D"https://meta.dis=
|
|
||||||
course.org/my/preferences" style=3D"text-decoration:none;font-weight:bold;c=
|
|
||||||
olor:#006699;color:#666" target=3D"_blank">user preferences</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</blockquote></div>
|
|
||||||
|
|
||||||
--001a1137c9285318bb0508f17bc5--
|
|
||||||
|
|
11
spec/fixtures/emails/readonly.eml
vendored
Normal file
11
spec/fixtures/emails/readonly.eml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
Return-Path: <readonly@bar.com>
|
||||||
|
From: Foo Bar <readonly@bar.com>
|
||||||
|
To: category@bar.com
|
||||||
|
Subject: This is a topic from a restricted user
|
||||||
|
Date: Fri, 15 Jan 2016 00:12:43 +0100
|
||||||
|
Message-ID: <33@foo.bar.mail>
|
||||||
|
Mime-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
Hey, this is a topic from a restricted user ;)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue