diff --git a/README.md b/README.md index fa7881a1a..bf56cb817 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,31 @@ +## akkoma + +*a smallish microblogging platform, aka the cooler pleroma* + +### Why though? + +pleroma as a project has stagnated of late. after a spat between +developers led to a fork (which died due to chronic lack of direction), +nearly nobody seems to _want_ to work on it. this in addition to the +BDFL being AWOL whenever needed, means that the entire project is +nought but a power vacuum waiting for someone to step in. and with the +track record pleroma has, i do not trust that whoever steps in will be +good for the project. + +thus, i am striking out on my own. i already had a few modifications +on my instance, so it wasn't a particularly large leap to assume direct +control. + +### But really, why should I migrate to your thing? + +aside from me actually being responsive? let's lookie here, we've got +- custom emoji reactions +- misskey markdown (MFM) rendering and posting support +- elasticsearch support (because pleroma search is GARBAGE) +- latest develop pleroma-fe additions +- local-only posting +- probably more, this is like 3.5 years of IHBA additions finally compiled + ## Upgrading to Akkoma ### From source diff --git a/config/config.exs b/config/config.exs index 417f298d7..ad7096669 100644 --- a/config/config.exs +++ b/config/config.exs @@ -222,7 +222,8 @@ "text/plain", "text/html", "text/markdown", - "text/bbcode" + "text/bbcode", + "text/x.misskeymarkdown" ], staff_transparency: [], autofollowed_nicknames: [], diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex index f4043ac80..9e1858ae7 100644 --- a/lib/pleroma/emoji.ex +++ b/lib/pleroma/emoji.ex @@ -165,7 +165,7 @@ def maybe_quote(name) when is_binary(name) do def maybe_quote(name), do: name - def emoji_url(%{"type" => "EmojiReact", "content" => emoji, "tag" => []}), do: nil + def emoji_url(%{"type" => "EmojiReact", "content" => _, "tag" => []}), do: nil def emoji_url(%{"type" => "EmojiReact", "content" => emoji, "tag" => tags}) do tag = diff --git a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex index e3f3110f2..815995895 100644 --- a/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex @@ -29,6 +29,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do end field(:replies, {:array, ObjectValidators.ObjectID}, default: []) + field(:source, :map) end def cast_and_apply(data) do @@ -79,6 +80,25 @@ defp fix_replies(%{"replies" => %{"first" => first}} = data) do defp fix_replies(data), do: data + # https://github.com/misskey-dev/misskey/pull/8787 + defp fix_misskey_content(%{"source" => %{"mediaType" => "text/x.misskeymarkdown"}} = object), + do: object + + defp fix_misskey_content(%{"_misskey_content" => content} = object) do + object + |> Map.put("source", %{"content" => content, "mediaType" => "text/x.misskeymarkdown"}) + |> Map.delete("_misskey_content") + end + + defp fix_misskey_content(data), do: data + + defp fix_source(%{"source" => source} = object) when is_binary(source) do + object + |> Map.put("source", %{"content" => source}) + end + + defp fix_source(object), do: object + defp fix(data) do data |> CommonFixes.fix_actor() @@ -86,6 +106,8 @@ defp fix(data) do |> fix_url() |> fix_tag() |> fix_replies() + |> fix_source() + |> fix_misskey_content() |> Transmogrifier.fix_emoji() |> Transmogrifier.fix_content_map() end diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex index b4e3e37ae..bd56b6e20 100644 --- a/lib/pleroma/web/common_api/activity_draft.ex +++ b/lib/pleroma/web/common_api/activity_draft.ex @@ -213,13 +213,15 @@ defp object(draft) do end emoji = Map.merge(emoji, summary_emoji) - {:ok, note_data, _meta} = Builder.note(draft) object = note_data |> Map.put("emoji", emoji) - |> Map.put("source", draft.status) + |> Map.put("source", %{ + "content" => draft.status, + "mediaType" => draft.params[:content_type] + }) |> Map.put("generator", draft.params[:generator]) %__MODULE__{draft | object: object} diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index b6feaf32a..8fde9ae15 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -291,6 +291,15 @@ def format_input(text, "text/markdown", options) do |> Formatter.html_escape("text/html") end + def format_input(text, "text/x.misskeymarkdown", options) do + text + |> Formatter.html_escape("text/plain") + |> Formatter.linkify(options) + |> (fn {text, mentions, tags} -> + {String.replace(text, ~r/\r?\n/, "
"), mentions, tags} + end).() + end + def format_naive_asctime(date) do date |> DateTime.from_naive!("Etc/UTC") |> format_asctime end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 008040866..c0f467592 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -80,7 +80,6 @@ defp reblogged?(_activity, _user), do: false def render("index.json", opts) do reading_user = opts[:for] - # To do: check AdminAPIControllerTest on the reasons behind nil activities in the list activities = Enum.filter(opts.activities, & &1) @@ -376,6 +375,9 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} emoji_reactions: emoji_reactions, parent_visible: visible_for_user?(reply_to, opts[:for]), pinned_at: pinned_at + }, + akkoma: %{ + source: object.data["source"] } } end diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs index ad0b87543..20870bdd7 100644 --- a/test/pleroma/web/common_api_test.exs +++ b/test/pleroma/web/common_api_test.exs @@ -586,7 +586,11 @@ test "it filters out obviously bad tags when accepting a post as HTML" do object = Object.normalize(activity, fetch: false) assert object.data["content"] == "

2hu

alert('xss')" - assert object.data["source"] == post + + assert object.data["source"] == %{ + "mediaType" => "text/html", + "content" => post + } end test "it filters out obviously bad tags when accepting a post as Markdown" do @@ -603,7 +607,11 @@ test "it filters out obviously bad tags when accepting a post as Markdown" do object = Object.normalize(activity, fetch: false) assert object.data["content"] == "

2hu

" - assert object.data["source"] == post + + assert object.data["source"] == %{ + "mediaType" => "text/markdown", + "content" => post + } end test "it does not allow replies to direct messages that are not direct messages themselves" do diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs index 3ee53d95c..caf2594c0 100644 --- a/test/pleroma/web/mastodon_api/views/status_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs @@ -302,6 +302,9 @@ test "a note activity" do emoji_reactions: [], parent_visible: false, pinned_at: nil + }, + akkoma: %{ + source: HTML.filter_tags(object_data["content"]) } }