defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
use Pleroma.Web, :controller
alias Pleroma.{Repo, Object, Activity, User, Notification, Stats}
+ alias Pleroma.Object.Fetcher
alias Pleroma.Web
alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView, FilterView}
alias Pleroma.Web.ActivityPub.ActivityPub
end
end
+ defp add_if_present(
+ map,
+ params,
+ params_field,
+ map_field,
+ value_function \\ fn x -> {:ok, x} end
+ ) do
+ if Map.has_key?(params, params_field) do
+ case value_function.(params[params_field]) do
+ {:ok, new_value} -> Map.put(map, map_field, new_value)
+ :error -> map
+ end
+ else
+ map
+ end
+ end
+
def update_credentials(%{assigns: %{user: user}} = conn, params) do
original_user = user
- avatar_upload_limit =
- Application.get_env(:pleroma, :instance)
- |> Keyword.fetch(:avatar_upload_limit)
-
- banner_upload_limit =
- Application.get_env(:pleroma, :instance)
- |> Keyword.fetch(:banner_upload_limit)
-
- params =
- if bio = params["note"] do
- Map.put(params, "bio", bio)
- else
- params
- end
-
- params =
- if name = params["display_name"] do
- Map.put(params, "name", name)
- else
- params
- end
+ user_params =
+ %{}
+ |> add_if_present(params, "display_name", :name)
+ |> add_if_present(params, "note", :bio, fn value -> {:ok, User.parse_bio(value)} end)
+ |> add_if_present(params, "avatar", :avatar, fn value ->
+ with %Plug.Upload{} <- value,
+ {:ok, object} <- ActivityPub.upload(value, type: :avatar) do
+ {:ok, object.data}
+ else
+ _ -> :error
+ end
+ end)
- user =
- if avatar = params["avatar"] do
- with %Plug.Upload{} <- avatar,
- {:ok, object} <- ActivityPub.upload(avatar, avatar_upload_limit),
- change = Ecto.Changeset.change(user, %{avatar: object.data}),
- {:ok, user} = User.update_and_set_cache(change) do
- user
+ info_params =
+ %{}
+ |> add_if_present(params, "locked", :locked, fn value -> {:ok, value == "true"} end)
+ |> add_if_present(params, "header", :banner, fn value ->
+ with %Plug.Upload{} <- value,
+ {:ok, object} <- ActivityPub.upload(value, type: :banner) do
+ {:ok, object.data}
else
- _e -> user
+ _ -> :error
end
- else
- user
- end
+ end)
- # user =
- # if banner = params["header"] do
- # with %Plug.Upload{} <- banner,
- # {:ok, object} <- ActivityPub.upload(banner, banner_upload_limit),
- # new_info <- Map.put(user.info, "banner", object.data),
- # change <- User.info_changeset(user, %{info: new_info}),
- # {:ok, user} <- User.update_and_set_cache(change) do
- # user
- # else
- # _e -> user
- # end
- # else
- # user
- # end
-
- # user =
- # if locked = params["locked"] do
- # with locked <- locked == "true",
- # new_info <- Map.put(user.info, "locked", locked),
- # change <- User.info_changeset(user, %{info: new_info}),
- # {:ok, user} <- User.update_and_set_cache(change) do
- # user
- # else
- # _e -> user
- # end
- # else
- # user
- # end
-
- with changeset <- User.update_changeset(user, params),
+ info_cng = User.Info.mastodon_profile_update(user.info, info_params)
+
+ with changeset <- User.update_changeset(user, user_params),
+ changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng),
{:ok, user} <- User.update_and_set_cache(changeset) do
if original_user != user do
CommonAPI.update(user)
end
def upload(%{assigns: %{user: _}} = conn, %{"file" => file} = data) do
- with {:ok, object} <- ActivityPub.upload(file) do
- objdata =
- if Map.has_key?(data, "description") do
- Map.put(object.data, "name", data["description"])
- else
- object.data
- end
-
- change = Object.change(object, %{data: objdata})
+ with {:ok, object} <- ActivityPub.upload(file, description: Map.get(data, "description")) do
+ change = Object.change(object, %{data: object.data})
{:ok, object} = Repo.update(change)
objdata =
- objdata
+ object.data
|> Map.put("id", object.id)
render(conn, StatusView, "attachment.json", %{attachment: objdata})
end
def favourited_by(conn, %{"id" => id}) do
- with %Activity{data: %{"object" => %{"likes" => likes}}} <- Repo.get(Activity, id) do
+ with %Activity{data: %{"object" => object}} <- Repo.get(Activity, id),
+ %Object{data: %{"likes" => likes}} <- Object.normalize(object) do
q = from(u in User, where: u.ap_id in ^likes)
users = Repo.all(q)
render(conn, AccountView, "accounts.json", %{users: users, as: :user})
end
def reblogged_by(conn, %{"id" => id}) do
- with %Activity{data: %{"object" => %{"announcements" => announces}}} <- Repo.get(Activity, id) do
+ with %Activity{data: %{"object" => object}} <- Repo.get(Activity, id),
+ %Object{data: %{"announcements" => announces}} <- Object.normalize(object) do
q = from(u in User, where: u.ap_id in ^announces)
users = Repo.all(q)
render(conn, AccountView, "accounts.json", %{users: users, as: :user})
def status_search(query) do
fetched =
if Regex.match?(~r/https?:/, query) do
- with {:ok, object} <- ActivityPub.fetch_object_from_id(query) do
+ with {:ok, object} <- Fetcher.fetch_object_from_id(query) do
[Activity.get_create_activity_by_object_ap_id(object.data["id"])]
else
_e -> []
def login(conn, _) do
with {:ok, app} <- get_or_make_app() do
path =
- o_auth_path(conn, :authorize,
+ o_auth_path(
+ conn,
+ :authorize,
response_type: "code",
client_id: app.client_id,
redirect_uri: ".",