diff options
Diffstat (limited to 'lib/pleroma/web/twitter_api')
8 files changed, 341 insertions, 193 deletions
diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 503719dbf..8f452c31c 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -11,21 +11,21 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do def show_password_reset(conn, %{"token" => token}) do with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}), - %User{} = user <- Repo.get(User, token.user_id) do - render conn, "password_reset.html", %{ + %User{} = user <- Repo.get(User, token.user_id) do + render(conn, "password_reset.html", %{ token: token, user: user - } + }) else - _e -> render conn, "invalid_token.html" + _e -> render(conn, "invalid_token.html") end end def password_reset(conn, %{"data" => data}) do with {:ok, _} <- PasswordResetToken.reset_password(data["token"], data) do - render conn, "password_reset_success.html" + render(conn, "password_reset_success.html") else - _e -> render conn, "password_reset_failed.html" + _e -> render(conn, "password_reset_failed.html") end end @@ -34,14 +34,19 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do - with %User{} = user <- User.get_cached_by_nickname(nick), - avatar = User.avatar_url(user) do + with %User{} = user <- User.get_cached_by_nickname(nick), avatar = User.avatar_url(user) do conn |> render("subscribe.html", %{nickname: nick, avatar: avatar, error: false}) else - _e -> render(conn, "subscribe.html", %{nickname: nick, avatar: nil, error: "Could not find user"}) + _e -> + render(conn, "subscribe.html", %{ + nickname: nick, + avatar: nil, + error: "Could not find user" + }) end end + def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profile}}) do with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile), %User{ap_id: ap_id} <- User.get_cached_by_nickname(nick) do @@ -49,7 +54,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do |> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id)) else _e -> - render(conn, "subscribe.html", %{nickname: nick, avatar: nil, error: "Something went wrong."}) + render(conn, "subscribe.html", %{ + nickname: nick, + avatar: nil, + error: "Something went wrong." + }) end end @@ -64,17 +73,26 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do |> render("follow.html", %{error: err, acct: acct, avatar: avatar, name: name, id: id}) else conn - |> render("follow_login.html", %{error: false, acct: acct, avatar: avatar, name: name, id: id}) + |> render("follow_login.html", %{ + error: false, + acct: acct, + avatar: avatar, + name: name, + id: id + }) end end - def do_remote_follow(conn, %{"authorization" => %{"name" => username, "password" => password, "id" => id}}) do + def do_remote_follow(conn, %{ + "authorization" => %{"name" => username, "password" => password, "id" => id} + }) do followee = Repo.get(User, id) avatar = User.avatar_url(followee) name = followee.nickname + with %User{} = user <- User.get_cached_by_nickname(username), true <- Pbkdf2.checkpw(password, user.password_hash), - %User{} = followed <- Repo.get(User, id), + %User{} = followed <- Repo.get(User, id), {:ok, follower} <- User.follow(user, followee), {:ok, _activity} <- ActivityPub.follow(follower, followee) do conn @@ -82,9 +100,15 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do else _e -> conn - |> render("follow_login.html", %{error: "Wrong username or password", id: id, name: name, avatar: avatar}) + |> render("follow_login.html", %{ + error: "Wrong username or password", + id: id, + name: name, + avatar: avatar + }) end end + def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) do with %User{} = followee <- Repo.get(User, id), {:ok, follower} <- User.follow(user, followee), @@ -93,9 +117,10 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do |> render("followed.html", %{error: false}) else e -> - Logger.debug("Remote follow failed with error #{inspect e}") - conn - |> render("followed.html", %{error: inspect(e)}) + Logger.debug("Remote follow failed with error #{inspect(e)}") + + conn + |> render("followed.html", %{error: inspect(e)}) end end @@ -107,60 +132,67 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do <config> <site> <name>#{Keyword.get(@instance, :name)}</name> - <site>#{Web.base_url}</site> + <site>#{Web.base_url()}</site> <textlimit>#{Keyword.get(@instance, :limit)}</textlimit> <closed>#{!Keyword.get(@instance, :registrations_open)}</closed> </site> </config> """ + conn |> put_resp_content_type("application/xml") |> send_resp(200, response) + _ -> json(conn, %{ - site: %{ - name: Keyword.get(@instance, :name), - server: Web.base_url, - textlimit: to_string(Keyword.get(@instance, :limit)), - closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1") - } - }) + site: %{ + name: Keyword.get(@instance, :name), + server: Web.base_url(), + textlimit: to_string(Keyword.get(@instance, :limit)), + closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1") + } + }) end end def version(conn, _params) do version = Keyword.get(@instance, :version) + case get_format(conn) do "xml" -> response = "<version>#{version}</version>" + conn |> put_resp_content_type("application/xml") |> send_resp(200, response) - _ -> json(conn, version) + + _ -> + json(conn, version) end end def emoji(conn, _params) do - json conn, Enum.into(Formatter.get_custom_emoji(), %{}) + json(conn, Enum.into(Formatter.get_custom_emoji(), %{})) end def follow_import(conn, %{"list" => %Plug.Upload{} = listfile}) do follow_import(conn, %{"list" => File.read!(listfile.path)}) end + def follow_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do Task.start(fn -> - String.split(list) - |> Enum.map(fn nick -> + String.split(list) + |> Enum.map(fn nick -> with %User{} = follower <- User.get_cached_by_ap_id(user.ap_id), - %User{} = followed <- User.get_or_fetch_by_nickname(nick), - {:ok, follower} <- User.follow(follower, followed) do + %User{} = followed <- User.get_or_fetch_by_nickname(nick), + {:ok, follower} <- User.follow(follower, followed) do ActivityPub.follow(follower, followed) else - _e -> Logger.debug "follow_import: following #{nick} failed" + _e -> Logger.debug("follow_import: following #{nick} failed") end end) end) - json conn, "job started" + json(conn, "job started") end end diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex index 73ae3422b..c216c606e 100644 --- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/activity_representer.ex @@ -7,18 +7,22 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do alias Pleroma.Formatter defp user_by_ap_id(user_list, ap_id) do - Enum.find(user_list, fn (%{ap_id: user_id}) -> ap_id == user_id end) + Enum.find(user_list, fn %{ap_id: user_id} -> ap_id == user_id end) end - def to_map(%Activity{data: %{"type" => "Announce", "actor" => actor, "published" => created_at}} = activity, - %{users: users, announced_activity: announced_activity} = opts) do + def to_map( + %Activity{data: %{"type" => "Announce", "actor" => actor, "published" => created_at}} = + activity, + %{users: users, announced_activity: announced_activity} = opts + ) do user = user_by_ap_id(users, actor) - created_at = created_at |> Utils.date_to_asctime + created_at = created_at |> Utils.date_to_asctime() text = "#{user.nickname} retweeted a status." announced_user = user_by_ap_id(users, announced_activity.data["actor"]) retweeted_status = to_map(announced_activity, Map.merge(%{user: announced_user}, opts)) + %{ "id" => activity.id, "user" => UserView.render("show.json", %{user: user, for: opts[:for]}), @@ -35,9 +39,11 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do } end - def to_map(%Activity{data: %{"type" => "Like", "published" => created_at}} = activity, - %{user: user, liked_activity: liked_activity} = opts) do - created_at = created_at |> Utils.date_to_asctime + def to_map( + %Activity{data: %{"type" => "Like", "published" => created_at}} = activity, + %{user: user, liked_activity: liked_activity} = opts + ) do + created_at = created_at |> Utils.date_to_asctime() text = "#{user.nickname} favorited a status." @@ -56,12 +62,16 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do } end - def to_map(%Activity{data: %{"type" => "Follow", "object" => followed_id}} = activity, %{user: user} = opts) do - created_at = activity.data["published"] || (DateTime.to_iso8601(activity.inserted_at)) - created_at = created_at |> Utils.date_to_asctime + def to_map( + %Activity{data: %{"type" => "Follow", "object" => followed_id}} = activity, + %{user: user} = opts + ) do + created_at = activity.data["published"] || DateTime.to_iso8601(activity.inserted_at) + created_at = created_at |> Utils.date_to_asctime() followed = User.get_cached_by_ap_id(followed_id) text = "#{user.nickname} started following #{followed.nickname}" + %{ "id" => activity.id, "user" => UserView.render("show.json", %{user: user, for: opts[:for]}), @@ -79,10 +89,16 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do # TODO: # Make this more proper. Just a placeholder to not break the frontend. - def to_map(%Activity{data: %{"type" => "Undo", "published" => created_at, "object" => undid_activity }} = activity, %{user: user} = opts) do - created_at = created_at |> Utils.date_to_asctime + def to_map( + %Activity{ + data: %{"type" => "Undo", "published" => created_at, "object" => undid_activity} + } = activity, + %{user: user} = opts + ) do + created_at = created_at |> Utils.date_to_asctime() text = "#{user.nickname} undid the action at #{undid_activity}" + %{ "id" => activity.id, "user" => UserView.render("show.json", %{user: user, for: opts[:for]}), @@ -98,8 +114,12 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do } end - def to_map(%Activity{data: %{"type" => "Delete", "published" => created_at, "object" => _ }} = activity, %{user: user} = opts) do - created_at = created_at |> Utils.date_to_asctime + def to_map( + %Activity{data: %{"type" => "Delete", "published" => created_at, "object" => _}} = + activity, + %{user: user} = opts + ) do + created_at = created_at |> Utils.date_to_asctime() %{ "id" => activity.id, @@ -107,7 +127,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do "user" => UserView.render("show.json", %{user: user, for: opts[:for]}), "attentions" => [], "statusnet_html" => "deleted notice {{tag", - "text" => "deleted notice {{tag" , + "text" => "deleted notice {{tag", "is_local" => activity.local, "is_post_verb" => false, "created_at" => created_at, @@ -117,8 +137,11 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do } end - def to_map(%Activity{data: %{"object" => %{"content" => content} = object}} = activity, %{user: user} = opts) do - created_at = object["published"] |> Utils.date_to_asctime + def to_map( + %Activity{data: %{"object" => %{"content" => content} = object}} = activity, + %{user: user} = opts + ) do + created_at = object["published"] |> Utils.date_to_asctime() like_count = object["like_count"] || 0 announcement_count = object["announcement_count"] || 0 favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || []) @@ -126,10 +149,11 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do mentions = opts[:mentioned] || [] - attentions = activity.recipients - |> Enum.map(fn (ap_id) -> Enum.find(mentions, fn(user) -> ap_id == user.ap_id end) end) - |> Enum.filter(&(&1)) - |> Enum.map(fn (user) -> UserView.render("show.json", %{user: user, for: opts[:for]}) end) + attentions = + activity.recipients + |> Enum.map(fn ap_id -> Enum.find(mentions, fn user -> ap_id == user.ap_id end) end) + |> Enum.filter(& &1) + |> Enum.map(fn user -> UserView.render("show.json", %{user: user, for: opts[:for]}) end) conversation_id = conversation_id(activity) @@ -139,14 +163,17 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do tags = if possibly_sensitive, do: Enum.uniq(["nsfw" | tags]), else: tags summary = activity.data["object"]["summary"] - content = if !!summary and summary != "" do - "<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>" - else - content - end - html = HtmlSanitizeEx.basic_html(content) - |> Formatter.emojify(object["emoji"]) + content = + if !!summary and summary != "" do + "<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>" + else + content + end + + html = + HtmlSanitizeEx.basic_html(content) + |> Formatter.emojify(object["emoji"]) %{ "id" => activity.id, @@ -175,7 +202,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do def conversation_id(activity) do with context when not is_nil(context) <- activity.data["context"] do TwitterAPI.context_to_conversation_id(context) - else _e -> nil + else + _e -> nil end end diff --git a/lib/pleroma/web/twitter_api/representers/base_representer.ex b/lib/pleroma/web/twitter_api/representers/base_representer.ex index 75e00520c..f32a21d47 100644 --- a/lib/pleroma/web/twitter_api/representers/base_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/base_representer.ex @@ -1,15 +1,18 @@ defmodule Pleroma.Web.TwitterAPI.Representers.BaseRepresenter do defmacro __using__(_opts) do quote do - def to_json(object) do to_json(object, %{}) end + def to_json(object) do + to_json(object, %{}) + end + def to_json(object, options) do object |> to_map(options) - |> Jason.encode! + |> Jason.encode!() end def enum_to_list(enum, options) do - mapping = fn (el) -> to_map(el, options) end + mapping = fn el -> to_map(el, options) end Enum.map(enum, mapping) end @@ -17,11 +20,14 @@ defmodule Pleroma.Web.TwitterAPI.Representers.BaseRepresenter do to_map(object, %{}) end - def enum_to_json(enum) do enum_to_json(enum, %{}) end + def enum_to_json(enum) do + enum_to_json(enum, %{}) + end + def enum_to_json(enum, options) do enum |> enum_to_list(options) - |> Jason.encode! + |> Jason.encode!() end end end diff --git a/lib/pleroma/web/twitter_api/representers/object_representer.ex b/lib/pleroma/web/twitter_api/representers/object_representer.ex index e2d653ba8..9af8a1691 100644 --- a/lib/pleroma/web/twitter_api/representers/object_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/object_representer.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter do def to_map(%Object{data: %{"url" => [url | _]}} = object, _opts) do data = object.data + %{ url: url["href"] |> Pleroma.Web.MediaProxy.url(), mimetype: url["mediaType"], diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 58801bc33..4eac8a8fd 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -13,37 +13,42 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end def fetch_friend_statuses(user, opts \\ %{}) do - opts = opts - |> Map.put("blocking_user", user) - |> Map.put("user", user) - |> Map.put("type", ["Create", "Announce", "Follow", "Like"]) + opts = + opts + |> Map.put("blocking_user", user) + |> Map.put("user", user) + |> Map.put("type", ["Create", "Announce", "Follow", "Like"]) ActivityPub.fetch_activities([user.ap_id | user.following], opts) |> activities_to_statuses(%{for: user}) end def fetch_public_statuses(user, opts \\ %{}) do - opts = opts - |> Map.put("local_only", true) - |> Map.put("blocking_user", user) - |> Map.put("type", ["Create", "Announce", "Follow"]) + opts = + opts + |> Map.put("local_only", true) + |> Map.put("blocking_user", user) + |> Map.put("type", ["Create", "Announce", "Follow"]) ActivityPub.fetch_public_activities(opts) |> activities_to_statuses(%{for: user}) end def fetch_public_and_external_statuses(user, opts \\ %{}) do - opts = opts - |> Map.put("blocking_user", user) - |> Map.put("type", ["Create", "Announce", "Follow"]) + opts = + opts + |> Map.put("blocking_user", user) + |> Map.put("type", ["Create", "Announce", "Follow"]) ActivityPub.fetch_public_activities(opts) |> activities_to_statuses(%{for: user}) end def fetch_user_statuses(user, opts \\ %{}) do - opts = opts - |> Map.put("type", ["Create"]) + opts = + opts + |> Map.put("type", ["Create"]) + ActivityPub.fetch_public_activities(opts) |> activities_to_statuses(%{for: user}) end @@ -55,12 +60,16 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def fetch_conversation(user, id) do with context when is_binary(context) <- conversation_id_to_context(id), - activities <- ActivityPub.fetch_activities_for_context(context, %{"blocking_user" => user, "user" => user}), - statuses <- activities |> activities_to_statuses(%{for: user}) - do + activities <- + ActivityPub.fetch_activities_for_context(context, %{ + "blocking_user" => user, + "user" => user + }), + statuses <- activities |> activities_to_statuses(%{for: user}) do statuses - else _e -> - [] + else + _e -> + [] end end @@ -74,8 +83,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def follow(%User{} = follower, params) do with {:ok, %User{} = followed} <- get_user(params), {:ok, follower} <- User.follow(follower, followed), - {:ok, activity} <- ActivityPub.follow(follower, followed) - do + {:ok, activity} <- ActivityPub.follow(follower, followed) do {:ok, follower, followed, activity} else err -> err @@ -83,16 +91,17 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end def unfollow(%User{} = follower, params) do - with { :ok, %User{} = unfollowed } <- get_user(params), - { :ok, follower, follow_activity } <- User.unfollow(follower, unfollowed), - { :ok, _activity } <- ActivityPub.insert(%{ - "type" => "Undo", - "actor" => follower.ap_id, - "object" => follow_activity.data["id"], # get latest Follow for these users - "published" => make_date() - }) - do - { :ok, follower, unfollowed } + with {:ok, %User{} = unfollowed} <- get_user(params), + {:ok, follower, follow_activity} <- User.unfollow(follower, unfollowed), + {:ok, _activity} <- + ActivityPub.insert(%{ + "type" => "Undo", + "actor" => follower.ap_id, + # get latest Follow for these users + "object" => follow_activity.data["id"], + "published" => make_date() + }) do + {:ok, follower, unfollowed} else err -> err end @@ -100,8 +109,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def block(%User{} = blocker, params) do with {:ok, %User{} = blocked} <- get_user(params), - {:ok, blocker} <- User.block(blocker, blocked) - do + {:ok, blocker} <- User.block(blocker, blocked) do {:ok, blocker, blocked} else err -> err @@ -110,8 +118,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def unblock(%User{} = blocker, params) do with {:ok, %User{} = blocked} <- get_user(params), - {:ok, blocker} <- User.unblock(blocker, blocked) - do + {:ok, blocker} <- User.unblock(blocker, blocked) do {:ok, blocker, blocked} else err -> err @@ -163,13 +170,15 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do <atom:link rel="enclosure" href="#{href}" type="#{type}"></atom:link> </rsp> """ + "json" -> %{ media_id: object.id, media_id_string: "#{object.id}}", media_url: href, size: 0 - } |> Jason.encode! + } + |> Jason.encode!() end end @@ -189,9 +198,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do {:ok, user} else {:error, changeset} -> - errors = Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end) - |> Jason.encode! - {:error, %{error: errors}} + errors = + Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end) + |> Jason.encode!() + + {:error, %{error: errors}} end end @@ -209,16 +220,20 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do case target = get_by_id_or_nickname(user_id) do nil -> {:error, "No user with such user_id"} + _ -> {:ok, target} end + %{"screen_name" => nickname} -> case target = Repo.get_by(User, nickname: nickname) do nil -> {:error, "No user with such screen_name"} + _ -> {:ok, target} end + _ -> if user do {:ok, user} @@ -229,6 +244,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end defp parse_int(string, default) + defp parse_int(string, default) when is_binary(string) do with {n, _} <- Integer.parse(string) do n @@ -236,6 +252,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do _e -> default end end + defp parse_int(_, default), do: default def search(user, %{"q" => query} = params) do @@ -243,19 +260,28 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do page = parse_int(params["page"], 1) offset = (page - 1) * limit - q = from a in Activity, - where: fragment("?->>'type' = 'Create'", a.data), - where: fragment("to_tsvector('english', ?->'object'->>'content') @@ plainto_tsquery('english', ?)", a.data, ^query), - limit: ^limit, - offset: ^offset, - order_by: [desc: :inserted_at] # this one isn't indexed so psql won't take the wrong index. + q = + from( + a in Activity, + where: fragment("?->>'type' = 'Create'", a.data), + where: + fragment( + "to_tsvector('english', ?->'object'->>'content') @@ plainto_tsquery('english', ?)", + a.data, + ^query + ), + limit: ^limit, + offset: ^offset, + # this one isn't indexed so psql won't take the wrong index. + order_by: [desc: :inserted_at] + ) activities = Repo.all(q) activities_to_statuses(activities, %{for: user}) end defp activities_to_statuses(activities, opts) do - Enum.map(activities, fn(activity) -> + Enum.map(activities, fn activity -> activity_to_status(activity, opts) end) end @@ -266,7 +292,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do user = User.get_cached_by_ap_id(actor) [liked_activity] = Activity.all_by_object_ap_id(activity.data["object"]) - ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user, liked_activity: liked_activity})) + ActivityRepresenter.to_map( + activity, + Map.merge(opts, %{user: user, liked_activity: liked_activity}) + ) end # For announces, fetch the announced activity and the user. @@ -276,7 +305,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do [announced_activity] = Activity.all_by_object_ap_id(activity.data["object"]) announced_actor = User.get_cached_by_ap_id(announced_activity.data["actor"]) - ActivityRepresenter.to_map(activity, Map.merge(opts, %{users: [user, announced_actor], announced_activity: announced_activity})) + ActivityRepresenter.to_map( + activity, + Map.merge(opts, %{users: [user, announced_actor], announced_activity: announced_activity}) + ) end defp activity_to_status(%Activity{data: %{"type" => "Delete"}} = activity, opts) do @@ -289,32 +321,41 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do actor = get_in(activity.data, ["actor"]) user = User.get_cached_by_ap_id(actor) # mentioned_users = Repo.all(from user in User, where: user.ap_id in ^activity.data["to"]) - mentioned_users = Enum.map(activity.recipients || [], fn (ap_id) -> - if ap_id do - User.get_cached_by_ap_id(ap_id) - else - nil - end - end) - |> Enum.filter(&(&1)) + mentioned_users = + Enum.map(activity.recipients || [], fn ap_id -> + if ap_id do + User.get_cached_by_ap_id(ap_id) + else + nil + end + end) + |> Enum.filter(& &1) - ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user, mentioned: mentioned_users})) + ActivityRepresenter.to_map( + activity, + Map.merge(opts, %{user: user, mentioned: mentioned_users}) + ) end defp make_date do - DateTime.utc_now() |> DateTime.to_iso8601 + DateTime.utc_now() |> DateTime.to_iso8601() end def context_to_conversation_id(context) do with %Object{id: id} <- Object.get_cached_by_ap_id(context) do id - else _e -> + else + _e -> changeset = Object.context_mapping(context) + case Repo.insert(changeset) do - {:ok, %{id: id}} -> id + {:ok, %{id: id}} -> + id + # This should be solved by an upsert, but it seems ecto # has problems accessing the constraint inside the jsonb. - {:error, _} -> Object.get_cached_by_ap_id(context).id + {:error, _} -> + Object.get_cached_by_ap_id(context).id end end end @@ -322,8 +363,9 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def conversation_id_to_context(id) do with %Object{data: %{"id" => context}} <- Repo.get(Object, id) do context - else _e -> - {:error, "No such conversation"} + else + _e -> + {:error, "No such conversation"} end end @@ -331,12 +373,15 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do with %User{} = user <- User.get_or_fetch(uri) do spawn(fn -> with url <- user.info["topic"], - {:ok, %{body: body}} <- @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do + {:ok, %{body: body}} <- + @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do OStatus.handle_incoming(body) end end) + {:ok, UserView.render("show.json", %{user: user, for: for_user})} - else _e -> + else + _e -> {:error, "Couldn't find user"} end end diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index a3c98a245..a8bcae5ba 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -16,7 +16,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do def status_update(%{assigns: %{user: user}} = conn, %{"status" => _} = status_data) do with media_ids <- extract_media_ids(status_data), - {:ok, activity} <- TwitterAPI.create_status(user, Map.put(status_data, "media_ids", media_ids)) do + {:ok, activity} <- + TwitterAPI.create_status(user, Map.put(status_data, "media_ids", media_ids)) do conn |> json(ActivityRepresenter.to_map(activity, %{user: user})) else @@ -35,10 +36,10 @@ defmodule Pleroma.Web.TwitterAPI.Controller do defp extract_media_ids(status_data) do with media_ids when not is_nil(media_ids) <- status_data["media_ids"], split_ids <- String.split(media_ids, ","), - clean_ids <- Enum.reject(split_ids, fn (id) -> String.length(id) == 0 end) - do - clean_ids - else _e -> [] + clean_ids <- Enum.reject(split_ids, fn id -> String.length(id) == 0 end) do + clean_ids + else + _e -> [] end end @@ -69,9 +70,9 @@ defmodule Pleroma.Web.TwitterAPI.Controller do def show_user(conn, params) do with {:ok, shown} <- TwitterAPI.get_user(params) do if user = conn.assigns.user do - render conn, UserView, "show.json", %{user: shown, for: user} + render(conn, UserView, "show.json", %{user: shown, for: user}) else - render conn, UserView, "show.json", %{user: shown} + render(conn, UserView, "show.json", %{user: shown}) end else {:error, msg} -> @@ -83,9 +84,11 @@ defmodule Pleroma.Web.TwitterAPI.Controller do case TwitterAPI.get_user(user, params) do {:ok, target_user} -> params = Map.merge(params, %{"actor_id" => target_user.ap_id, "whole_db" => true}) - statuses = TwitterAPI.fetch_user_statuses(user, params) + statuses = TwitterAPI.fetch_user_statuses(user, params) + conn - |> json_reply(200, statuses |> Jason.encode!) + |> json_reply(200, statuses |> Jason.encode!()) + {:error, msg} -> bad_request_reply(conn, msg) end @@ -103,29 +106,36 @@ defmodule Pleroma.Web.TwitterAPI.Controller do case TwitterAPI.follow(user, params) do {:ok, user, followed, _activity} -> render(conn, UserView, "show.json", %{user: followed, for: user}) - {:error, msg} -> forbidden_json_reply(conn, msg) + + {:error, msg} -> + forbidden_json_reply(conn, msg) end end def block(%{assigns: %{user: user}} = conn, params) do case TwitterAPI.block(user, params) do {:ok, user, blocked} -> - render conn, UserView, "show.json", %{user: blocked, for: user} - {:error, msg} -> forbidden_json_reply(conn, msg) + render(conn, UserView, "show.json", %{user: blocked, for: user}) + + {:error, msg} -> + forbidden_json_reply(conn, msg) end end def unblock(%{assigns: %{user: user}} = conn, params) do case TwitterAPI.unblock(user, params) do {:ok, user, blocked} -> - render conn, UserView, "show.json", %{user: blocked, for: user} - {:error, msg} -> forbidden_json_reply(conn, msg) + render(conn, UserView, "show.json", %{user: blocked, for: user}) + + {:error, msg} -> + forbidden_json_reply(conn, msg) end end def delete_post(%{assigns: %{user: user}} = conn, %{"id" => id}) do with {:ok, delete} <- CommonAPI.delete(id, user) do json = ActivityRepresenter.to_json(delete, %{user: user, for: user}) + conn |> json_reply(200, json) end @@ -135,14 +145,16 @@ defmodule Pleroma.Web.TwitterAPI.Controller do case TwitterAPI.unfollow(user, params) do {:ok, user, unfollowed} -> render(conn, UserView, "show.json", %{user: unfollowed, for: user}) - {:error, msg} -> forbidden_json_reply(conn, msg) + + {:error, msg} -> + forbidden_json_reply(conn, msg) end end def fetch_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do with %Activity{} = activity <- Repo.get(Activity, id), true <- ActivityPub.visible_for_user?(activity, user) do - render conn, ActivityView, "activity.json", %{activity: activity, for: user} + render(conn, ActivityView, "activity.json", %{activity: activity, for: user}) end end @@ -156,6 +168,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do def upload(conn, %{"media" => media}) do response = TwitterAPI.upload(media) + conn |> put_resp_content_type("application/atom+xml") |> send_resp(200, response) @@ -163,12 +176,14 @@ defmodule Pleroma.Web.TwitterAPI.Controller do def upload_json(conn, %{"media" => media}) do response = TwitterAPI.upload(media, "json") + conn |> json_reply(200, response) end def get_by_id_or_ap_id(id) do activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id) + if activity.data["type"] == "Create" do activity else @@ -199,8 +214,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do render(conn, UserView, "show.json", %{user: user}) else {:error, errors} -> - conn - |> json_reply(400, Jason.encode!(errors)) + conn + |> json_reply(400, Jason.encode!(errors)) end end @@ -219,8 +234,9 @@ defmodule Pleroma.Web.TwitterAPI.Controller do change <- User.info_changeset(user, %{info: new_info}), {:ok, user} <- User.update_and_set_cache(change) do CommonAPI.update(user) - %{"url" => [ %{ "href" => href } | _ ]} = object.data - response = %{ url: href } |> Jason.encode! + %{"url" => [%{"href" => href} | _]} = object.data + response = %{url: href} |> Jason.encode!() + conn |> json_reply(200, response) end @@ -231,8 +247,9 @@ defmodule Pleroma.Web.TwitterAPI.Controller do new_info <- Map.put(user.info, "background", object.data), change <- User.info_changeset(user, %{info: new_info}), {:ok, _user} <- User.update_and_set_cache(change) do - %{"url" => [ %{ "href" => href } | _ ]} = object.data - response = %{ url: href } |> Jason.encode! + %{"url" => [%{"href" => href} | _]} = object.data + response = %{url: href} |> Jason.encode!() + conn |> json_reply(200, response) end @@ -285,9 +302,10 @@ defmodule Pleroma.Web.TwitterAPI.Controller do def friends_ids(%{assigns: %{user: user}} = conn, _params) do with {:ok, friends} <- User.get_friends(user) do - ids = friends - |> Enum.map(fn x -> x.id end) - |> Jason.encode! + ids = + friends + |> Enum.map(fn x -> x.id end) + |> Jason.encode!() json(conn, ids) else @@ -300,11 +318,12 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def update_profile(%{assigns: %{user: user}} = conn, params) do - params = if bio = params["description"] do - Map.put(params, "bio", bio) - else - params - end + params = + if bio = params["description"] do + Map.put(params, "bio", bio) + else + params + end with changeset <- User.update_changeset(user, params), {:ok, user} <- User.update_and_set_cache(changeset) do @@ -339,6 +358,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end defp error_json(conn, error_message) do - %{"error" => error_message, "request" => conn.request_path} |> Jason.encode! + %{"error" => error_message, "request" => conn.request_path} |> Jason.encode!() end end diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index 50d536d0e..1596b34dc 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -10,7 +10,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do def render("activity.json", %{activity: %{data: %{"type" => "Announce"}} = activity} = opts) do user = User.get_by_ap_id(activity.data["actor"]) - created_at = activity.data["published"] |> Utils.date_to_asctime + created_at = activity.data["published"] |> Utils.date_to_asctime() announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) text = "#{user.nickname} retweeted a status." @@ -37,8 +37,10 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do def render("activity.json", %{activity: %{data: %{"type" => "Like"}} = activity} = opts) do user = User.get_cached_by_ap_id(activity.data["actor"]) liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) - created_at = activity.data["published"] - |> Utils.date_to_asctime + + created_at = + activity.data["published"] + |> Utils.date_to_asctime() text = "#{user.nickname} favorited a status." @@ -57,20 +59,24 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do } end - def render("activity.json", %{activity: %{data: %{"type" => "Create", "object" => object}} = activity} = opts) do + def render( + "activity.json", + %{activity: %{data: %{"type" => "Create", "object" => object}} = activity} = opts + ) do actor = get_in(activity.data, ["actor"]) user = User.get_cached_by_ap_id(actor) - created_at = object["published"] |> Utils.date_to_asctime + created_at = object["published"] |> Utils.date_to_asctime() like_count = object["like_count"] || 0 announcement_count = object["announcement_count"] || 0 favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || []) repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || []) - attentions = activity.recipients - |> Enum.map(fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end) - |> Enum.filter(&(&1)) - |> Enum.map(fn (user) -> UserView.render("show.json", %{user: user, for: opts[:for]}) end) + attentions = + activity.recipients + |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end) + |> Enum.filter(& &1) + |> Enum.map(fn user -> UserView.render("show.json", %{user: user, for: opts[:for]}) end) conversation_id = conversation_id(activity) @@ -81,14 +87,17 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do summary = activity.data["object"]["summary"] content = object["content"] - content = if !!summary and summary != "" do - "<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>" - else - content - end - html = HtmlSanitizeEx.basic_html(content) - |> Formatter.emojify(object["emoji"]) + content = + if !!summary and summary != "" do + "<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>" + else + content + end + + html = + HtmlSanitizeEx.basic_html(content) + |> Formatter.emojify(object["emoji"]) %{ "id" => activity.id, @@ -117,7 +126,8 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do defp conversation_id(activity) do with context when not is_nil(context) <- activity.data["context"] do TwitterAPI.context_to_conversation_id(context) - else _e -> nil + else + _e -> nil end end end diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index 6fb07f052..31527caae 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -14,20 +14,22 @@ defmodule Pleroma.Web.TwitterAPI.UserView do def render("user.json", %{user: user = %User{}} = assigns) do image = User.avatar_url(user) |> MediaProxy.url() - {following, follows_you, statusnet_blocking} = if assigns[:for] do - { - User.following?(assigns[:for], user), - User.following?(user, assigns[:for]), - User.blocks?(assigns[:for], user) - } - else - {false, false, false} - end + + {following, follows_you, statusnet_blocking} = + if assigns[:for] do + { + User.following?(assigns[:for], user), + User.following?(user, assigns[:for]), + User.blocks?(assigns[:for], user) + } + else + {false, false, false} + end user_info = User.get_cached_user_info(user) data = %{ - "created_at" => user.inserted_at |> Utils.format_naive_asctime, + "created_at" => user.inserted_at |> Utils.format_naive_asctime(), "description" => HtmlSanitizeEx.strip_tags(user.bio), "favourites_count" => 0, "followers_count" => user_info[:follower_count], @@ -59,9 +61,14 @@ defmodule Pleroma.Web.TwitterAPI.UserView do end end - def render("short.json", %{user: %User{ - nickname: nickname, id: id, ap_id: ap_id, name: name - }}) do + def render("short.json", %{ + user: %User{ + nickname: nickname, + id: id, + ap_id: ap_id, + name: name + } + }) do %{ "fullname" => name, "id" => id, @@ -71,6 +78,6 @@ defmodule Pleroma.Web.TwitterAPI.UserView do } end - defp image_url(%{"url" => [ %{ "href" => href } | _ ]}), do: href + defp image_url(%{"url" => [%{"href" => href} | _]}), do: href defp image_url(_), do: nil end |