diff options
-rw-r--r-- | client.rb | 2 | ||||
-rw-r--r-- | create.rb | 33 | ||||
-rw-r--r-- | helpers.rb | 40 | ||||
-rw-r--r-- | server.rb | 27 |
4 files changed, 59 insertions, 43 deletions
@@ -53,7 +53,7 @@ post '/unfollow' do params['id'] = actor params['mention'] if params['mention'] following = Dir[File.join(OUTBOX[:dir], 'follow', '*.json')].collect { |f| JSON.parse(File.read(f)) } activity = following.find { |a| a['object'] == params['id'] } - activity ||= save_activity({ 'type' => 'Follow', 'actor' => ACTOR, 'object' => params['id'] }, OUTBOX) # recreate activity for old/deleted follows + # activity ||= save_activity({ 'type' => 'Follow', 'actor' => ACTOR, 'object' => params['id'] }, OUTBOX) # recreate activity for old/deleted follows outbox 'Undo', activity, [params['id']] update_collection FOLLOWING, params['id'], true 200 @@ -33,11 +33,14 @@ post '/create' do # TODO elsif line.match(/\A==\Z/) attachment = lines[i + 1..-1].collect do |url| url.chomp! - { + url, name = url.split(/\s+/, 2) + doc = { 'type' => 'Document', 'mediaType' => media_type(url), 'url' => url } + doc['name'] = name if name + doc end break else @@ -70,41 +73,19 @@ post '/create' do # TODO content << line end end + content.shift while content[0] == '<p>' object = { 'to' => to, 'type' => 'Note', 'attributedTo' => ACTOR, - 'content' => "#{content.join("\n")}" + 'content' => "#{content.join(' ')}" } object['inReplyTo'] = inReplyTo unless inReplyTo.empty? object['attachment'] = attachment unless attachment.empty? object['tag'] = tag unless tag.empty? - activity = outbox 'Create', object, to + outbox 'Create', object, to - if activity['object']['tag'] - activity['object']['tag'].each do |tag| - next unless tag['type'] == 'Hashtag' - - tag_path = File.join(TAGS[:dir], tag['name'].sub('#', '')) + '.json' - tag_collection = if File.exist? tag_path - JSON.parse(File.read(tag_path)) - else - { - '@context' => 'https://www.w3.org/ns/activitystreams', - 'id' => tag['href'], - 'type' => 'OrderedCollection', - 'totalItems' => 0, - 'orderedItems' => [] - } - end - tag_collection['orderedItems'] << activity['object']['id'] - tag_collection['totalItems'] = tag_collection['orderedItems'].size - File.open(tag_path, 'w+') do |f| - f.puts tag_collection.to_json - end - end - end 200 end @@ -21,13 +21,18 @@ helpers do # save activity FileUtils.mkdir_p File.dirname(activity_path) File.open(activity_path, 'w+') { |f| f.puts activity.to_json } - activity + activity_path end def save_object(object, box) object = fetch(object) if object.is_a? String and object.match(/^http/) return unless object # and object['type'] != 'Person' + unless object['attributedTo'] + jj object + return + end + object['@context'] = 'https://www.w3.org/ns/activitystreams' basename = "#{object['published']}_#{mention(object['attributedTo'])}.json" object_rel_path = File.join 'object', object['type'].downcase, basename @@ -35,6 +40,29 @@ helpers do object_path = File.join box[:dir], object_rel_path FileUtils.mkdir_p File.dirname(object_path) File.open(object_path, 'w+') { |f| f.puts object.to_json } + if box == OUTBOX and object['tag'] + object['tag'].each do |tag| + next unless tag['type'] == 'Hashtag' + + tag_path = File.join(TAGS[:dir], tag['name'].sub('#', '')) + '.json' + tag_collection = if File.exist? tag_path + JSON.parse(File.read(tag_path)) + else + { + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => tag['href'], + 'type' => 'OrderedCollection', + 'totalItems' => 0, + 'orderedItems' => [] + } + end + tag_collection['orderedItems'] << object['id'] + tag_collection['totalItems'] = tag_collection['orderedItems'].size + File.open(tag_path, 'w+') do |f| + f.puts tag_collection.to_json + end + end + end object end @@ -61,7 +89,13 @@ helpers do end def fetch(url, accept = 'application/activity+json') - uri = URI(url) + begin + uri = URI(url) + rescue StandardError => e + p url + p e + return nil + end 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}" @@ -74,11 +108,11 @@ helpers do end def curl(ext, url) - p url response = `/run/current-system/sw/bin/curl -H 'Content-Type: #{CONTENT_TYPE}' -H 'Accept: #{CONTENT_TYPE}' --fail-with-body -sSL #{ext} #{url}` if $CHILD_STATUS.success? response else + p url p response nil end @@ -16,7 +16,7 @@ post '/inbox' do type = @activity['type'].downcase.to_sym save_activity(@activity, INBOX) unless %i[create announce].include? type send(type) if %i[create announce follow accept undo].include? type - halt 200 + 200 end # public @@ -88,7 +88,7 @@ helpers do update_collection FOLLOWERS, @activity['object']['actor'], true when 'Create', 'Announce' file = find_file @activity['object']['id'] - FileUtils.rm(file) if File.exist? file + FileUtils.rm(file) if file else halt 501 end @@ -164,15 +164,16 @@ helpers do end # add date and id, save - activity = save_activity({ - '@context' => 'https://www.w3.org/ns/activitystreams', - 'type' => type, - 'actor' => ACTOR, - 'object' => object, - 'to' => to - }, OUTBOX) - - body = activity.to_json + activity_path = save_activity({ + '@context' => 'https://www.w3.org/ns/activitystreams', + 'type' => type, + 'actor' => ACTOR, + 'object' => object, + 'to' => to + }, OUTBOX) + + # p activity_path + body = File.read(activity_path) sha256 = OpenSSL::Digest.new('SHA256') digest = "SHA-256=#{sha256.base64digest(body)}" keypair = OpenSSL::PKey::RSA.new(File.read('private.pem')) @@ -186,9 +187,9 @@ helpers do # Net::HTTP fails with OpenSSL error curl( - "-X POST -H 'Host: #{uri.host}' -H 'Date: #{httpdate}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' --data-raw '#{body}'", inbox + "-X POST -H 'Host: #{uri.host}' -H 'Date: #{httpdate}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' --data-binary '@#{activity_path}'", inbox ) end - activity + activity_path end end |