Add DiasporaUrlParser to extract diaspora:// URLs from texts
This commit is contained in:
parent
457f06d1da
commit
0b927290e3
3 changed files with 98 additions and 0 deletions
|
|
@ -4,6 +4,7 @@ module DiasporaFederation
|
|||
end
|
||||
end
|
||||
|
||||
require "diaspora_federation/federation/diaspora_url_parser"
|
||||
require "diaspora_federation/federation/fetcher"
|
||||
require "diaspora_federation/federation/receiver"
|
||||
require "diaspora_federation/federation/sender"
|
||||
|
|
|
|||
29
lib/diaspora_federation/federation/diaspora_url_parser.rb
Normal file
29
lib/diaspora_federation/federation/diaspora_url_parser.rb
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
module DiasporaFederation
|
||||
module Federation
|
||||
# This module is for parsing and fetching linked entities.
|
||||
module DiasporaUrlParser
|
||||
include Logging
|
||||
|
||||
# Regex to find diaspora:// URLs
|
||||
DIASPORA_URL_REGEX = %r{diaspora://(#{Entity::ENTITY_NAME_REGEX})/(#{Validation::Rule::Guid::VALID_CHARS})}
|
||||
|
||||
# Parses all diaspora:// URLs from the text and fetches the entities from
|
||||
# the remote server if needed.
|
||||
# @param [String] sender the diaspora* ID of the sender of the entity
|
||||
# @param [String] text text with diaspora:// URLs to fetch
|
||||
def self.fetch_linked_entities(sender, text)
|
||||
text.scan(DIASPORA_URL_REGEX).each do |type, guid|
|
||||
fetch_entity(sender, type, guid)
|
||||
end
|
||||
end
|
||||
|
||||
private_class_method def self.fetch_entity(sender, type, guid)
|
||||
class_name = Entity.entity_class(type).to_s.rpartition("::").last
|
||||
return if DiasporaFederation.callbacks.trigger(:fetch_related_entity, class_name, guid)
|
||||
Fetcher.fetch_public(sender, type, guid)
|
||||
rescue => e
|
||||
logger.error "Failed to fetch linked entity #{type}:#{guid}: #{e.class}: #{e.message}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
module DiasporaFederation
|
||||
describe Federation::DiasporaUrlParser do
|
||||
let(:sender) { Fabricate.sequence(:diaspora_id) }
|
||||
let(:guid) { Fabricate.sequence(:guid) }
|
||||
|
||||
describe ".fetch_linked_entities" do
|
||||
it "parses linked posts from the text" do
|
||||
guid2 = Fabricate.sequence(:guid)
|
||||
guid3 = Fabricate.sequence(:guid)
|
||||
expect_callback(:fetch_related_entity, "Post", guid).and_return(double)
|
||||
expect_callback(:fetch_related_entity, "Post", guid2).and_return(double)
|
||||
expect_callback(:fetch_related_entity, "Post", guid3).and_return(double)
|
||||
|
||||
text = "This is a [link to a post with markdown](diaspora://post/#{guid}) and one without " \
|
||||
"diaspora://post/#{guid2} and finally a last one diaspora://post/#{guid3}."
|
||||
|
||||
Federation::DiasporaUrlParser.fetch_linked_entities(sender, text)
|
||||
end
|
||||
|
||||
it "ignores invalid diaspora:// urls" do
|
||||
expect(DiasporaFederation.callbacks).not_to receive(:trigger)
|
||||
|
||||
text = "This is an invalid link diaspora://Post/#{guid}) and another one: " \
|
||||
"diaspora://post/abcd."
|
||||
|
||||
Federation::DiasporaUrlParser.fetch_linked_entities(sender, text)
|
||||
end
|
||||
|
||||
it "allows to link other entities" do
|
||||
expect_callback(:fetch_related_entity, "Event", guid).and_return(double)
|
||||
|
||||
text = "This is a link to an event diaspora://event/#{guid}."
|
||||
|
||||
Federation::DiasporaUrlParser.fetch_linked_entities(sender, text)
|
||||
end
|
||||
|
||||
it "handles unknown entities gracefully" do
|
||||
expect(DiasporaFederation.callbacks).not_to receive(:trigger)
|
||||
|
||||
text = "This is a link to an event diaspora://unknown/#{guid}."
|
||||
|
||||
Federation::DiasporaUrlParser.fetch_linked_entities(sender, text)
|
||||
end
|
||||
|
||||
it "fetches entities from sender when not found locally" do
|
||||
expect_callback(:fetch_related_entity, "Post", guid).and_return(nil)
|
||||
expect(Federation::Fetcher).to receive(:fetch_public).with(sender, "post", guid)
|
||||
|
||||
text = "This is a link to a post: diaspora://post/#{guid}."
|
||||
|
||||
Federation::DiasporaUrlParser.fetch_linked_entities(sender, text)
|
||||
end
|
||||
|
||||
it "handles fetch errors gracefully" do
|
||||
expect_callback(:fetch_related_entity, "Post", guid).and_return(nil)
|
||||
expect(Federation::Fetcher).to receive(:fetch_public).with(
|
||||
sender, "post", guid
|
||||
).and_raise(Federation::Fetcher::NotFetchable, "Something went wrong!")
|
||||
|
||||
text = "This is a link to a post: diaspora://post/#{guid}."
|
||||
|
||||
expect {
|
||||
Federation::DiasporaUrlParser.fetch_linked_entities(sender, text)
|
||||
}.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue