Skip to content

Instantly share code, notes, and snippets.

@wasamasa
Last active February 4, 2023 10:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wasamasa/41a6c67623d8b80a8b697b91a65a5f5f to your computer and use it in GitHub Desktop.
Save wasamasa/41a6c67623d8b80a8b697b91a65a5f5f to your computer and use it in GitHub Desktop.
See the local timeline of any Mastodon instance
#!/usr/bin/env ruby
require 'json'
require 'http'
def api_request(instance, path, params)
uri = URI::HTTPS.build(host: instance, path: path,
query: URI.encode_www_form(params))
res = HTTP.headers(accept: 'application/json').get(uri)
raise("HTTP error #{res.status.to_i}") unless res.status.ok?
[res.headers, res.parse]
end
def proceed_Yn(prompt)
print("#{prompt} [Yn] ")
answer = STDIN.gets
return nil unless answer
answer.strip!
return true if answer.empty? || answer[/y/i]
end
def check_meta(instance)
_, meta = api_request(instance, '/api/v1/instance', {})
puts "Title: #{meta['title']}"
puts "Description: #{meta['short_description']}"
puts "Version: #{meta['version']}"
puts "Users: #{meta['stats']['user_count']}"
puts "Max chars: #{meta['max_toot_chars'] || 'unknown'}"
puts "Languages: #{meta['languages']}"
puts "Registrations: #{meta['registrations'] ? 'open' : 'closed'}"
puts "Admin: #{meta['contact_account']['url']}"
end
def find_next_link(header)
parts = header.split(', ')
part = parts.grep(/rel="next"/)[0]
return unless part
part[/<([^>]*>)/] && $1
end
def check_post(post)
puts "User: #{post['account']['url']}"
puts "Date: #{post['created_at']}"
puts "Content: #{post['content']}"
attachments = post['media_attachments']
puts "Media: #{attachments.map { |a| a['url'] }}" unless attachments.empty?
end
def check_posts(instance)
params = { 'local' => 'true', 'limit' => '10' }
loop do
headers, posts = api_request(instance, '/api/v1/timelines/public', params)
has_next_link = headers['Link'].include?('rel="next"')
posts.each { |p| check_post(p) }
puts
break unless has_next_link && proceed_Yn('Continue?')
params['max_id'] = posts[-1]['id']
end
end
def check(instance)
check_meta(instance)
puts
check_posts(instance)
end
def die(msg)
STDERR.puts(msg)
exit(1)
end
die("usage: #{$PROGRAM_NAME} <host>") unless ARGV.count == 1
check(ARGV[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment