summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--application.rb123
-rw-r--r--config.ru2
2 files changed, 93 insertions, 32 deletions
diff --git a/application.rb b/application.rb
index fe84d61..c8a657c 100644
--- a/application.rb
+++ b/application.rb
@@ -1,8 +1,10 @@
# TODO
-# run as service
+# unwrap and save object from create
+# boost
+# archive
+# threads
# federation
# client post media
-# client get media
# test with pleroma etc
require 'json'
require 'net/http'
@@ -41,6 +43,7 @@ class Application
case object["type"]
when "Create"
File.open(File.join("inbox", SecureRandom.uuid + ".json"), "w+") { |f| f.puts input }
+ # File.open(File.join("inbox", input["published"] + ".json"), "w+") { |f| f.puts input["object"] }
when "Delete"
puts input
when "Follow"
@@ -53,19 +56,16 @@ class Application
send accept, [accept["object"]["actor"]]
when "Undo"
o = object["object"]
- # puts o
case o["type"]
when "Follow"
Dir["followers/*.json"].each do |follower|
- puts follower
- # puts JSON.parse(File.read(follower))["actor"]
if JSON.parse(File.read(follower))["actor"] == o["actor"]
FileUtils.rm follower
end
end
- # ordered_collection("followers")
+ else
+ puts input
end
- # puts input
else
puts input
end
@@ -80,6 +80,12 @@ class Application
response = "Key verification failed for POST to #{env["REQUEST_URI"]}."
end
+ when %r{/delete} # receive from client
+ if auth(env)
+ FileUtils.rm env["REQUEST_URI"].sub("/delete/", "")
+ return [302, { "Location" => "/inbox" }, []]
+ end
+
when "/outbox" # receive from client
if auth(env)
code, response = parse input
@@ -144,7 +150,13 @@ class Application
when "/inbox"
if auth(env)
- type, response = format ordered_collection(env["REQUEST_PATH"]), env["HTTP_ACCEPT"]
+ case env["HTTP_ACCEPT"]
+ when /json/
+ response = ordered_collection(env["REQUEST_PATH"]).to_json
+ else
+ type = "text/html"
+ response = html env["REQUEST_PATH"]
+ end
code = 200
else
code = 403
@@ -160,6 +172,76 @@ class Application
[code, { "Content-Type" => type }, [response]]
end
+ def html path
+ html = "<!DOCTYPE html>\n<html lang='en'>\n\t<body>"
+ Dir[File.join(path.sub(/^\//, ''), "*")].sort_by { |f| File.stat(f).ctime }.each do |file|
+ item = JSON.parse(File.read(file))
+ html << "\n\t\t<b>#{mention item["actor"]}</b>&nbsp;<i>#{item["object"]["published"].sub("T",
+ " ")}</i><p>#{item["object"]["content"]}"
+ if item["object"]["attachment"]
+ item["object"]["attachment"].each do |att|
+ case att["mediaType"]
+ when /audio/
+ html << "\n<br><audio controls=''><source src='#{att["url"]}' type='#{att["mediaType"]}'></audio>"
+ when /image/
+ html << "\n<br><a href='#{att["url"]}'><img src='#{att["url"]}'></a>"
+ when /video/
+ html << "\n<br><video controls=''><source src='#{att["url"]}' type='#{att["mediaType"]}'></video>"
+ else
+ html << att + "<br>"
+ html << "\n<a href='#{att["url"]}'>#{att["url"]}</a>"
+ end
+ end
+ end
+ html << "<p>
+ <form action='#{File.join "delete", file}' method='post'>
+ <button>Delete</button>
+ </form>
+ <form action='#{File.join "boost", file}' method='post'>
+ <button>Boost</button>
+ </form>
+ <form action='#{File.join "archive", file}' method='post'>
+ <button>Archive</button>
+ </form>
+ <form action='#{File.join "reply", file}' method='post'>
+ <button>Reply</button>
+ </form>
+ <hr>"
+ end
+ html << "\n\t</body>\n</html>"
+ end
+=begin
+=end
+
+=begin
+ def html o
+ html = "<!DOCTYPE html>
+<html lang='en'>
+ <body>
+ <b>#{mention o["actor"]}</b>&nbsp;<i>#{o["object"]["published"]}</i>
+ <p>#{o["object"]["content"]}
+ "
+ if o["object"]["attachment"]
+ o["object"]["attachment"].each do |att|
+ case att["mediaType"]
+ when /audio/
+ html<< "\n<br><audio controls=''><source src='#{att["url"]}' type='#{att["mediaType"]}'></audio>"
+ when /image/
+ html << "\n<br><a href='#{att["url"]}'><img src='#{att["url"]}'></a>"
+ when /video/
+ html<< "\n<br><video controls=''><source src='#{att["url"]}' type='#{att["mediaType"]}'></video>"
+ else
+ html<< att + "<br>"
+ html << "\n<a href='#{att["url"]}'>#{att["url"]}</a>"
+ end
+ end
+ end
+ end
+ html << "\n\t</body>\n</html>"
+ html
+ end
+=end
+
def parse input
date = Time.now.strftime("%Y-%m-%dT%H:%M:%S")
# TODO media attachments, hashtags
@@ -210,25 +292,6 @@ class Application
[code, response]
end
- def format response, accept
- if accept == "text/plain"
- response = response["orderedItems"].collect.with_index do |r, i|
- object = r["object"]
- doc = Nokogiri::HTML(object["content"])
- str = "#{i}\t#{object["published"]}\t#{mention r["actor"]}\n\n#{doc.text}"
- str << "\n" + object["attachment"].collect { |att|
- `kitty +kitten icat #{att["url"]}`
- }.join("\n") if object["attachment"]
- str
- end.join("\n\n")
- type = "text/plain"
- else
- response = response.to_json
- type = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
- end
- [type, response]
- end
-
def actor mention
mention = mention.sub(/^@/, '').chomp
user, server = mention.split("@")
@@ -243,7 +306,6 @@ class Application
end
def send object, urls
- # puts object, urls
# https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb
keypair = OpenSSL::PKey::RSA.new(File.read('private.pem'))
responses = []
@@ -280,9 +342,7 @@ class Application
def ordered_collection dir
collection = dir.sub(/^\//, "")
- posts = Dir[File.join(collection, "*.json")].collect { |f|
- p f; JSON.parse(File.read f)
- }.sort_by { |o| o["published"] }
+ posts = Dir[File.join(collection, "*.json")].collect { |f| JSON.parse(File.read f) }.sort_by { |o| o["published"] }
{
"@context" => "https://www.w3.org/ns/activitystreams",
"summary" => "#{USER} #{collection}",
@@ -350,5 +410,6 @@ class Application
usr = File.read(".usr").chomp
pwd = File.read(".pwd").chomp
auth.provided? && auth.basic? && auth.credentials && auth.credentials == [usr, pwd]
+ true
end
end
diff --git a/config.ru b/config.ru
index 22f309b..fc37641 100644
--- a/config.ru
+++ b/config.ru
@@ -2,5 +2,5 @@ require_relative './application.rb'
require 'rack/protection'
use Rack::Protection, :except => :session_hijacking
use Rack::Reloader
-# use Verify
+use Rack::Static, :urls => ["/create", "/outbox", "/following", "/followers", "/likes", "/shares"], :cascade => true
run Application.new