X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fmastodon_api%2Fmastodon_api_controller.ex;h=ff52b2aab6cafdfe63b00cd2607100568c2c0749;hb=a8369db4f222676040a072ceb0bde647ef237f14;hp=58bb5e03afe173b898459b91c1333eadfcf24bb6;hpb=b3d67750f04d7c72c3e1deeb6df573cbb195146a;p=akkoma diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 58bb5e03a..ff52b2aab 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -2,7 +2,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do use Pleroma.Web, :controller alias Pleroma.{Repo, Activity, User, Notification, Stats} alias Pleroma.Web - alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView} + alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.{CommonAPI, OStatus} alias Pleroma.Web.OAuth.{Authorization, Token, App} @@ -102,13 +102,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end @instance Application.get_env(:pleroma, :instance) + @mastodon_api_level "2.3.3" def masto_instance(conn, _params) do response = %{ uri: Web.base_url(), title: Keyword.get(@instance, :name), description: "A Pleroma instance, an alternative fediverse server", - version: Keyword.get(@instance, :version), + version: "#{@mastodon_api_level} (compatible; #{Keyword.get(@instance, :version)})", email: Keyword.get(@instance, :email), urls: %{ streaming_api: String.replace(Web.base_url(), ["http", "https"], "wss") @@ -211,9 +212,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> Map.put("actor_id", ap_id) |> Map.put("whole_db", true) - activities = - ActivityPub.fetch_public_activities(params) - |> Enum.reverse() + if params["pinned"] == "true" do + # Since Pleroma has no "pinned" posts feature, we'll just set an empty list here + activities = [] + else + activities = + ActivityPub.fetch_public_activities(params) + |> Enum.reverse() + end conn |> add_link_headers(:user_statuses, activities, params["id"]) @@ -494,6 +500,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do if Regex.match?(~r/https?:/, query) do with {:ok, activities} <- OStatus.fetch_activity_from_url(query) do activities + |> Enum.filter(fn + %{data: %{"type" => "Create"}} -> true + _ -> false + end) else _e -> [] end @@ -503,22 +513,30 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do from( a in Activity, where: fragment("?->>'type' = 'Create'", a.data), + where: "https://www.w3.org/ns/activitystreams#Public" in a.recipients, where: fragment( "to_tsvector('english', ?->'object'->>'content') @@ plainto_tsquery('english', ?)", a.data, ^query ), - limit: 20 + limit: 20, + order_by: [desc: :id] ) statuses = Repo.all(q) ++ fetched + tags = + String.split(query) + |> Enum.uniq() + |> Enum.filter(fn tag -> String.starts_with?(tag, "#") end) + |> Enum.map(fn tag -> String.slice(tag, 1..-1) end) + res = %{ "accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user), "statuses" => StatusView.render("index.json", activities: statuses, for: user, as: :activity), - "hashtags" => [] + "hashtags" => tags } json(conn, res) @@ -547,6 +565,102 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> render(StatusView, "index.json", %{activities: activities, for: user, as: :activity}) end + def get_lists(%{assigns: %{user: user}} = conn, opts) do + lists = Pleroma.List.for_user(user, opts) + res = ListView.render("lists.json", lists: lists) + json(conn, res) + end + + def get_list(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %Pleroma.List{} = list <- Pleroma.List.get(user, id) do + res = ListView.render("list.json", list: list) + json(conn, res) + else + _e -> json(conn, "error") + end + end + + def delete_list(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %Pleroma.List{} = list <- Pleroma.List.get(user, id), + {:ok, _list} <- Pleroma.List.delete(list) do + json(conn, %{}) + else + _e -> + json(conn, "error") + end + end + + def create_list(%{assigns: %{user: user}} = conn, %{"title" => title}) do + with {:ok, %Pleroma.List{} = list} <- Pleroma.List.create(title, user) do + res = ListView.render("list.json", list: list) + json(conn, res) + end + end + + def add_to_list(%{assigns: %{user: user}} = conn, %{"id" => id, "account_ids" => accounts}) do + accounts + |> Enum.each(fn account_id -> + with %Pleroma.List{} = list <- Pleroma.List.get(user, id), + %User{} = followed <- Repo.get(User, account_id) do + ret = Pleroma.List.follow(list, followed) + end + end) + + json(conn, %{}) + end + + def remove_from_list(%{assigns: %{user: user}} = conn, %{"id" => id, "account_ids" => accounts}) do + accounts + |> Enum.each(fn account_id -> + with %Pleroma.List{} = list <- Pleroma.List.get(user, id), + %User{} = followed <- Repo.get(Pleroma.User, account_id) do + Pleroma.List.unfollow(list, followed) + end + end) + + json(conn, %{}) + end + + def list_accounts(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %Pleroma.List{} = list <- Pleroma.List.get(user, id), + {:ok, users} = Pleroma.List.get_following(list) do + render(conn, AccountView, "accounts.json", %{users: users, as: :user}) + end + end + + def rename_list(%{assigns: %{user: user}} = conn, %{"id" => id, "title" => title}) do + with %Pleroma.List{} = list <- Pleroma.List.get(user, id), + {:ok, list} <- Pleroma.List.rename(list, title) do + res = ListView.render("list.json", list: list) + json(conn, res) + else + _e -> + json(conn, "error") + end + end + + def list_timeline(%{assigns: %{user: user}} = conn, %{"list_id" => id} = params) do + with %Pleroma.List{title: title, following: following} <- Pleroma.List.get(user, id) do + params = + params + |> Map.put("type", "Create") + |> Map.put("blocking_user", user) + + # adding title is a hack to not make empty lists function like a public timeline + activities = + ActivityPub.fetch_activities([title | following], params) + |> Enum.reverse() + + conn + |> render(StatusView, "index.json", %{activities: activities, for: user, as: :activity}) + else + _e -> + conn + |> put_status(403) + |> json(%{error: "Error."}) + end + end + def index(%{assigns: %{user: user}} = conn, _params) do token = conn @@ -593,35 +707,37 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do "video\/mp4" ] }, - settings: %{ - onboarded: true, - home: %{ - shows: %{ - reblog: true, - reply: true - } - }, - notifications: %{ - alerts: %{ - follow: true, - favourite: true, - reblog: true, - mention: true + settings: + Map.get(user.info, "settings") || + %{ + onboarded: true, + home: %{ + shows: %{ + reblog: true, + reply: true + } + }, + notifications: %{ + alerts: %{ + follow: true, + favourite: true, + reblog: true, + mention: true + }, + shows: %{ + follow: true, + favourite: true, + reblog: true, + mention: true + }, + sounds: %{ + follow: true, + favourite: true, + reblog: true, + mention: true + } + } }, - shows: %{ - follow: true, - favourite: true, - reblog: true, - mention: true - }, - sounds: %{ - follow: true, - favourite: true, - reblog: true, - mention: true - } - } - }, push_subscription: nil, accounts: accounts, custom_emojis: mastodon_emoji, @@ -638,6 +754,19 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do + with new_info <- Map.put(user.info, "settings", settings), + change <- User.info_changeset(user, %{info: new_info}), + {:ok, _user} <- User.update_and_set_cache(change) do + conn + |> json(%{}) + else + e -> + conn + |> json(%{error: inspect(e)}) + end + end + def login(conn, _) do conn |> render(MastodonView, "login.html", %{error: false}) @@ -660,7 +789,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def login_post(conn, %{"authorization" => %{"name" => name, "password" => password}}) do - with %User{} = user <- User.get_cached_by_nickname(name), + with %User{} = user <- User.get_by_nickname_or_email(name), true <- Pbkdf2.checkpw(password, user.password_hash), {:ok, app} <- get_or_make_app(), {:ok, auth} <- Authorization.create_authorization(app, user),