Skip to content

Instantly share code, notes, and snippets.

@johnholdun
Created April 19, 2017 16:20
Show Gist options
  • Save johnholdun/13c2e1f237bf553f19e24840f041c354 to your computer and use it in GitHub Desktop.
Save johnholdun/13c2e1f237bf553f19e24840f041c354 to your computer and use it in GitHub Desktop.
Turn a Mastodon permalink URL into a one-line plain text status
require 'nokogiri'
require 'open-uri'
require 'upmark'
require 'cgi'
require 'uri'
class TootReader
ACTIVITY_NAMESPACE = 'http://activitystrea.ms/spec/1.0/'.freeze
COMMENT_TYPE = 'http://activitystrea.ms/schema/1.0/comment'.freeze
def initialize(url)
@url = url
end
def call
# Just call all these things so that if any of them goes wrong, we get a
# specific error. This is a bad pattern.
html_doc
atom_href
atom_doc
atom_type
@toot = read_toot
formatted_toot
end
def self.call(*args)
new(*args).call
end
private
attr_reader :url, :toot
def html_doc
@html_doc ||= Nokogiri::HTML open(url).read
rescue => e
raise "Could not open URL (#{e.class})"
end
def atom_href
@atom_href ||=
html_doc
.css('link[rel="alternate"][type="application/atom+xml"]')
.first['href']
rescue => e
raise "Could not find a related Atom document (#{e.class})"
end
def atom_doc
@atom_doc ||= Nokogiri::XML open(atom_href).read
rescue => e
raise "Could not load related Atom document (#{e.class})"
end
def atom_type
@atom_type ||=
atom_doc
.css('entry')
.xpath \
'activity:object-type',
'activity' => ACTIVITY_NAMESPACE
rescue => e
raise "Could not find activity:object-type in Atom document (#{e.class})"
end
def read_toot
unless atom_type && atom_type.text == COMMENT_TYPE
raise "Related Atom document is an unrecognized type (#{e.class})"
end
username = atom_doc.css('author name').text
author_uri = atom_doc.css('author uri').text
content = atom_doc.css('entry > content').first.text
{
username: username,
author_uri: author_uri,
content: content
}
end
def formatted_toot
full_username = "#{toot[:username]}@#{URI.parse(toot[:author_uri]).host}"
"#{full_username}: #{CGI.unescapeHTML(Upmark.convert(toot[:content]))}"
rescue => e
raise "Could not format toot (#{e.class})"
end
end
# ruby mastodon-parser.rb https://mastodon.social/@Gargron/3274547
begin
puts TootReader.call(ARGV.first)
rescue => e
puts e.message
exit(1)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment