mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
Add custom embed_by_username feature
Feature to allow each imported post to be created using a different discourse username. A possible use case of this is a multi-author blog where discourse is being used to track comments. This feature allows authors to receive updates when someone leaves a comment on one of their articles because each of the imported posts can be created using the discourse username of the author.
This commit is contained in:
parent
8e882ad145
commit
a78df3d57d
8 changed files with 184 additions and 65 deletions
|
@ -13,8 +13,7 @@ module Jobs
|
|||
if args[:user_id]
|
||||
user = User.find_by(id: args[:user_id])
|
||||
end
|
||||
|
||||
TopicRetriever.new(args[:embed_url], no_throttle: user.try(:staff?)).retrieve
|
||||
TopicRetriever.new(args[:embed_url], author_username: args[:author_username], no_throttle: user.try(:staff?)).retrieve
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -14,8 +14,7 @@ module Jobs
|
|||
|
||||
def execute(args)
|
||||
poll_feed if SiteSetting.feed_polling_enabled? &&
|
||||
SiteSetting.feed_polling_url.present? &&
|
||||
SiteSetting.embed_by_username.present?
|
||||
SiteSetting.feed_polling_url.present?
|
||||
end
|
||||
|
||||
def feed_key
|
||||
|
@ -23,22 +22,111 @@ module Jobs
|
|||
end
|
||||
|
||||
def poll_feed
|
||||
user = User.find_by(username_lower: SiteSetting.embed_by_username.downcase)
|
||||
return if user.blank?
|
||||
feed = Feed.new
|
||||
import_topics(feed.topics)
|
||||
end
|
||||
|
||||
require 'simple-rss'
|
||||
rss = SimpleRSS.parse open(SiteSetting.feed_polling_url)
|
||||
private
|
||||
|
||||
rss.items.each do |i|
|
||||
url = i.link
|
||||
url = i.id if url.blank? || url !~ /^https?\:\/\//
|
||||
|
||||
content = i.content || i.description
|
||||
if content
|
||||
TopicEmbed.import(user, url, i.title, CGI.unescapeHTML(content.scrub))
|
||||
end
|
||||
def import_topics(feed_topics)
|
||||
feed_topics.each do |topic|
|
||||
import_topic(topic)
|
||||
end
|
||||
end
|
||||
|
||||
def import_topic(topic)
|
||||
if topic.user
|
||||
TopicEmbed.import(topic.user, topic.url, topic.title, CGI.unescapeHTML(topic.content.scrub))
|
||||
end
|
||||
end
|
||||
|
||||
class Feed
|
||||
require 'simple-rss'
|
||||
SimpleRSS.item_tags << SiteSetting.embed_username_key_from_feed.to_sym
|
||||
|
||||
def initialize
|
||||
@feed_url = SiteSetting.feed_polling_url
|
||||
end
|
||||
|
||||
def topics
|
||||
feed_topics = []
|
||||
|
||||
rss.items.each do |i|
|
||||
current_feed_topic = FeedTopic.new(i)
|
||||
feed_topics << current_feed_topic if current_feed_topic.content
|
||||
end
|
||||
|
||||
return feed_topics
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rss
|
||||
SimpleRSS.parse open(@feed_url)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class FeedTopic
|
||||
def initialize(article_rss_item)
|
||||
@article_rss_item = article_rss_item
|
||||
end
|
||||
|
||||
def url
|
||||
link = @article_rss_item.link
|
||||
if url?(link)
|
||||
return link
|
||||
else
|
||||
return @article_rss_item.id
|
||||
end
|
||||
end
|
||||
|
||||
def content
|
||||
@article_rss_item.content || @article_rss_item.description
|
||||
end
|
||||
|
||||
def title
|
||||
@article_rss_item.title
|
||||
end
|
||||
|
||||
def user
|
||||
author_user || default_user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def url?(link)
|
||||
if link.blank? || link !~ /^https?\:\/\//
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
def author_username
|
||||
begin
|
||||
@article_rss_item.send(SiteSetting.embed_username_key_from_feed.to_sym)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def default_user
|
||||
find_user(SiteSetting.embed_by_username.downcase)
|
||||
end
|
||||
|
||||
def author_user
|
||||
return nil if !author_username.present?
|
||||
|
||||
find_user(author_username)
|
||||
end
|
||||
|
||||
def find_user(user_name)
|
||||
User.where(username_lower: user_name).first
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -899,6 +899,7 @@ en:
|
|||
feed_polling_enabled: "Whether to import a RSS/ATOM feed as posts"
|
||||
feed_polling_url: "URL of RSS/ATOM feed to import"
|
||||
embed_by_username: "Discourse username of the user who creates the topics"
|
||||
embed_username_key_from_feed: "Key to pull discourse username from feed"
|
||||
embed_truncate: "Truncate the imported posts"
|
||||
embed_category: "Category of created topics"
|
||||
embed_post_limit: "Maximum number of posts to embed"
|
||||
|
|
|
@ -469,6 +469,7 @@ embedding:
|
|||
feed_polling_enabled: false
|
||||
feed_polling_url: ''
|
||||
embed_by_username: ''
|
||||
embed_username_key_from_feed: ''
|
||||
embed_category: ''
|
||||
embed_post_limit: 100
|
||||
embed_truncate: false
|
||||
|
|
|
@ -2,6 +2,7 @@ class TopicRetriever
|
|||
|
||||
def initialize(embed_url, opts=nil)
|
||||
@embed_url = embed_url
|
||||
@author_username = opts[:author_username]
|
||||
@opts = opts || {}
|
||||
end
|
||||
|
||||
|
@ -46,7 +47,13 @@ class TopicRetriever
|
|||
end
|
||||
|
||||
def fetch_http
|
||||
user = User.find_by(username_lower: SiteSetting.embed_by_username.downcase)
|
||||
if @author_username.nil?
|
||||
username = SiteSetting.embed_by_username.downcase
|
||||
else
|
||||
username = @author_username
|
||||
end
|
||||
|
||||
user = User.where(username_lower: username.downcase).first
|
||||
return if user.blank?
|
||||
|
||||
TopicEmbed.import_remote(user, @embed_url)
|
||||
|
|
|
@ -1,10 +1,24 @@
|
|||
/* global discourseUrl */
|
||||
/* global discourseUserName */
|
||||
/* global discourseEmbedUrl */
|
||||
(function() {
|
||||
|
||||
var comments = document.getElementById('discourse-comments'),
|
||||
iframe = document.createElement('iframe');
|
||||
iframe.src = discourseUrl + "embed/comments?embed_url=" + encodeURIComponent(discourseEmbedUrl);
|
||||
iframe = document.createElement('iframe');
|
||||
if (typeof discourseUserName === 'undefined') {
|
||||
iframe.src =
|
||||
[ discourseUrl,
|
||||
'embed/comments?embed_url=',
|
||||
encodeURIComponent(discourseEmbedUrl)
|
||||
].join('');
|
||||
} else {
|
||||
iframe.src =
|
||||
[ discourseUrl,
|
||||
'embed/comments?embed_url=',
|
||||
encodeURIComponent(discourseEmbedUrl),
|
||||
'&discourse_username=',
|
||||
discourseUserName
|
||||
].join('');
|
||||
}
|
||||
iframe.id = 'discourse-embed-frame';
|
||||
iframe.width = "100%";
|
||||
iframe.frameBorder = "0";
|
||||
|
|
|
@ -4,43 +4,59 @@ require_dependency 'topic_retriever'
|
|||
describe TopicRetriever do
|
||||
|
||||
let(:embed_url) { "http://eviltrout.com/2013/02/10/why-discourse-uses-emberjs.html" }
|
||||
let(:topic_retriever) { TopicRetriever.new(embed_url) }
|
||||
let(:author_username) { "eviltrout" }
|
||||
let(:topic_retriever) { TopicRetriever.new(embed_url, author_username: author_username) }
|
||||
|
||||
it "does not call perform_retrieve when embeddable_host is not set" do
|
||||
SiteSetting.stubs(:embeddable_host).returns(nil)
|
||||
topic_retriever.expects(:perform_retrieve).never
|
||||
topic_retriever.retrieve
|
||||
end
|
||||
describe "#retrieve" do
|
||||
context "when host is invalid" do
|
||||
before do
|
||||
topic_retriever.stubs(:invalid_host?).returns(true)
|
||||
end
|
||||
|
||||
it "does not call perform_retrieve when embeddable_host is different than the host of the URL" do
|
||||
SiteSetting.stubs(:embeddable_host).returns("eviltuna.com")
|
||||
topic_retriever.expects(:perform_retrieve).never
|
||||
topic_retriever.retrieve
|
||||
end
|
||||
|
||||
it "does not call perform_retrieve when the embed url is not a url" do
|
||||
r = TopicRetriever.new("not a url")
|
||||
r.expects(:perform_retrieve).never
|
||||
r.retrieve
|
||||
end
|
||||
|
||||
context "with a valid host" do
|
||||
before do
|
||||
SiteSetting.stubs(:embeddable_host).returns("eviltrout.com")
|
||||
it "does not perform_retrieve" do
|
||||
topic_retriever.expects(:perform_retrieve).never
|
||||
topic_retriever.retrieve
|
||||
end
|
||||
end
|
||||
|
||||
it "calls perform_retrieve if it hasn't been retrieved recently" do
|
||||
topic_retriever.expects(:perform_retrieve).once
|
||||
topic_retriever.expects(:retrieved_recently?).returns(false)
|
||||
topic_retriever.retrieve
|
||||
context "when topics have been retrieived recently" do
|
||||
before do
|
||||
topic_retriever.stubs(:retrieved_recently?).returns(true)
|
||||
end
|
||||
|
||||
it "does not perform_retrieve" do
|
||||
topic_retriever.expects(:perform_retrieve).never
|
||||
topic_retriever.retrieve
|
||||
end
|
||||
end
|
||||
|
||||
it "doesn't call perform_retrieve if it's been retrieved recently" do
|
||||
topic_retriever.expects(:perform_retrieve).never
|
||||
topic_retriever.expects(:retrieved_recently?).returns(true)
|
||||
topic_retriever.retrieve
|
||||
end
|
||||
context "when host is not invalid" do
|
||||
before do
|
||||
topic_retriever.stubs(:invalid_host?).returns(false)
|
||||
end
|
||||
|
||||
context "when topics have been retrieived recently" do
|
||||
before do
|
||||
topic_retriever.stubs(:retrieved_recently?).returns(true)
|
||||
end
|
||||
|
||||
it "does not perform_retrieve" do
|
||||
topic_retriever.expects(:perform_retrieve).never
|
||||
topic_retriever.retrieve
|
||||
end
|
||||
end
|
||||
|
||||
context "when topics have not been retrieived recently" do
|
||||
before do
|
||||
topic_retriever.stubs(:retrieved_recently?).returns(false)
|
||||
end
|
||||
|
||||
it "does perform_retrieve" do
|
||||
topic_retriever.expects(:perform_retrieve).once
|
||||
topic_retriever.retrieve
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -2,7 +2,6 @@ require 'spec_helper'
|
|||
require_dependency 'jobs/regular/process_post'
|
||||
|
||||
describe Jobs::PollFeed do
|
||||
|
||||
let(:poller) { Jobs::PollFeed.new }
|
||||
|
||||
context "execute" do
|
||||
|
@ -10,28 +9,22 @@ describe Jobs::PollFeed do
|
|||
let(:embed_by_username) { "eviltrout" }
|
||||
|
||||
it "requires feed_polling_enabled?" do
|
||||
SiteSetting.stubs(:feed_polling_enabled?).returns(false)
|
||||
poller.expects(:poll_feed).never
|
||||
poller.execute({})
|
||||
SiteSetting.stubs(:feed_polling_enabled?).returns(true)
|
||||
SiteSetting.stubs(:feed_polling_url).returns(nil)
|
||||
poller.expects(:poll_feed).never
|
||||
poller.execute({})
|
||||
end
|
||||
|
||||
it "requires feed_polling_url" do
|
||||
SiteSetting.stubs(:feed_polling_url).returns(nil)
|
||||
poller.expects(:poll_feed).never
|
||||
poller.execute({})
|
||||
SiteSetting.stubs(:feed_polling_enabled?).returns(false)
|
||||
SiteSetting.stubs(:feed_polling_url).returns(nil)
|
||||
poller.expects(:poll_feed).never
|
||||
poller.execute({})
|
||||
end
|
||||
|
||||
it "requires embed_by_username" do
|
||||
SiteSetting.stubs(:embed_by_username).returns(nil)
|
||||
poller.expects(:poll_feed).never
|
||||
poller.execute({})
|
||||
end
|
||||
|
||||
|
||||
it "delegates to poll_feed" do
|
||||
SiteSetting.stubs(:feed_polling_enabled?).returns(true)
|
||||
SiteSetting.stubs(:feed_polling_url).returns(url)
|
||||
SiteSetting.stubs(:embed_by_username).returns(embed_by_username)
|
||||
poller.expects(:poll_feed).once
|
||||
poller.execute({})
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue