xrforge/manyfold/root/hook.d/experience_updated/500-mastodon-post.rb

93 lines
2.5 KiB
Ruby
Executable file

#!/usr/bin/env ruby
require 'rss'
require 'json'
require 'open-uri'
require 'cgi'
require_relative './../../xrforge.rb'
# Check if a filename is provided
if ARGV.length != 1
puts "Usage: #{$0} <path/to/experience/somefile.xxx>"
exit 1
end
filename = ARGV[0]
# dont run for each file-update
if ! filename.end_with?("datapackage.json")
exit 0
end
begin
# Change the directory
dir = File.dirname(filename)
Dir.chdir( dir )
# Read and parse the JSON file
data = JSON.parse( File.read( "datapackage.json" ) )
APHandle = false
data['keywords'].any? do |tag|
if tag.match?(/@.*@.*\./) # scan for activitypub handle (@foo@mastodon.online e.g.)
APHandle = tag
end
end
if ! APHandle # nothing to do
exit 0
end
logfile = File.join( File.dirname(filename), ".xrforge/log.txt" )
XRForge.log("✅ starting Mastodon post2image", logfile)
parts = APHandle.split("@")
server = parts[2].sub(/@/,"")
rssUrl = "https://#{server}/@#{parts[1]}.rss"
XRForge.log("✅ checking #{rssUrl}", logfile)
feed = RSS::Parser.parse(URI.open(rssUrl, 'User-Agent' => 'Ruby-RSS-Client'))
puts feed.channel.title
puts feed.channel.link
first_item = feed.items.first
if first_item
description = CGI.unescapeHTML(first_item.description.to_s)
.split("\n")[0,4].join("\n") # max 5 lines
.gsub(/<[^>]*>/, '') # remove other tags
#.gsub(/<br\s*\/?>/i, "\n") # preserve linebreaks
#.gsub(/<\/p>/i, "\n") # preserve linebreaks
description = description.length > 130 ? description = description[0,130] + " (..)" : description
else
XRForge.log("❌ did not find post", logfile)
exit 0
end
puts description
# look for first image
MEDIA_REGEX = /<media:content url=['"]([^'"]+)['"]/
img = feed.to_s.match(MEDIA_REGEX)
if img and img[1] and img[1].match(/(png|jpg)/)
imgurl = img[1]
end
# generate the final .glb
system("/root/templates/mastodon-post/mastodon-post.sh", description, feed.channel.title, feed.channel.link, APHandle, "#{dir}/mastodon-post.glb")
XRForge.log(" ", logfile)
rescue OpenURI::HTTPError => e
# Handle HTTP errors (e.g., 404 not found, 403 forbidden)
puts "Error fetching feed: #{e.message}"
exit
rescue => e
# Handle other parsing or connection errors
puts "An error occurred: #{e.message}"
rescue Errno::ENOENT
puts "File #{filename} not found"
rescue JSON::ParserError
puts "Error parsing JSON from #{filename}"
rescue => e
puts "An error occurred: #{e.message}"
end