Compare commits
5 commits
0333dc2c2f
...
abefbcec64
Author | SHA1 | Date | |
---|---|---|---|
abefbcec64 | |||
0627da0027 | |||
829ae13572 | |||
4fb2251221 | |||
3f06ccc9e3 |
9 changed files with 82 additions and 7 deletions
28
README.md
28
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
|
## Upgrading to Akkoma
|
||||||
|
|
||||||
### From source
|
### From source
|
||||||
|
|
|
@ -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: [],
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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('xss')"
|
assert object.data["content"] == "<p><b>2hu</b></p>alert('xss')"
|
||||||
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
|
||||||
|
|
|
@ -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"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue