Compare commits

..

5 commits

Author SHA1 Message Date
abefbcec64 Merge branch 'mfm' into develop
Some checks failed
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/lint Pipeline was successful
ci/woodpecker/push/test Pipeline failed
2022-06-14 16:25:47 +01:00
0627da0027 mix format 2022-06-14 16:25:28 +01:00
829ae13572 ensure tests pass
Some checks failed
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/lint Pipeline failed
ci/woodpecker/push/test unknown status
2022-06-14 16:24:03 +01:00
4fb2251221 Allow authoring MFM
Some checks failed
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/lint Pipeline failed
ci/woodpecker/push/test unknown status
2022-06-14 15:56:12 +01:00
3f06ccc9e3 allow source from misskey 2022-06-14 10:56:18 +01:00
9 changed files with 82 additions and 7 deletions

View file

@ -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 ## Upgrading to Akkoma
### From source ### From source

View file

@ -222,7 +222,8 @@
"text/plain", "text/plain",
"text/html", "text/html",
"text/markdown", "text/markdown",
"text/bbcode" "text/bbcode",
"text/x.misskeymarkdown"
], ],
staff_transparency: [], staff_transparency: [],
autofollowed_nicknames: [], autofollowed_nicknames: [],

View file

@ -165,7 +165,7 @@ def maybe_quote(name) when is_binary(name) do
def maybe_quote(name), do: name 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 def emoji_url(%{"type" => "EmojiReact", "content" => emoji, "tag" => tags}) do
tag = tag =

View file

@ -29,6 +29,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
end end
field(:replies, {:array, ObjectValidators.ObjectID}, default: []) field(:replies, {:array, ObjectValidators.ObjectID}, default: [])
field(:source, :map)
end end
def cast_and_apply(data) do def cast_and_apply(data) do
@ -79,6 +80,25 @@ defp fix_replies(%{"replies" => %{"first" => first}} = data) do
defp fix_replies(data), do: data 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 defp fix(data) do
data data
|> CommonFixes.fix_actor() |> CommonFixes.fix_actor()
@ -86,6 +106,8 @@ defp fix(data) do
|> fix_url() |> fix_url()
|> fix_tag() |> fix_tag()
|> fix_replies() |> fix_replies()
|> fix_source()
|> fix_misskey_content()
|> Transmogrifier.fix_emoji() |> Transmogrifier.fix_emoji()
|> Transmogrifier.fix_content_map() |> Transmogrifier.fix_content_map()
end end

View file

@ -213,13 +213,15 @@ defp object(draft) do
end end
emoji = Map.merge(emoji, summary_emoji) emoji = Map.merge(emoji, summary_emoji)
{:ok, note_data, _meta} = Builder.note(draft) {:ok, note_data, _meta} = Builder.note(draft)
object = object =
note_data note_data
|> Map.put("emoji", emoji) |> 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]) |> Map.put("generator", draft.params[:generator])
%__MODULE__{draft | object: object} %__MODULE__{draft | object: object}

View file

@ -291,6 +291,15 @@ def format_input(text, "text/markdown", options) do
|> Formatter.html_escape("text/html") |> Formatter.html_escape("text/html")
end 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/, "<br>"), mentions, tags}
end).()
end
def format_naive_asctime(date) do def format_naive_asctime(date) do
date |> DateTime.from_naive!("Etc/UTC") |> format_asctime date |> DateTime.from_naive!("Etc/UTC") |> format_asctime
end end

View file

@ -80,7 +80,6 @@ defp reblogged?(_activity, _user), do: false
def render("index.json", opts) do def render("index.json", opts) do
reading_user = opts[:for] reading_user = opts[:for]
# To do: check AdminAPIControllerTest on the reasons behind nil activities in the list # To do: check AdminAPIControllerTest on the reasons behind nil activities in the list
activities = Enum.filter(opts.activities, & &1) activities = Enum.filter(opts.activities, & &1)
@ -376,6 +375,9 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
emoji_reactions: emoji_reactions, emoji_reactions: emoji_reactions,
parent_visible: visible_for_user?(reply_to, opts[:for]), parent_visible: visible_for_user?(reply_to, opts[:for]),
pinned_at: pinned_at pinned_at: pinned_at
},
akkoma: %{
source: object.data["source"]
} }
} }
end end

View file

@ -586,7 +586,11 @@ test "it filters out obviously bad tags when accepting a post as HTML" do
object = Object.normalize(activity, fetch: false) object = Object.normalize(activity, fetch: false)
assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)" assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)"
assert object.data["source"] == post
assert object.data["source"] == %{
"mediaType" => "text/html",
"content" => post
}
end end
test "it filters out obviously bad tags when accepting a post as Markdown" do 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) object = Object.normalize(activity, fetch: false)
assert object.data["content"] == "<p><b>2hu</b></p>" assert object.data["content"] == "<p><b>2hu</b></p>"
assert object.data["source"] == post
assert object.data["source"] == %{
"mediaType" => "text/markdown",
"content" => post
}
end end
test "it does not allow replies to direct messages that are not direct messages themselves" do test "it does not allow replies to direct messages that are not direct messages themselves" do

View file

@ -302,6 +302,9 @@ test "a note activity" do
emoji_reactions: [], emoji_reactions: [],
parent_visible: false, parent_visible: false,
pinned_at: nil pinned_at: nil
},
akkoma: %{
source: HTML.filter_tags(object_data["content"])
} }
} }