diff options
Diffstat (limited to 'helpers.rb')
-rw-r--r-- | helpers.rb | 127 |
1 files changed, 81 insertions, 46 deletions
@@ -3,34 +3,6 @@ require 'English' helpers do - def curl(ext, url) - p url - response = `/run/current-system/sw/bin/curl --fail-with-body -sSL #{ext} #{url}` - if $CHILD_STATUS.success? - response - else - p response - nil - end - end - - def fetch(url, accept = 'application/activity+json') - uri = URI(url) - httpdate = Time.now.utc.httpdate - keypair = OpenSSL::PKey::RSA.new(File.read('private.pem')) - string = "(request-target): get #{uri.request_uri}\nhost: #{uri.host}\ndate: #{httpdate}" - signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), string)) - signed_header = "keyId=\"#{ACTOR}#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date\",signature=\"#{signature}\"" - - response = curl( - "-H 'Accept: #{accept}' -H 'Host: #{uri.host}' -H 'Date: #{httpdate}' -H 'Signature: #{signed_header}' ", url - ) - # response = curl("-H 'Accept: #{accept}'", url) - response ? JSON.parse(response) : nil - end - - # https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb - # , url def outbox(type, object, recipients, add_recipients = false) activity = { '@context' => 'https://www.w3.org/ns/activitystreams', @@ -43,16 +15,34 @@ helpers do date = now.strftime('%Y-%m-%dT%H:%M:%S.%N') httpdate = now.utc.httpdate basename = "#{date}.json" - activity['id'] = File.join(OUTBOX_URL, basename) + activity_rel_path = File.join(type.downcase, basename) + activity_path = File.join(OUTBOX_DIR, activity_rel_path) + activity['id'] = File.join(OUTBOX_URL, activity_rel_path) activity['published'] = httpdate + + # save object if activity['object'] && activity['object']['type'] && !activity['object']['id'] - rel_path = File.join activity['object']['type'].downcase, basename - activity['object']['published'] = httpdate - activity['object']['id'] = File.join(OUTBOX_URL, rel_path) - File.open(File.join(OUTBOX_DIR, rel_path), 'w+') { |f| f.puts activity.to_json } + + object = activity['object'] + object['@context'] = 'https://www.w3.org/ns/activitystreams' + object_rel_path = File.join activity['object']['type'].downcase, basename + object_path = File.join OUTBOX_DIR, object_rel_path + object['id'] = File.join OUTBOX_URL, object_rel_path + object['published'] = httpdate + FileUtils.mkdir_p File.dirname(object_path) + File.open(object_path, 'w+') { |f| f.puts object.to_json } end - File.open(File.join(OUTBOX_DIR, basename), 'w+') { |f| f.puts activity.to_json } + # save activity + FileUtils.mkdir_p File.dirname(activity_path) + File.open(activity_path, 'w+') { |f| f.puts activity.to_json } + update_collection OUTBOX, activity['id'] + # if type == 'Follow' + # jj activity + # update_collection FOLLO, activity['id'] + # end + # send + # https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb keypair = OpenSSL::PKey::RSA.new(File.read('private.pem')) body = activity.to_json sha256 = OpenSSL::Digest.new('SHA256') @@ -62,21 +52,17 @@ helpers do # put all recipients into 'to', avoid 'cc' 'bto' 'bcc' 'audience' !! activity['to'] = recipients if add_recipients inboxes = [] - # inboxes = if recipients.include? 'https://www.w3.org/ns/activitystreams#Public' - # people.collect { |p| p[2] }.uniq # cached sharedInboxes - # else - # [] - # end recipients.uniq.each do |url| next if [ACTOR, 'https://www.w3.org/ns/activitystreams#Public'].include? url - p 'FETCH', url actor = fetch url - p actor - next unless actor && actor['inbox'] + next unless actor - inbox = actor['endpoints']['sharedInbox'] - inboxes << (inbox || actor['inbox']) + if actor['endpoints'] and actor['endpoints']['sharedInbox'] + inboxes << actor['endpoints']['sharedInbox'] + elsif actor['inbox'] + inboxes << actor['inbox'] + end end inboxes.compact.uniq.each do |inbox| uri = URI(inbox) @@ -90,6 +76,55 @@ helpers do end end + def update_collection(path, objects, delete = false) + objects = [objects] unless objects.is_a? Array + File.open(path, 'r+') do |f| + f.flock(File::LOCK_EX) + json = f.read + collection = JSON.parse(json) + objects.each do |object| + if delete + collection['orderedItems'].delete_if { |o| o['id'] == object['id'] } + modified = true + else + ids = collection['orderedItems'].collect { |i| i['id'] } + collection['orderedItems'] << object unless ids.include?(object['id']) + modified = true + end + end + collection['totalItems'] = collection['orderedItems'].size + f.rewind + f.puts collection.to_json + f.truncate(f.pos) + end + end + + def fetch(url, accept = 'application/activity+json') + uri = URI(url) + httpdate = Time.now.utc.httpdate + keypair = OpenSSL::PKey::RSA.new(File.read('private.pem')) + string = "(request-target): get #{uri.request_uri}\nhost: #{uri.host}\ndate: #{httpdate}" + signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), string)) + signed_header = "keyId=\"#{ACTOR}#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date\",signature=\"#{signature}\"" + + response = curl( + "-H 'Accept: #{accept}' -H 'Host: #{uri.host}' -H 'Date: #{httpdate}' -H 'Signature: #{signed_header}' ", url + ) + # response = curl("-H 'Accept: #{accept}'", url) + response ? JSON.parse(response) : nil + end + + def curl(ext, url) + p url + response = `/run/current-system/sw/bin/curl --fail-with-body -sSL #{ext} #{url}` + if $CHILD_STATUS.success? + response + else + p response + nil + end + end + def mention(actor) person = people.select { |p| p[1] == actor } if person.empty? @@ -123,11 +158,11 @@ helpers do end def people - File.read('cache/people.tsv').split("\n").collect { |l| l.chomp.split("\t") } + File.read('private/people.tsv').split("\n").collect { |l| l.chomp.split("\t") } end def cache(mention, actor, a) sharedInbox = a['endpoints']['sharedInbox'] if a['endpoints'] && a['endpoints']['sharedInbox'] - File.open('cache/people.tsv', 'a') { |f| f.puts "#{mention}\t#{actor}\t#{sharedInbox}" } + File.open('private/people.tsv', 'a') { |f| f.puts "#{mention}\t#{actor}\t#{sharedInbox}" } end end |