diff options
-rw-r--r-- | activitypub.rb | 4 | ||||
-rw-r--r-- | client.rb | 47 | ||||
-rw-r--r-- | helpers.rb | 15 | ||||
-rwxr-xr-x | watch | 2 |
4 files changed, 50 insertions, 18 deletions
diff --git a/activitypub.rb b/activitypub.rb index 7416cca..5148a27 100644 --- a/activitypub.rb +++ b/activitypub.rb @@ -9,13 +9,14 @@ SOCIAL_DIR = '/srv/social/' PUBLIC_DIR = File.join(SOCIAL_DIR, 'public') PRIVATE_DIR = File.join(SOCIAL_DIR, 'private') OUTBOX_DIR = File.join(PUBLIC_DIR, 'outbox') +TAGS_DIR = File.join(PUBLIC_DIR, 'tags') INBOX = File.join(PRIVATE_DIR, 'inbox.json') FOLLOWERS = File.join(PUBLIC_DIR, 'followers.json') FOLLOWING = File.join(PUBLIC_DIR, 'following.json') OUTBOX = File.join(PUBLIC_DIR, 'outbox.json') SHARED = File.join(PUBLIC_DIR, 'shared.json') -VISITED = File.join(PRIVATE_DIR, 'visited') +# VISITED = File.join(PRIVATE_DIR, 'visited') USER = 'pdp8' SOCIAL_DOMAIN = 'social.pdp8.info' @@ -25,6 +26,7 @@ WEBFINGER = File.join(PUBLIC_DIR, MENTION + '.json') SOCIAL_URL = "https://#{SOCIAL_DOMAIN}" ACTOR = File.join(SOCIAL_URL, USER) OUTBOX_URL = File.join(SOCIAL_URL, 'outbox') +TAGS_URL = File.join(SOCIAL_URL, 'tags') CONTENT_TYPE = 'application/activity+json' # CONTENT_TYPE = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' @@ -29,13 +29,23 @@ post '/' do # TODO else tags = line.split(/\s+/).grep(/^#\w+$/) tags.each do |name| - href = File.join(SOCIAL_URL, 'tags', name.sub('#', '')) + # href = File.join(TAGS_URL, name.sub('#', '')) + tag_url = File.join(TAGS_URL, name.sub('#', '')) tag << { 'type' => 'Hashtag', - 'href' => href, + 'href' => tag_url, 'name' => name } - line.gsub!(name, "<a href='#{href}' class='mention hashtag' rel='tag'>#{name}</a>") + end + + mentions = line.split(/\s+/).grep(/^@\w+@\S+$/) + mentions.each do |mention| + actor = actor(mention) + tag << { + 'type' => 'Mention', + 'href' => actor, + 'name' => mention + } end content << line end @@ -51,7 +61,25 @@ post '/' do # TODO 'to' => recipients } - outbox 'Create', object, recipients, true + activity = outbox 'Create', object, recipients, true + activity['object']['tag'].each do |tag| + next unless tag['type'] == 'Hashtag' + + tag_path = File.join(TAGS_DIR, tag['name'].sub('#', '')) + '.json' + unless File.exist? tag_path + File.open(tag_path, 'w+') do |f| + tag_collection = { + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => tag['href'], + 'type' => 'OrderedCollection', + 'totalItems' => 0, + 'orderedItems' => [] + } + f.puts tag_collection.to_json + end + end + update_collection tag_path, activity['object']['id'] + end redirect(params['anchor'] || '/inbox') end @@ -88,8 +116,13 @@ end post '/share' do # TODO protected! - selection(params).each { |f| FileUtils.mv f, f.sub(%r{/inbox/}, '/shared/') } - outbox 'Announce', params['id'], public + inbox = JSON.parse File.read(INBOX) + object = inbox['orderedItems'].find { |i| i['id'] == params['id'] } + update_collection SHARED, object + update_collection INBOX, object, true + recipients = public + recipients << object['attributedTo'] + outbox 'Announce', params['id'], recipients redirect(params['anchor'] || '/inbox') end @@ -148,7 +181,7 @@ helpers do mention = follow when /^http/ actor = follow - mention = mention actor + mention = mention(actor) when /^@*\w+@\w+/ mention = follow actor = actor(follow) @@ -19,6 +19,9 @@ helpers do activity_path = File.join(OUTBOX_DIR, activity_rel_path) activity['id'] = File.join(OUTBOX_URL, activity_rel_path) activity['published'] = httpdate + # assumes that recipient collections have been expanded by sender + # put all recipients into 'to', avoid 'cc' 'bto' 'bcc' 'audience' !! + activity['to'] = recipients if add_recipients # save object if activity['object'] && activity['object']['type'] && !activity['object']['id'] @@ -35,11 +38,7 @@ helpers do # 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 + update_collection OUTBOX, activity['id'] if %w[Create Announce].include?(type) # send # https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb @@ -48,9 +47,6 @@ helpers do sha256 = OpenSSL::Digest.new('SHA256') digest = "SHA-256=#{sha256.base64digest(body)}" - # assumes that recipient collections have been expanded by sender - # put all recipients into 'to', avoid 'cc' 'bto' 'bcc' 'audience' !! - activity['to'] = recipients if add_recipients inboxes = [] recipients.uniq.each do |url| next if [ACTOR, 'https://www.w3.org/ns/activitystreams#Public'].include? url @@ -74,6 +70,7 @@ helpers do "-X POST -H 'Content-Type: application/activity+json' -H 'Host: #{uri.host}' -H 'Date: #{httpdate}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}'", inbox ) end + activity end def update_collection(path, objects, delete = false) @@ -109,12 +106,12 @@ helpers do 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 + # p "/run/current-system/sw/bin/curl --fail-with-body -sSL #{ext} #{url}" response = `/run/current-system/sw/bin/curl --fail-with-body -sSL #{ext} #{url}` if $CHILD_STATUS.success? response @@ -1,5 +1,5 @@ #!/bin/sh while inotifywait -qq -r ./ -e create,delete,modify; do - rsync -a --exclude='.git/' --exclude='watch' --filter=":- .gitignore" ./ /srv/social/ + rsync -a --exclude='.git/' --exclude='watch' --exclude='generate-digest.rb' --exclude='.gitignore' --exclude='TODO' --filter=":- .gitignore" ./ /srv/social/ sudo systemctl restart social.service done |