Refactored status-related Twitter API
This commit is contained in:
parent
bfe628ebaa
commit
9af466790a
|
@ -2,4 +2,10 @@ defmodule Pleroma.Misc do
|
||||||
def make_date do
|
def make_date do
|
||||||
DateTime.utc_now() |> DateTime.to_iso8601
|
DateTime.utc_now() |> DateTime.to_iso8601
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_boolean(false), do: false
|
||||||
|
|
||||||
|
def to_boolean(nil), do: false
|
||||||
|
|
||||||
|
def to_boolean(_), do: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -166,4 +166,29 @@ defmodule Pleroma.User do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_by_params(user \\ nil, params) do
|
||||||
|
case params do
|
||||||
|
%{"user_id" => user_id} ->
|
||||||
|
case target = Repo.get(User, user_id) do
|
||||||
|
nil ->
|
||||||
|
{:not_found, "No user with such user_id"}
|
||||||
|
_ ->
|
||||||
|
{:ok, target}
|
||||||
|
end
|
||||||
|
%{"screen_name" => nickname} ->
|
||||||
|
case target = Repo.get_by(User, nickname: nickname) do
|
||||||
|
nil ->
|
||||||
|
{:not_found, "No user with such screen_name"}
|
||||||
|
_ ->
|
||||||
|
{:ok, target}
|
||||||
|
end
|
||||||
|
_ ->
|
||||||
|
if user do
|
||||||
|
{:ok, user}
|
||||||
|
else
|
||||||
|
{:bad_request, "You need to specify screen_name or user_id"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,13 +29,13 @@ defmodule Pleroma.Web.Router do
|
||||||
get "/help/test", TwitterAPI.UtilController, :help_test
|
get "/help/test", TwitterAPI.UtilController, :help_test
|
||||||
get "/statusnet/config", TwitterAPI.UtilController, :config
|
get "/statusnet/config", TwitterAPI.UtilController, :config
|
||||||
|
|
||||||
get "/statuses/public_timeline", TwitterAPI.Controller, :public_timeline
|
get "/statuses/public_timeline", TwitterAPI.StatusController, :public_timeline
|
||||||
get "/statuses/public_and_external_timeline", TwitterAPI.Controller, :public_and_external_timeline
|
get "/statuses/public_and_external_timeline", TwitterAPI.StatusController, :public_and_external_timeline
|
||||||
get "/statuses/networkpublic_timeline", TwitterAPI.Controller, :public_and_external_timeline
|
get "/statuses/networkpublic_timeline", TwitterAPI.StatusController, :public_and_external_timeline
|
||||||
get "/statuses/user_timeline", TwitterAPI.Controller, :user_timeline
|
get "/statuses/user_timeline", TwitterAPI.StatusController, :user_timeline
|
||||||
|
|
||||||
get "/statuses/show/:id", TwitterAPI.Controller, :fetch_status
|
get "/statuses/show/:id", TwitterAPI.StatusController, :fetch_status
|
||||||
get "/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation
|
get "/statusnet/conversation/:id", TwitterAPI.StatusController, :fetch_conversation
|
||||||
|
|
||||||
post "/account/register", TwitterAPI.UserController, :register
|
post "/account/register", TwitterAPI.UserController, :register
|
||||||
end
|
end
|
||||||
|
@ -46,13 +46,13 @@ defmodule Pleroma.Web.Router do
|
||||||
get "/account/verify_credentials", TwitterAPI.UserController, :verify_credentials
|
get "/account/verify_credentials", TwitterAPI.UserController, :verify_credentials
|
||||||
post "/account/verify_credentials", TwitterAPI.UserController, :verify_credentials
|
post "/account/verify_credentials", TwitterAPI.UserController, :verify_credentials
|
||||||
|
|
||||||
get "/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline
|
get "/statuses/home_timeline", TwitterAPI.StatusController, :friends_timeline
|
||||||
get "/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline
|
get "/statuses/friends_timeline", TwitterAPI.StatusController, :friends_timeline
|
||||||
get "/statuses/mentions", TwitterAPI.Controller, :mentions_timeline
|
get "/statuses/mentions", TwitterAPI.StatusController, :mentions_timeline
|
||||||
get "/statuses/mentions_timeline", TwitterAPI.Controller, :mentions_timeline
|
get "/statuses/mentions_timeline", TwitterAPI.StatusController, :mentions_timeline
|
||||||
|
|
||||||
post "/statuses/update", TwitterAPI.Controller, :status_update
|
post "/statuses/update", TwitterAPI.StatusController, :status_update
|
||||||
post "/statuses/retweet/:id", TwitterAPI.Controller, :retweet
|
post "/statuses/retweet/:id", TwitterAPI.StatusController, :retweet
|
||||||
|
|
||||||
post "/friendships/create", TwitterAPI.UserController, :follow
|
post "/friendships/create", TwitterAPI.UserController, :follow
|
||||||
post "/friendships/destroy", TwitterAPI.UserController, :unfollow
|
post "/friendships/destroy", TwitterAPI.UserController, :unfollow
|
||||||
|
@ -60,9 +60,9 @@ defmodule Pleroma.Web.Router do
|
||||||
post "/statusnet/media/upload", TwitterAPI.Controller, :upload
|
post "/statusnet/media/upload", TwitterAPI.Controller, :upload
|
||||||
post "/media/upload", TwitterAPI.Controller, :upload_json
|
post "/media/upload", TwitterAPI.Controller, :upload_json
|
||||||
|
|
||||||
post "/favorites/create/:id", TwitterAPI.Controller, :favorite
|
post "/favorites/create/:id", TwitterAPI.StatusController, :favorite
|
||||||
post "/favorites/create", TwitterAPI.Controller, :favorite
|
post "/favorites/create", TwitterAPI.StatusController, :favorite
|
||||||
post "/favorites/destroy/:id", TwitterAPI.Controller, :unfavorite
|
post "/favorites/destroy/:id", TwitterAPI.StatusController, :unfavorite
|
||||||
|
|
||||||
post "/qvitter/update_avatar", TwitterAPI.UserController, :update_avatar
|
post "/qvitter/update_avatar", TwitterAPI.UserController, :update_avatar
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
defmodule Pleroma.Web.TwitterAPI.StatusController do
|
||||||
|
use Pleroma.Web, :controller
|
||||||
|
alias Pleroma.{Activity, Repo, Object, User, Misc}
|
||||||
|
alias Pleroma.Web.TwitterAPI.{ErrorView, TwitterAPI, UserController}
|
||||||
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
|
||||||
|
def status_update(%{assigns: %{user: user}} = conn, %{"status" => status_text} = status_data) do
|
||||||
|
l = status_text |> String.trim |> String.length
|
||||||
|
if l > 0 && l < 5000 do
|
||||||
|
media_ids = extract_media_ids(status_data)
|
||||||
|
{:ok, activity} = TwitterAPI.create_status(user, Map.put(status_data, "media_ids", media_ids))
|
||||||
|
render(conn, "show.json", %{activity: activity, for: user})
|
||||||
|
else
|
||||||
|
empty_status_reply(conn)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def status_update(conn, _status_data) do
|
||||||
|
empty_status_reply(conn)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp empty_status_reply(conn) do
|
||||||
|
message = "Client must provide a 'status' parameter with a value."
|
||||||
|
conn
|
||||||
|
|> put_status(:bad_request)
|
||||||
|
|> render(ErrorView, "error.json", %{request_path: conn.request_path, message: message})
|
||||||
|
end
|
||||||
|
|
||||||
|
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 -> []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def public_and_external_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|
activities = ActivityPub.fetch_public_activities(params)
|
||||||
|
render(conn, "timeline.json", %{activities: activities, for: user})
|
||||||
|
end
|
||||||
|
|
||||||
|
def public_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|
activities = ActivityPub.fetch_public_activities(Map.put(params, "local_only", true))
|
||||||
|
render(conn, "timeline.json", %{activities: activities, for: user})
|
||||||
|
end
|
||||||
|
|
||||||
|
def friends_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|
activities = ActivityPub.fetch_activities([user.ap_id | user.following], params)
|
||||||
|
render(conn, "timeline.json", %{activities: activities, for: user})
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_timeline(conn, params) do
|
||||||
|
case UserController.find_user(conn, params) do
|
||||||
|
{:error, response} -> response
|
||||||
|
|
||||||
|
{:ok, user = %User{ap_id: ap_id}} ->
|
||||||
|
activities = ActivityPub.fetch_activities([], Map.merge(params, %{"actor_id" => ap_id}))
|
||||||
|
render(conn, "timeline.json", %{activities: activities, for: user})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def mentions_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|
activities = ActivityPub.fetch_activities([user.ap_id], params)
|
||||||
|
render(conn, "timeline.json", %{activities: activities, for: user})
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
|
case find_activity(conn, id) do
|
||||||
|
{:not_found, response} -> response
|
||||||
|
{:ok, activity = %Activity{}} -> render(conn, "show.json", %{activity: activity, for: user})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
|
id = String.to_integer(id)
|
||||||
|
with context when is_binary(context) <- TwitterAPI.conversation_id_to_context(id),
|
||||||
|
activities <- ActivityPub.fetch_activities_for_context(context)
|
||||||
|
do
|
||||||
|
render(conn, "timeline.json", %{activities: activities, for: user})
|
||||||
|
else _e ->
|
||||||
|
json(conn, [])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def favorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
|
case find_activity(conn, id) do
|
||||||
|
{:not_found, response} -> response
|
||||||
|
{:ok, activity = %Activity{data: %{"object" => %{"id" => object_id}}}} ->
|
||||||
|
object = Object.get_by_ap_id(object_id)
|
||||||
|
case ActivityPub.like(user, object) do
|
||||||
|
{:ok, _like, object = %Object{}} ->
|
||||||
|
activity = update_data(activity, object)
|
||||||
|
render(conn, "show.json", %{activity: activity, for: user})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfavorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
|
case find_activity(conn, id) do
|
||||||
|
{:not_found, response} -> response
|
||||||
|
{:ok, activity = %Activity{data: %{"object" => %{"id" => object_id}}}} ->
|
||||||
|
object = Object.get_by_ap_id(object_id)
|
||||||
|
case ActivityPub.unlike(user, object) do
|
||||||
|
{:ok, object = %Object{}} ->
|
||||||
|
activity = update_data(activity, object)
|
||||||
|
render(conn, "show.json", %{activity: activity, for: user})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def retweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
|
case find_activity(conn, id) do
|
||||||
|
{:not_found, response} -> response
|
||||||
|
{:ok, activity = %Activity{data: %{"actor" => actor, "object" => %{"id" => object_id}}}} ->
|
||||||
|
if actor == user.ap_id do
|
||||||
|
conn
|
||||||
|
|> put_status(:bad_request)
|
||||||
|
|> render(ErrorView, "error.json", %{request_path: conn.request_path,
|
||||||
|
message: "You cannot repeat your own status."})
|
||||||
|
else
|
||||||
|
object = Object.get_by_ap_id(object_id)
|
||||||
|
case ActivityPub.announce(user, object) do
|
||||||
|
{:ok, _announce, object = %Object{}} ->
|
||||||
|
activity = update_data(activity, object)
|
||||||
|
render(conn, "show.json", %{activity: activity, for: user})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp update_data(activity = %Activity{data: data}, %Object{data: object_data}) do
|
||||||
|
new_data = Map.put(data, "object", object_data)
|
||||||
|
%{activity | data: new_data}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp find_activity(conn, id) do
|
||||||
|
case Repo.get(Activity, id) do
|
||||||
|
nil ->
|
||||||
|
response = conn
|
||||||
|
|> put_status(:not_found)
|
||||||
|
|> render(ErrorView, "error.json", %{request_path: conn.request_path,
|
||||||
|
message: "No such status."})
|
||||||
|
{:not_found, response}
|
||||||
|
|
||||||
|
activity = %Activity{} -> {:ok, activity}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,45 +1,48 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.UserController do
|
defmodule Pleroma.Web.TwitterAPI.UserController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
alias Pleroma.{Repo, User, Misc}
|
alias Pleroma.{Activity, Object, Repo, User, Misc}
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
alias Pleroma.Web.TwitterAPI.ErrorView
|
||||||
|
|
||||||
def verify_credentials(%{assigns: %{user: user}} = conn, _params) do
|
def verify_credentials(%{assigns: %{user: user}} = conn, _params) do
|
||||||
render conn, "show.json", %{user: user, for: user}
|
render conn, "show.json", %{user: user, for: user}
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow(%{assigns: %{user: follower}} = conn, params) do
|
def follow(%{assigns: %{user: follower}} = conn, params) do
|
||||||
with {:ok, %User{} = followed} <- get_user(params),
|
case find_user(conn, params) do
|
||||||
{:ok, follower} <- User.follow(follower, followed),
|
{:ok, followed = %User{}} ->
|
||||||
{:ok, activity} <- ActivityPub.follow(follower, followed)
|
case User.follow(follower, followed) do
|
||||||
do
|
{:ok, follower = %User{}} ->
|
||||||
|
{:ok, _activity} = ActivityPub.follow(follower, followed)
|
||||||
render conn, "show.json", %{user: followed, for: follower}
|
render conn, "show.json", %{user: followed, for: follower}
|
||||||
else
|
|
||||||
{:error, message} ->
|
{:error, message} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:bad_request)
|
||||||
|> render(Pleroma.Web.TwitterAPI.ErrorView, "error.json",
|
|> render(ErrorView, "error.json", %{request_path: conn.request_path, message: message})
|
||||||
%{request_path: conn.request_path, message: message})
|
end
|
||||||
|
{:error, response} -> response
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def unfollow(%{assigns: %{user: follower}} = conn, params) do
|
def unfollow(%{assigns: %{user: follower}} = conn, params) do
|
||||||
with { :ok, %User{} = unfollowed } <- get_user(params),
|
case find_user(conn, params) do
|
||||||
{ :ok, follower, follow_activity } <- User.unfollow(follower, unfollowed),
|
{:ok, unfollowed = %User{ap_id: unfollowed_id}} ->
|
||||||
{ :ok, _activity } <- ActivityPub.insert(%{
|
case User.unfollow(follower, unfollowed) do
|
||||||
|
{:ok, follower = %User{ap_id: ap_id}, %Activity{data: %{"id" => id}}} ->
|
||||||
|
{:ok, _activity} = ActivityPub.insert(%{
|
||||||
"type" => "Undo",
|
"type" => "Undo",
|
||||||
"actor" => follower.ap_id,
|
"actor" => ap_id,
|
||||||
"object" => follow_activity.data["id"], # get latest Follow for these users
|
"object" => id, # get latest Follow for these users
|
||||||
"published" => Misc.make_date()
|
"published" => Misc.make_date()
|
||||||
})
|
})
|
||||||
do
|
|
||||||
render conn, "show.json", %{user: unfollowed, for: follower}
|
render conn, "show.json", %{user: unfollowed, for: follower}
|
||||||
else
|
|
||||||
{:error, message} ->
|
{:error, message} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:bad_request)
|
||||||
|> render(Pleroma.Web.TwitterAPI.ErrorView, "error.json",
|
|> render(ErrorView, "error.json", %{request_path: conn.request_path, message: message})
|
||||||
%{request_path: conn.request_path, message: message})
|
end
|
||||||
|
{:error, response} -> response
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,41 +65,26 @@ defmodule Pleroma.Web.TwitterAPI.UserController do
|
||||||
errors = Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end)
|
errors = Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end)
|
||||||
conn
|
conn
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> render(Pleroma.Web.TwitterAPI.ErrorView, "error.json",
|
|> render(ErrorView, "error.json",
|
||||||
%{request_path: conn.request_path, message: errors})
|
%{request_path: conn.request_path, message: errors})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
||||||
{:ok, object} = ActivityPub.upload(params)
|
{:ok, %Object{data: data}} = ActivityPub.upload(params)
|
||||||
change = Changeset.change(user, %{avatar: object.data})
|
change = Changeset.change(user, %{avatar: data})
|
||||||
{:ok, user} = Repo.update(change)
|
{:ok, user} = Repo.update(change)
|
||||||
|
|
||||||
render conn, "show.json", %{user: user}
|
render conn, "show.json", %{user: user}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_user(user \\ nil, params) do
|
def find_user(%{assigns: %{user: user}} = conn, params) do
|
||||||
case params do
|
case User.get_by_params(user, params) do
|
||||||
%{"user_id" => user_id} ->
|
{:ok, user = %User{}} -> {:ok, user}
|
||||||
case target = Repo.get(User, user_id) do
|
{status, message} ->
|
||||||
nil ->
|
response = conn
|
||||||
{:error, "No user with such user_id"}
|
|> put_status(status)
|
||||||
_ ->
|
|> render(ErrorView, "error.json", %{request_path: conn.request_path, message: message})
|
||||||
{:ok, target}
|
{:error, response}
|
||||||
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}
|
|
||||||
else
|
|
||||||
{:error, "You need to specify screen_name or user_id"}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
|
|
||||||
use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
|
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ObjectRepresenter}
|
|
||||||
alias Pleroma.{Activity, User}
|
|
||||||
alias Calendar.Strftime
|
|
||||||
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
|
||||||
|
|
||||||
defp user_by_ap_id(user_list, ap_id) do
|
|
||||||
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
|
|
||||||
user = user_by_ap_id(users, actor)
|
|
||||||
created_at = created_at |> 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" => UserRepresenter.to_map(user, opts),
|
|
||||||
"statusnet_html" => text,
|
|
||||||
"text" => text,
|
|
||||||
"is_local" => true,
|
|
||||||
"is_post_verb" => false,
|
|
||||||
"uri" => "tag:#{activity.data["id"]}:objectType=note",
|
|
||||||
"created_at" => created_at,
|
|
||||||
"retweeted_status" => retweeted_status,
|
|
||||||
"statusnet_conversation_id" => conversation_id(announced_activity),
|
|
||||||
"external_url" => activity.data["id"]
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_map(%Activity{data: %{"type" => "Like", "published" => created_at}} = activity,
|
|
||||||
%{user: user, liked_activity: liked_activity} = opts) do
|
|
||||||
created_at = created_at |> date_to_asctime
|
|
||||||
|
|
||||||
text = "#{user.nickname} favorited a status."
|
|
||||||
|
|
||||||
%{
|
|
||||||
"id" => activity.id,
|
|
||||||
"user" => UserRepresenter.to_map(user, opts),
|
|
||||||
"statusnet_html" => text,
|
|
||||||
"text" => text,
|
|
||||||
"is_local" => true,
|
|
||||||
"is_post_verb" => false,
|
|
||||||
"uri" => "tag:#{activity.data["id"]}:objectType=Favourite",
|
|
||||||
"created_at" => created_at,
|
|
||||||
"in_reply_to_status_id" => liked_activity.id,
|
|
||||||
"external_url" => activity.data["id"]
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_map(%Activity{data: %{"type" => "Follow", "published" => created_at, "object" => followed_id}} = activity, %{user: user} = opts) do
|
|
||||||
created_at = created_at |> date_to_asctime
|
|
||||||
|
|
||||||
followed = User.get_cached_by_ap_id(followed_id)
|
|
||||||
text = "#{user.nickname} started following #{followed.nickname}"
|
|
||||||
%{
|
|
||||||
"id" => activity.id,
|
|
||||||
"user" => UserRepresenter.to_map(user, opts),
|
|
||||||
"attentions" => [],
|
|
||||||
"statusnet_html" => text,
|
|
||||||
"text" => text,
|
|
||||||
"is_local" => true,
|
|
||||||
"is_post_verb" => false,
|
|
||||||
"created_at" => created_at,
|
|
||||||
"in_reply_to_status_id" => nil,
|
|
||||||
"external_url" => activity.data["id"]
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_map(%Activity{data: %{"object" => %{"content" => content} = object}} = activity, %{user: user} = opts) do
|
|
||||||
created_at = object["published"] |> 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"] || [])
|
|
||||||
|
|
||||||
mentions = opts[:mentioned] || []
|
|
||||||
|
|
||||||
attentions = activity.data["to"]
|
|
||||||
|> Enum.map(fn (ap_id) -> Enum.find(mentions, fn(user) -> ap_id == user.ap_id end) end)
|
|
||||||
|> Enum.filter(&(&1))
|
|
||||||
|> Enum.map(fn (user) -> UserRepresenter.to_map(user, opts) end)
|
|
||||||
|
|
||||||
conversation_id = conversation_id(activity)
|
|
||||||
|
|
||||||
%{
|
|
||||||
"id" => activity.id,
|
|
||||||
"user" => UserRepresenter.to_map(user, opts),
|
|
||||||
"attentions" => [],
|
|
||||||
"statusnet_html" => content,
|
|
||||||
"text" => HtmlSanitizeEx.strip_tags(content),
|
|
||||||
"is_local" => true,
|
|
||||||
"is_post_verb" => true,
|
|
||||||
"created_at" => created_at,
|
|
||||||
"in_reply_to_status_id" => object["inReplyToStatusId"],
|
|
||||||
"statusnet_conversation_id" => conversation_id,
|
|
||||||
"attachments" => (object["attachment"] || []) |> ObjectRepresenter.enum_to_list(opts),
|
|
||||||
"attentions" => attentions,
|
|
||||||
"fave_num" => like_count,
|
|
||||||
"repeat_num" => announcement_count,
|
|
||||||
"favorited" => to_boolean(favorited),
|
|
||||||
"repeated" => to_boolean(repeated),
|
|
||||||
"external_url" => activity.data["id"]
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp date_to_asctime(date) do
|
|
||||||
with {:ok, date, _offset} <- date |> DateTime.from_iso8601 do
|
|
||||||
Strftime.strftime!(date, "%a %b %d %H:%M:%S %z %Y")
|
|
||||||
else _e ->
|
|
||||||
""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp to_boolean(false) do
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
defp to_boolean(nil) do
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
defp to_boolean(_) do
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,28 +0,0 @@
|
||||||
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, options) do
|
|
||||||
object
|
|
||||||
|> to_map(options)
|
|
||||||
|> Poison.encode!
|
|
||||||
end
|
|
||||||
|
|
||||||
def enum_to_list(enum, options) do
|
|
||||||
mapping = fn (el) -> to_map(el, options) end
|
|
||||||
Enum.map(enum, mapping)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_map(object) do
|
|
||||||
to_map(object, %{})
|
|
||||||
end
|
|
||||||
|
|
||||||
def enum_to_json(enum) do enum_to_json(enum, %{}) end
|
|
||||||
def enum_to_json(enum, options) do
|
|
||||||
enum
|
|
||||||
|> enum_to_list(options)
|
|
||||||
|> Poison.encode!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,20 +0,0 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter do
|
|
||||||
use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
|
|
||||||
alias Pleroma.Object
|
|
||||||
|
|
||||||
def to_map(%Object{} = object, _opts) do
|
|
||||||
data = object.data
|
|
||||||
url = List.first(data["url"])
|
|
||||||
%{
|
|
||||||
url: url["href"],
|
|
||||||
mimetype: url["mediaType"],
|
|
||||||
id: data["uuid"],
|
|
||||||
oembed: false
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# If we only get the naked data, wrap in an object
|
|
||||||
def to_map(%{} = data, opts) do
|
|
||||||
to_map(%Object{data: data}, opts)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,37 +0,0 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.Representers.UserRepresenter do
|
|
||||||
use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
|
|
||||||
|
|
||||||
alias Pleroma.User
|
|
||||||
|
|
||||||
def to_map(user, opts) do
|
|
||||||
image = User.avatar_url(user)
|
|
||||||
following = if opts[:for] do
|
|
||||||
User.following?(opts[:for], user)
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
user_info = User.get_cached_user_info(user)
|
|
||||||
|
|
||||||
map = %{
|
|
||||||
"id" => user.id,
|
|
||||||
"name" => user.name,
|
|
||||||
"screen_name" => user.nickname,
|
|
||||||
"description" => user.bio,
|
|
||||||
"following" => following,
|
|
||||||
# Fake fields
|
|
||||||
"favourites_count" => 0,
|
|
||||||
"statuses_count" => user_info[:note_count],
|
|
||||||
"friends_count" => user_info[:following_count],
|
|
||||||
"followers_count" => user_info[:follower_count],
|
|
||||||
"profile_image_url" => image,
|
|
||||||
"profile_image_url_https" => image,
|
|
||||||
"profile_image_url_profile_size" => image,
|
|
||||||
"profile_image_url_original" => image,
|
|
||||||
"rights" => %{},
|
|
||||||
"statusnet_profile_url" => user.ap_id
|
|
||||||
}
|
|
||||||
|
|
||||||
map
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -90,88 +90,6 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
||||||
ActivityPub.create(to, user, context, object, additional, data)
|
ActivityPub.create(to, user, context, object, additional, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_friend_statuses(user, opts \\ %{}) do
|
|
||||||
ActivityPub.fetch_activities([user.ap_id | user.following], opts)
|
|
||||||
|> activities_to_statuses(%{for: user})
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_public_statuses(user, opts \\ %{}) do
|
|
||||||
opts = Map.put(opts, "local_only", true)
|
|
||||||
ActivityPub.fetch_public_activities(opts)
|
|
||||||
|> activities_to_statuses(%{for: user})
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_public_and_external_statuses(user, opts \\ %{}) do
|
|
||||||
ActivityPub.fetch_public_activities(opts)
|
|
||||||
|> activities_to_statuses(%{for: user})
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_user_statuses(user, opts \\ %{}) do
|
|
||||||
ActivityPub.fetch_activities([], opts)
|
|
||||||
|> activities_to_statuses(%{for: user})
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_mentions(user, opts \\ %{}) do
|
|
||||||
ActivityPub.fetch_activities([user.ap_id], opts)
|
|
||||||
|> activities_to_statuses(%{for: user})
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_conversation(user, id) do
|
|
||||||
with context when is_binary(context) <- conversation_id_to_context(id),
|
|
||||||
activities <- ActivityPub.fetch_activities_for_context(context),
|
|
||||||
statuses <- activities |> activities_to_statuses(%{for: user})
|
|
||||||
do
|
|
||||||
statuses
|
|
||||||
else _e ->
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_status(user, id) do
|
|
||||||
with %Activity{} = activity <- Repo.get(Activity, id) do
|
|
||||||
activity_to_status(activity, %{for: user})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def favorite(%User{} = user, %Activity{data: %{"object" => object}} = activity) do
|
|
||||||
object = Object.get_by_ap_id(object["id"])
|
|
||||||
|
|
||||||
{:ok, _like_activity, object} = ActivityPub.like(user, object)
|
|
||||||
new_data = activity.data
|
|
||||||
|> Map.put("object", object.data)
|
|
||||||
|
|
||||||
status = %{activity | data: new_data}
|
|
||||||
|> activity_to_status(%{for: user})
|
|
||||||
|
|
||||||
{:ok, status}
|
|
||||||
end
|
|
||||||
|
|
||||||
def unfavorite(%User{} = user, %Activity{data: %{"object" => object}} = activity) do
|
|
||||||
object = Object.get_by_ap_id(object["id"])
|
|
||||||
|
|
||||||
{:ok, object} = ActivityPub.unlike(user, object)
|
|
||||||
new_data = activity.data
|
|
||||||
|> Map.put("object", object.data)
|
|
||||||
|
|
||||||
status = %{activity | data: new_data}
|
|
||||||
|> activity_to_status(%{for: user})
|
|
||||||
|
|
||||||
{:ok, status}
|
|
||||||
end
|
|
||||||
|
|
||||||
def retweet(%User{} = user, %Activity{data: %{"object" => object}} = activity) do
|
|
||||||
object = Object.get_by_ap_id(object["id"])
|
|
||||||
|
|
||||||
{:ok, _announce_activity, object} = ActivityPub.announce(user, object)
|
|
||||||
new_data = activity.data
|
|
||||||
|> Map.put("object", object.data)
|
|
||||||
|
|
||||||
status = %{activity | data: new_data}
|
|
||||||
|> activity_to_status(%{for: user})
|
|
||||||
|
|
||||||
{:ok, status}
|
|
||||||
end
|
|
||||||
|
|
||||||
def upload(%Plug.Upload{} = file, format \\ "xml") do
|
def upload(%Plug.Upload{} = file, format \\ "xml") do
|
||||||
{:ok, object} = ActivityPub.upload(file)
|
{:ok, object} = ActivityPub.upload(file)
|
||||||
|
|
||||||
|
@ -218,68 +136,6 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
||||||
Enum.reduce(mentions, text, fn ({match, %User{ap_id: ap_id}}, text) -> String.replace(text, match, "<a href='#{ap_id}'>#{match}</a>") end)
|
Enum.reduce(mentions, text, fn ({match, %User{ap_id: ap_id}}, text) -> String.replace(text, match, "<a href='#{ap_id}'>#{match}</a>") end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_user(user \\ nil, params) do
|
|
||||||
case params do
|
|
||||||
%{"user_id" => user_id} ->
|
|
||||||
case target = Repo.get(User, 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}
|
|
||||||
else
|
|
||||||
{:error, "You need to specify screen_name or user_id"}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp activities_to_statuses(activities, opts) do
|
|
||||||
Enum.map(activities, fn(activity) ->
|
|
||||||
activity_to_status(activity, opts)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
# For likes, fetch the liked activity, too.
|
|
||||||
defp activity_to_status(%Activity{data: %{"type" => "Like"}} = activity, opts) do
|
|
||||||
actor = get_in(activity.data, ["actor"])
|
|
||||||
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}))
|
|
||||||
end
|
|
||||||
|
|
||||||
# For announces, fetch the announced activity and the user.
|
|
||||||
defp activity_to_status(%Activity{data: %{"type" => "Announce"}} = activity, opts) do
|
|
||||||
actor = get_in(activity.data, ["actor"])
|
|
||||||
user = User.get_cached_by_ap_id(actor)
|
|
||||||
[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}))
|
|
||||||
end
|
|
||||||
|
|
||||||
defp activity_to_status(activity, opts) 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.data["to"] || [], fn (ap_id) ->
|
|
||||||
User.get_cached_by_ap_id(ap_id)
|
|
||||||
end)
|
|
||||||
|> Enum.filter(&(&1))
|
|
||||||
|
|
||||||
ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user, mentioned: mentioned_users}))
|
|
||||||
end
|
|
||||||
|
|
||||||
def context_to_conversation_id(context) do
|
def context_to_conversation_id(context) do
|
||||||
with %Object{id: id} <- Object.get_cached_by_ap_id(context) do
|
with %Object{id: id} <- Object.get_cached_by_ap_id(context) do
|
||||||
id
|
id
|
||||||
|
|
|
@ -1,99 +1,6 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.Controller do
|
defmodule Pleroma.Web.TwitterAPI.Controller do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter}
|
|
||||||
alias Pleroma.{Web, Repo, Activity}
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
|
||||||
alias Ecto.Changeset
|
|
||||||
|
|
||||||
def status_update(%{assigns: %{user: user}} = conn, %{"status" => status_text} = status_data) do
|
|
||||||
l = status_text |> String.trim |> String.length
|
|
||||||
if l > 0 && l < 5000 do
|
|
||||||
media_ids = extract_media_ids(status_data)
|
|
||||||
{:ok, activity} = TwitterAPI.create_status(user, Map.put(status_data, "media_ids", media_ids))
|
|
||||||
conn
|
|
||||||
|> json_reply(200, ActivityRepresenter.to_json(activity, %{user: user}))
|
|
||||||
else
|
|
||||||
empty_status_reply(conn)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def status_update(conn, _status_data) do
|
|
||||||
empty_status_reply(conn)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp empty_status_reply(conn) do
|
|
||||||
bad_request_reply(conn, "Client must provide a 'status' parameter with a value.")
|
|
||||||
end
|
|
||||||
|
|
||||||
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 -> []
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def public_and_external_timeline(%{assigns: %{user: user}} = conn, params) do
|
|
||||||
statuses = TwitterAPI.fetch_public_and_external_statuses(user, params)
|
|
||||||
{:ok, json} = Poison.encode(statuses)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, json)
|
|
||||||
end
|
|
||||||
|
|
||||||
def public_timeline(%{assigns: %{user: user}} = conn, params) do
|
|
||||||
statuses = TwitterAPI.fetch_public_statuses(user, params)
|
|
||||||
{:ok, json} = Poison.encode(statuses)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, json)
|
|
||||||
end
|
|
||||||
|
|
||||||
def friends_timeline(%{assigns: %{user: user}} = conn, params) do
|
|
||||||
statuses = TwitterAPI.fetch_friend_statuses(user, params)
|
|
||||||
{:ok, json} = Poison.encode(statuses)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, json)
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_timeline(%{assigns: %{user: user}} = conn, params) do
|
|
||||||
case TwitterAPI.get_user(user, params) do
|
|
||||||
{:ok, target_user} ->
|
|
||||||
params = Map.merge(params, %{"actor_id" => target_user.ap_id})
|
|
||||||
statuses = TwitterAPI.fetch_user_statuses(user, params)
|
|
||||||
conn
|
|
||||||
|> json_reply(200, statuses |> Poison.encode!)
|
|
||||||
{:error, msg} ->
|
|
||||||
bad_request_reply(conn, msg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def mentions_timeline(%{assigns: %{user: user}} = conn, params) do
|
|
||||||
statuses = TwitterAPI.fetch_mentions(user, params)
|
|
||||||
{:ok, json} = Poison.encode(statuses)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, json)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
|
||||||
response = Poison.encode!(TwitterAPI.fetch_status(user, id))
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, response)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
|
||||||
id = String.to_integer(id)
|
|
||||||
response = Poison.encode!(TwitterAPI.fetch_conversation(user, id))
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, response)
|
|
||||||
end
|
|
||||||
|
|
||||||
def upload(conn, %{"media" => media}) do
|
def upload(conn, %{"media" => media}) do
|
||||||
response = TwitterAPI.upload(media)
|
response = TwitterAPI.upload(media)
|
||||||
|
@ -102,79 +9,15 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
|
||||||
|> send_resp(200, response)
|
|> send_resp(200, response)
|
||||||
end
|
end
|
||||||
|
|
||||||
def help_test(conn, _params) do
|
|
||||||
conn |> json_reply(200, Poison.encode!("ok"))
|
|
||||||
end
|
|
||||||
|
|
||||||
def upload_json(conn, %{"media" => media}) do
|
def upload_json(conn, %{"media" => media}) do
|
||||||
response = TwitterAPI.upload(media, "json")
|
response = TwitterAPI.upload(media, "json")
|
||||||
conn
|
conn
|
||||||
|> json_reply(200, response)
|
|> json_reply(200, response)
|
||||||
end
|
end
|
||||||
|
|
||||||
def config(conn, _params) do
|
|
||||||
response = %{
|
|
||||||
site: %{
|
|
||||||
name: Web.base_url,
|
|
||||||
server: Web.base_url,
|
|
||||||
textlimit: -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|> Poison.encode!
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, response)
|
|
||||||
end
|
|
||||||
|
|
||||||
def favorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
|
||||||
activity = Repo.get(Activity, id)
|
|
||||||
{:ok, status} = TwitterAPI.favorite(user, activity)
|
|
||||||
response = Poison.encode!(status)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, response)
|
|
||||||
end
|
|
||||||
|
|
||||||
def unfavorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
|
||||||
activity = Repo.get(Activity, id)
|
|
||||||
{:ok, status} = TwitterAPI.unfavorite(user, activity)
|
|
||||||
response = Poison.encode!(status)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> json_reply(200, response)
|
|
||||||
end
|
|
||||||
|
|
||||||
def retweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
|
||||||
activity = Repo.get(Activity, id)
|
|
||||||
if activity.data["actor"] == user.ap_id do
|
|
||||||
bad_request_reply(conn, "You cannot repeat your own notice.")
|
|
||||||
else
|
|
||||||
{:ok, status} = TwitterAPI.retweet(user, activity)
|
|
||||||
response = Poison.encode!(status)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|
|
||||||
|> json_reply(200, response)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp bad_request_reply(conn, error_message) do
|
|
||||||
json = error_json(conn, error_message)
|
|
||||||
json_reply(conn, 400, json)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp json_reply(conn, status, json) do
|
defp json_reply(conn, status, json) do
|
||||||
conn
|
conn
|
||||||
|> put_resp_content_type("application/json")
|
|> put_resp_content_type("application/json")
|
||||||
|> send_resp(status, json)
|
|> send_resp(status, json)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp forbidden_json_reply(conn, error_message) do
|
|
||||||
json = error_json(conn, error_message)
|
|
||||||
json_reply(conn, 403, json)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp error_json(conn, error_message) do
|
|
||||||
%{"error" => error_message, "request" => conn.request_path} |> Poison.encode!
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
defmodule Pleroma.Web.TwitterAPI.AttachmentView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.Object
|
||||||
|
|
||||||
|
def render("show.json", %{attachment: %Object{data: data}}) do
|
||||||
|
url = List.first(data["url"])
|
||||||
|
%{
|
||||||
|
url: url["href"],
|
||||||
|
mimetype: url["mediaType"],
|
||||||
|
id: data["uuid"],
|
||||||
|
oembed: false
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,155 @@
|
||||||
|
defmodule Pleroma.Web.TwitterAPI.StatusView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
alias Pleroma.{Activity, User, Misc}
|
||||||
|
alias Calendar.Strftime
|
||||||
|
alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, AttachmentView}
|
||||||
|
|
||||||
|
def render(
|
||||||
|
"show.json",
|
||||||
|
assigns = %{
|
||||||
|
activity: %Activity{
|
||||||
|
data: %{"type" => "Announce", "id" => id, "object" => ap_id}
|
||||||
|
},
|
||||||
|
}) do
|
||||||
|
{activity, user} = render_activity(assigns)
|
||||||
|
|
||||||
|
announced_activity = Activity.get_by_ap_id(ap_id)
|
||||||
|
text = "#{user.nickname} retweeted a status."
|
||||||
|
retweeted_status = render("show.json",
|
||||||
|
Map.merge(assigns, %{activity: announced_activity})
|
||||||
|
)
|
||||||
|
|
||||||
|
Map.merge(activity, %{
|
||||||
|
"retweeted_status" => retweeted_status,
|
||||||
|
"statusnet_html" => text,
|
||||||
|
"text" => text,
|
||||||
|
"uri" => "tag:#{id}:objectType=note"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(
|
||||||
|
"show.json",
|
||||||
|
assigns = %{activity: %Activity{
|
||||||
|
data: %{"type" => "Like", "id" => id, "object" => liked_id}
|
||||||
|
},
|
||||||
|
}) do
|
||||||
|
{activity, %User{nickname: nickname}} = render_activity(assigns)
|
||||||
|
text = "#{nickname} favorited a status."
|
||||||
|
|
||||||
|
%Activity{id: liked_activity_id} = Activity.get_by_ap_id(liked_id)
|
||||||
|
|
||||||
|
Map.merge(activity, %{
|
||||||
|
"in_reply_to_status_id" => liked_activity_id,
|
||||||
|
"statusnet_html" => text,
|
||||||
|
"text" => text,
|
||||||
|
"uri" => "tag#{id}:objectType=Favorite"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(
|
||||||
|
"show.json",
|
||||||
|
assigns = %{
|
||||||
|
activity: %Activity{
|
||||||
|
data: %{"type" => "Follow", "object" => followed_id}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) do
|
||||||
|
{activity, %User{nickname: follower_name}} = render_activity(assigns)
|
||||||
|
%User{nickname: followed_name} = User.get_cached_by_ap_id(followed_id)
|
||||||
|
text = "#{follower_name} started following #{followed_name}"
|
||||||
|
|
||||||
|
Map.merge(activity, %{
|
||||||
|
"statusnet_html" => text,
|
||||||
|
"text" => text
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(
|
||||||
|
"show.json",
|
||||||
|
assigns = %{
|
||||||
|
activity: %Activity{
|
||||||
|
data: %{
|
||||||
|
"type" => "Create", "to" => to,
|
||||||
|
"object" => object = %{
|
||||||
|
"content" => content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) do
|
||||||
|
announcement_count = object["announcement_count"] || 0
|
||||||
|
repeated = Misc.to_boolean(assigns[:for] && assigns[:for].ap_id in (object["announcements"] || []))
|
||||||
|
|
||||||
|
like_count = object["like_count"] || 0
|
||||||
|
favorited = Misc.to_boolean(assigns[:for] && assigns[:for].ap_id in (object["likes"] || []))
|
||||||
|
|
||||||
|
mentions = assigns[:mentions] || []
|
||||||
|
attentions = to
|
||||||
|
|> Enum.map(fn (ap_id) -> Enum.find(mentions, fn(user) -> ap_id == user.ap_id end) end)
|
||||||
|
|> Enum.filter(&Misc.to_boolean/1)
|
||||||
|
|> Enum.map(fn (user) -> UserView.render("short.json", Map.merge(assigns, %{user: user})) end)
|
||||||
|
|
||||||
|
attachments = (object["attachment"] || [])
|
||||||
|
{activity, _user} = render_activity(assigns)
|
||||||
|
Map.merge(activity, %{
|
||||||
|
"attachments" => render_many(attachments, AttachmentView, "show.json"),
|
||||||
|
"attentions" => attentions,
|
||||||
|
"fave_num" => like_count,
|
||||||
|
"favorited" => favorited,
|
||||||
|
"in_reply_to_status_id" => object["inReplyToStatusId"],
|
||||||
|
"is_post_verb" => true,
|
||||||
|
"repeat_num" => announcement_count,
|
||||||
|
"repeated" => repeated,
|
||||||
|
"statusnet_html" => content,
|
||||||
|
"text" => HtmlSanitizeEx.strip_tags(content)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def render("timeline.json", assigns = %{activities: activities}) do
|
||||||
|
render_many(activities, Pleroma.Web.TwitterAPI.StatusView, "show.json",
|
||||||
|
Map.merge(assigns, %{as: :activity}))
|
||||||
|
end
|
||||||
|
|
||||||
|
def conversation_id(%Activity{data: %{"context" => context}}) do
|
||||||
|
if context do
|
||||||
|
TwitterAPI.context_to_conversation_id(context)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def conversation_id(%Activity{}), do: nil
|
||||||
|
|
||||||
|
defp render_activity(assigns = %{
|
||||||
|
activity: activity = %Activity{
|
||||||
|
data: %{"published" => created_at, "id" => external_url, "actor" => actor_id}
|
||||||
|
},
|
||||||
|
}) do
|
||||||
|
user = User.get_cached_by_ap_id(actor_id)
|
||||||
|
{%{
|
||||||
|
"attachments" => [],
|
||||||
|
"attentions" => [],
|
||||||
|
"created_at" => created_at |> date_to_asctime,
|
||||||
|
"external_url" => external_url,
|
||||||
|
"fave_num" => 0,
|
||||||
|
"favorited" => false,
|
||||||
|
"id" => activity.id,
|
||||||
|
"in_reply_to_status_id" => nil,
|
||||||
|
"is_local" => true,
|
||||||
|
"is_post_verb" => false,
|
||||||
|
"repeat_num" => 0,
|
||||||
|
"repeated" => false,
|
||||||
|
"statusnet_conversation_id" => conversation_id(activity),
|
||||||
|
"source" => "api",
|
||||||
|
"user" => UserView.render("show.json", Map.merge(assigns, %{user: user}))
|
||||||
|
}, user}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp date_to_asctime(date) do
|
||||||
|
with {:ok, date, _offset} <- date |> DateTime.from_iso8601 do
|
||||||
|
Strftime.strftime!(date, "%a %b %d %H:%M:%S %z %Y")
|
||||||
|
else _e ->
|
||||||
|
""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,10 +2,10 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
def render("show.json", opts = %{user: user = %User{}}) do
|
def render("show.json", assigns = %{user: user = %User{}}) do
|
||||||
image = User.avatar_url(user)
|
image = User.avatar_url(user)
|
||||||
following = if opts[:for] do
|
following = if assigns[:for] do
|
||||||
User.following?(opts[:for], user)
|
User.following?(assigns[:for], user)
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -13,22 +13,33 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
|
||||||
user_info = User.get_cached_user_info(user)
|
user_info = User.get_cached_user_info(user)
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
"description" => user.bio,
|
||||||
|
"favourites_count" => 0,
|
||||||
|
"followers_count" => user_info[:follower_count],
|
||||||
|
"following" => following,
|
||||||
|
"friends_count" => user_info[:following_count],
|
||||||
"id" => user.id,
|
"id" => user.id,
|
||||||
"name" => user.name,
|
"name" => user.name,
|
||||||
"screen_name" => user.nickname,
|
|
||||||
"description" => user.bio,
|
|
||||||
"following" => following,
|
|
||||||
# Fake fields
|
|
||||||
"favourites_count" => 0,
|
|
||||||
"statuses_count" => user_info[:note_count],
|
|
||||||
"friends_count" => user_info[:following_count],
|
|
||||||
"followers_count" => user_info[:follower_count],
|
|
||||||
"profile_image_url" => image,
|
"profile_image_url" => image,
|
||||||
"profile_image_url_https" => image,
|
"profile_image_url_https" => image,
|
||||||
"profile_image_url_profile_size" => image,
|
"profile_image_url_profile_size" => image,
|
||||||
"profile_image_url_original" => image,
|
"profile_image_url_original" => image,
|
||||||
"rights" => %{},
|
"rights" => %{},
|
||||||
|
"screen_name" => user.nickname,
|
||||||
|
"statuses_count" => user_info[:note_count],
|
||||||
"statusnet_profile_url" => user.ap_id
|
"statusnet_profile_url" => user.ap_id
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render("short.json", %{user: %User{
|
||||||
|
nickname: nickname, id: id, ap_id: ap_id, name: name
|
||||||
|
}}) do
|
||||||
|
%{
|
||||||
|
"fullname" => name,
|
||||||
|
"id" => id,
|
||||||
|
"ostatus_uri" => ap_id,
|
||||||
|
"profile_url" => ap_id,
|
||||||
|
"screen_name" => nickname
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,8 @@ defmodule Pleroma.Builders.ActivityBuilder do
|
||||||
"object" => %{
|
"object" => %{
|
||||||
"type" => "Note",
|
"type" => "Note",
|
||||||
"content" => "test"
|
"content" => "test"
|
||||||
}
|
},
|
||||||
|
"type" => "Create"
|
||||||
}
|
}
|
||||||
Map.merge(activity, data)
|
Map.merge(activity, data)
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,7 +23,7 @@ defmodule Pleroma.Factory do
|
||||||
"id" => Pleroma.Web.ActivityPub.ActivityPub.generate_object_id,
|
"id" => Pleroma.Web.ActivityPub.ActivityPub.generate_object_id,
|
||||||
"actor" => user.ap_id,
|
"actor" => user.ap_id,
|
||||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||||
"published_at" => Misc.make_date(),
|
"published" => Misc.make_date(),
|
||||||
"likes" => [],
|
"likes" => [],
|
||||||
"like_count" => 0,
|
"like_count" => 0,
|
||||||
"context" => "2hu"
|
"context" => "2hu"
|
||||||
|
@ -42,7 +42,7 @@ defmodule Pleroma.Factory do
|
||||||
"actor" => note.data["actor"],
|
"actor" => note.data["actor"],
|
||||||
"to" => note.data["to"],
|
"to" => note.data["to"],
|
||||||
"object" => note.data,
|
"object" => note.data,
|
||||||
"published_at" => Misc.make_date(),
|
"published" => Misc.make_date(),
|
||||||
"context" => note.data["context"]
|
"context" => note.data["context"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ defmodule Pleroma.Factory do
|
||||||
"actor" => user.ap_id,
|
"actor" => user.ap_id,
|
||||||
"type" => "Like",
|
"type" => "Like",
|
||||||
"object" => note_activity.data["object"]["id"],
|
"object" => note_activity.data["object"]["id"],
|
||||||
"published_at" => Misc.make_date()
|
"published" => Misc.make_date()
|
||||||
}
|
}
|
||||||
|
|
||||||
%Pleroma.Activity{
|
%Pleroma.Activity{
|
||||||
|
@ -77,7 +77,7 @@ defmodule Pleroma.Factory do
|
||||||
"actor" => follower.ap_id,
|
"actor" => follower.ap_id,
|
||||||
"type" => "Follow",
|
"type" => "Follow",
|
||||||
"object" => followed.ap_id,
|
"object" => followed.ap_id,
|
||||||
"published_at" => Misc.make_date()
|
"published" => Misc.make_date()
|
||||||
}
|
}
|
||||||
|
|
||||||
%Pleroma.Activity{
|
%Pleroma.Activity{
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
|
|
||||||
use Pleroma.DataCase
|
|
||||||
alias Pleroma.{User, Activity, Object}
|
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter, ObjectRepresenter}
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
|
||||||
alias Pleroma.Builders.UserBuilder
|
|
||||||
import Pleroma.Factory
|
|
||||||
|
|
||||||
test "an announce activity" do
|
|
||||||
user = insert(:user)
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
activity_actor = Repo.get_by(User, ap_id: note_activity.data["actor"])
|
|
||||||
object = Object.get_by_ap_id(note_activity.data["object"]["id"])
|
|
||||||
|
|
||||||
{:ok, announce_activity, _object} = ActivityPub.announce(user, object)
|
|
||||||
note_activity = Activity.get_by_ap_id(note_activity.data["id"])
|
|
||||||
|
|
||||||
status = ActivityRepresenter.to_map(announce_activity, %{users: [user, activity_actor], announced_activity: note_activity, for: user})
|
|
||||||
|
|
||||||
assert status["id"] == announce_activity.id
|
|
||||||
assert status["user"] == UserRepresenter.to_map(user, %{for: user})
|
|
||||||
|
|
||||||
retweeted_status = ActivityRepresenter.to_map(note_activity, %{user: activity_actor, for: user})
|
|
||||||
assert retweeted_status["repeated"] == true
|
|
||||||
assert retweeted_status["id"] == note_activity.id
|
|
||||||
assert status["statusnet_conversation_id"] == retweeted_status["statusnet_conversation_id"]
|
|
||||||
|
|
||||||
assert status["retweeted_status"] == retweeted_status
|
|
||||||
end
|
|
||||||
|
|
||||||
test "a like activity" do
|
|
||||||
user = insert(:user)
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
object = Object.get_by_ap_id(note_activity.data["object"]["id"])
|
|
||||||
|
|
||||||
{:ok, like_activity, _object} = ActivityPub.like(user, object)
|
|
||||||
status = ActivityRepresenter.to_map(like_activity, %{user: user, liked_activity: note_activity})
|
|
||||||
|
|
||||||
assert status["id"] == like_activity.id
|
|
||||||
assert status["in_reply_to_status_id"] == note_activity.id
|
|
||||||
|
|
||||||
note_activity = Activity.get_by_ap_id(note_activity.data["id"])
|
|
||||||
activity_actor = Repo.get_by(User, ap_id: note_activity.data["actor"])
|
|
||||||
liked_status = ActivityRepresenter.to_map(note_activity, %{user: activity_actor, for: user})
|
|
||||||
assert liked_status["favorited"] == true
|
|
||||||
end
|
|
||||||
|
|
||||||
test "an activity" do
|
|
||||||
{:ok, user} = UserBuilder.insert
|
|
||||||
# {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
|
|
||||||
mentioned_user = insert(:user, %{nickname: "shp"})
|
|
||||||
|
|
||||||
# {:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]})
|
|
||||||
follower = insert(:user, %{following: [User.ap_followers(user)]})
|
|
||||||
|
|
||||||
object = %Object{
|
|
||||||
data: %{
|
|
||||||
"type" => "Image",
|
|
||||||
"url" => [
|
|
||||||
%{
|
|
||||||
"type" => "Link",
|
|
||||||
"mediaType" => "image/jpg",
|
|
||||||
"href" => "http://example.org/image.jpg"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"uuid" => 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
content_html = "Some content mentioning <a href='#{mentioned_user.ap_id}'>@shp</shp>"
|
|
||||||
content = HtmlSanitizeEx.strip_tags(content_html)
|
|
||||||
date = DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC") |> DateTime.to_iso8601
|
|
||||||
|
|
||||||
{:ok, convo_object} = Object.context_mapping("2hu") |> Repo.insert
|
|
||||||
|
|
||||||
activity = %Activity{
|
|
||||||
id: 1,
|
|
||||||
data: %{
|
|
||||||
"type" => "Create",
|
|
||||||
"id" => "id",
|
|
||||||
"to" => [
|
|
||||||
User.ap_followers(user),
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public",
|
|
||||||
mentioned_user.ap_id
|
|
||||||
],
|
|
||||||
"actor" => User.ap_id(user),
|
|
||||||
"object" => %{
|
|
||||||
"published" => date,
|
|
||||||
"type" => "Note",
|
|
||||||
"content" => content_html,
|
|
||||||
"inReplyToStatusId" => 213123,
|
|
||||||
"attachment" => [
|
|
||||||
object
|
|
||||||
],
|
|
||||||
"like_count" => 5,
|
|
||||||
"announcement_count" => 3,
|
|
||||||
"context" => "2hu"
|
|
||||||
},
|
|
||||||
"published" => date,
|
|
||||||
"context" => "2hu"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
expected_status = %{
|
|
||||||
"id" => activity.id,
|
|
||||||
"user" => UserRepresenter.to_map(user, %{for: follower}),
|
|
||||||
"is_local" => true,
|
|
||||||
"attentions" => [],
|
|
||||||
"statusnet_html" => content_html,
|
|
||||||
"text" => content,
|
|
||||||
"is_post_verb" => true,
|
|
||||||
"created_at" => "Tue May 24 13:26:08 +0000 2016",
|
|
||||||
"in_reply_to_status_id" => 213123,
|
|
||||||
"statusnet_conversation_id" => convo_object.id,
|
|
||||||
"attachments" => [
|
|
||||||
ObjectRepresenter.to_map(object)
|
|
||||||
],
|
|
||||||
"attentions" => [
|
|
||||||
UserRepresenter.to_map(mentioned_user, %{for: follower})
|
|
||||||
],
|
|
||||||
"fave_num" => 5,
|
|
||||||
"repeat_num" => 3,
|
|
||||||
"favorited" => false,
|
|
||||||
"repeated" => false,
|
|
||||||
"external_url" => activity.data["id"]
|
|
||||||
}
|
|
||||||
|
|
||||||
assert ActivityRepresenter.to_map(activity, %{user: user, for: follower, mentioned: [mentioned_user]}) == expected_status
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,31 +0,0 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.Representers.ObjectReprenterTest do
|
|
||||||
use Pleroma.DataCase
|
|
||||||
|
|
||||||
alias Pleroma.Object
|
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
|
|
||||||
|
|
||||||
test "represent an image attachment" do
|
|
||||||
object = %Object{
|
|
||||||
id: 5,
|
|
||||||
data: %{
|
|
||||||
"type" => "Image",
|
|
||||||
"url" => [
|
|
||||||
%{
|
|
||||||
"mediaType" => "sometype",
|
|
||||||
"href" => "someurl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"uuid" => 6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expected_object = %{
|
|
||||||
id: 6,
|
|
||||||
url: "someurl",
|
|
||||||
mimetype: "sometype",
|
|
||||||
oembed: false
|
|
||||||
}
|
|
||||||
|
|
||||||
assert expected_object == ObjectRepresenter.to_map(object)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,82 +0,0 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.Representers.UserRepresenterTest do
|
|
||||||
use Pleroma.DataCase
|
|
||||||
|
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.UserRepresenter
|
|
||||||
alias Pleroma.Builders.UserBuilder
|
|
||||||
|
|
||||||
import Pleroma.Factory
|
|
||||||
|
|
||||||
setup do
|
|
||||||
user = insert(:user)
|
|
||||||
[user: user]
|
|
||||||
end
|
|
||||||
|
|
||||||
test "A user with an avatar object", %{user: user} do
|
|
||||||
image = "image"
|
|
||||||
user = %{ user | avatar: %{ "url" => [%{"href" => image}] }}
|
|
||||||
represented = UserRepresenter.to_map(user)
|
|
||||||
assert represented["profile_image_url"] == image
|
|
||||||
end
|
|
||||||
|
|
||||||
test "A user" do
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
|
||||||
follower = insert(:user)
|
|
||||||
second_follower = insert(:user)
|
|
||||||
|
|
||||||
User.follow(follower, user)
|
|
||||||
User.follow(second_follower, user)
|
|
||||||
User.follow(user, follower)
|
|
||||||
|
|
||||||
user = Repo.get!(User, user.id)
|
|
||||||
|
|
||||||
image = "https://placehold.it/48x48"
|
|
||||||
|
|
||||||
represented = %{
|
|
||||||
"id" => user.id,
|
|
||||||
"name" => user.name,
|
|
||||||
"screen_name" => user.nickname,
|
|
||||||
"description" => user.bio,
|
|
||||||
# Fake fields
|
|
||||||
"favourites_count" => 0,
|
|
||||||
"statuses_count" => 1,
|
|
||||||
"friends_count" => 1,
|
|
||||||
"followers_count" => 2,
|
|
||||||
"profile_image_url" => image,
|
|
||||||
"profile_image_url_https" => image,
|
|
||||||
"profile_image_url_profile_size" => image,
|
|
||||||
"profile_image_url_original" => image,
|
|
||||||
"following" => false,
|
|
||||||
"rights" => %{},
|
|
||||||
"statusnet_profile_url" => user.ap_id
|
|
||||||
}
|
|
||||||
|
|
||||||
assert represented == UserRepresenter.to_map(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "A user for a given other follower", %{user: user} do
|
|
||||||
{:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]})
|
|
||||||
image = "https://placehold.it/48x48"
|
|
||||||
represented = %{
|
|
||||||
"id" => user.id,
|
|
||||||
"name" => user.name,
|
|
||||||
"screen_name" => user.nickname,
|
|
||||||
"description" => user.bio,
|
|
||||||
# Fake fields
|
|
||||||
"favourites_count" => 0,
|
|
||||||
"statuses_count" => 0,
|
|
||||||
"friends_count" => 0,
|
|
||||||
"followers_count" => 1,
|
|
||||||
"profile_image_url" => image,
|
|
||||||
"profile_image_url_https" => image,
|
|
||||||
"profile_image_url_profile_size" => image,
|
|
||||||
"profile_image_url_original" => image,
|
|
||||||
"following" => true,
|
|
||||||
"rights" => %{},
|
|
||||||
"statusnet_profile_url" => user.ap_id
|
|
||||||
}
|
|
||||||
|
|
||||||
assert represented == UserRepresenter.to_map(user, %{for: follower})
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,9 +1,9 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter}
|
|
||||||
alias Pleroma.Builders.{ActivityBuilder, UserBuilder}
|
alias Pleroma.Builders.{ActivityBuilder, UserBuilder}
|
||||||
alias Pleroma.{Repo, Activity, User, Object}
|
alias Pleroma.{Repo, Activity, User, Object}
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
alias Pleroma.Web.TwitterAPI.{UserView, StatusView}
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
|> with_credentials(user.nickname, "test")
|
|> with_credentials(user.nickname, "test")
|
||||||
|> post("/api/account/verify_credentials.json")
|
|> post("/api/account/verify_credentials.json")
|
||||||
|
|
||||||
assert json_response(conn, 200) == UserRepresenter.to_map(user)
|
assert json_response(conn, 200) == UserView.render("show.json", %{user: user})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
assert json_response(conn, 400) == error_response
|
assert json_response(conn, 400) == error_response
|
||||||
|
|
||||||
conn = conn_with_creds |> post(request_path, %{ status: "Nice meme." })
|
conn = conn_with_creds |> post(request_path, %{ status: "Nice meme." })
|
||||||
assert json_response(conn, 200) == ActivityRepresenter.to_map(Repo.one(Activity), %{user: user})
|
assert json_response(conn, 200) == StatusView.render("show.json", %{activity: Repo.one(Activity)})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -70,14 +70,13 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
test "returns one status", %{conn: conn} do
|
test "returns one status", %{conn: conn} do
|
||||||
{:ok, user} = UserBuilder.insert
|
{:ok, user} = UserBuilder.insert
|
||||||
{:ok, activity} = ActivityBuilder.insert(%{}, %{user: user})
|
{:ok, activity} = ActivityBuilder.insert(%{}, %{user: user})
|
||||||
actor = Repo.get_by!(User, ap_id: activity.data["actor"])
|
|
||||||
|
|
||||||
conn = conn
|
conn = conn
|
||||||
|> get("/api/statuses/show/#{activity.id}.json")
|
|> get("/api/statuses/show/#{activity.id}.json")
|
||||||
|
|
||||||
response = json_response(conn, 200)
|
response = json_response(conn, 200)
|
||||||
|
|
||||||
assert response == ActivityRepresenter.to_map(activity, %{user: actor})
|
assert response == StatusView.render("show.json", %{activity: activity})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -122,7 +121,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
response = json_response(conn, 200)
|
response = json_response(conn, 200)
|
||||||
|
|
||||||
assert length(response) == 10
|
assert length(response) == 10
|
||||||
assert response == Enum.map(returned_activities, fn (activity) -> ActivityRepresenter.to_map(activity, %{user: User.get_cached_by_ap_id(activity.data["actor"]), for: current_user}) end)
|
assert response == StatusView.render("timeline.json", %{activities: returned_activities, for: current_user})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -143,7 +142,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
response = json_response(conn, 200)
|
response = json_response(conn, 200)
|
||||||
|
|
||||||
assert length(response) == 1
|
assert length(response) == 1
|
||||||
assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user, mentioned: [current_user]})
|
assert Enum.at(response, 0) == StatusView.render("show.json", %{activity: activity})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -161,7 +160,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
|
conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
|
||||||
response = json_response(conn, 200)
|
response = json_response(conn, 200)
|
||||||
assert length(response) == 1
|
assert length(response) == 1
|
||||||
assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
|
assert Enum.at(response, 0) == StatusView.render("show.json", %{activity: activity})
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with screen_name", %{conn: conn} do
|
test "with screen_name", %{conn: conn} do
|
||||||
|
@ -171,7 +170,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
|
conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
|
||||||
response = json_response(conn, 200)
|
response = json_response(conn, 200)
|
||||||
assert length(response) == 1
|
assert length(response) == 1
|
||||||
assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
|
assert Enum.at(response, 0) == StatusView.render("show.json", %{activity: activity})
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with credentials", %{conn: conn, user: current_user} do
|
test "with credentials", %{conn: conn, user: current_user} do
|
||||||
|
@ -183,7 +182,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
response = json_response(conn, 200)
|
response = json_response(conn, 200)
|
||||||
|
|
||||||
assert length(response) == 1
|
assert length(response) == 1
|
||||||
assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
|
assert Enum.at(response, 0) == StatusView.render("show.json", %{activity: activity})
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with credentials with user_id", %{conn: conn, user: current_user} do
|
test "with credentials with user_id", %{conn: conn, user: current_user} do
|
||||||
|
@ -196,7 +195,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
response = json_response(conn, 200)
|
response = json_response(conn, 200)
|
||||||
|
|
||||||
assert length(response) == 1
|
assert length(response) == 1
|
||||||
assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
|
assert Enum.at(response, 0) == StatusView.render("show.json", %{activity: activity})
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with credentials screen_name", %{conn: conn, user: current_user} do
|
test "with credentials screen_name", %{conn: conn, user: current_user} do
|
||||||
|
@ -209,7 +208,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
response = json_response(conn, 200)
|
response = json_response(conn, 200)
|
||||||
|
|
||||||
assert length(response) == 1
|
assert length(response) == 1
|
||||||
assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
|
assert Enum.at(response, 0) == StatusView.render("show.json", %{activity: activity})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -229,7 +228,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
|
|
||||||
current_user = Repo.get(User, current_user.id)
|
current_user = Repo.get(User, current_user.id)
|
||||||
assert current_user.following == [User.ap_followers(followed)]
|
assert current_user.following == [User.ap_followers(followed)]
|
||||||
assert json_response(conn, 200) == UserRepresenter.to_map(followed, %{for: current_user})
|
assert json_response(conn, 200) == UserView.render("show.json", %{user: followed, for: current_user})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -253,7 +252,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
|
|
||||||
current_user = Repo.get(User, current_user.id)
|
current_user = Repo.get(User, current_user.id)
|
||||||
assert current_user.following == []
|
assert current_user.following == []
|
||||||
assert json_response(conn, 200) == UserRepresenter.to_map(followed, %{for: current_user})
|
assert json_response(conn, 200) == UserView.render("show.json", %{user: followed, for: current_user})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -278,7 +277,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
|
|
||||||
current_user = Repo.get(User, current_user.id)
|
current_user = Repo.get(User, current_user.id)
|
||||||
assert is_map(current_user.avatar)
|
assert is_map(current_user.avatar)
|
||||||
assert json_response(conn, 200) == UserRepresenter.to_map(current_user, %{for: current_user})
|
assert json_response(conn, 200) == UserView.render("show.json", %{user: current_user, for: current_user})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -339,15 +338,14 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
response = conn
|
response = conn
|
||||||
|> with_credentials(user.nickname, "test")
|
|> with_credentials(user.nickname, "test")
|
||||||
|> post(request_path)
|
|> post(request_path)
|
||||||
assert json_response(response, 400) == %{"error" => "You cannot repeat your own notice.",
|
assert json_response(response, 400) == %{"error" => "You cannot repeat your own status.",
|
||||||
"request" => request_path}
|
"request" => request_path}
|
||||||
|
|
||||||
response = conn
|
response = conn
|
||||||
|> with_credentials(current_user.nickname, "test")
|
|> with_credentials(current_user.nickname, "test")
|
||||||
|> post(request_path)
|
|> post(request_path)
|
||||||
activity = Repo.get(Activity, note_activity.id)
|
activity = Repo.get(Activity, note_activity.id)
|
||||||
activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
|
assert json_response(response, 200) == StatusView.render("show.json", %{activity: activity, for: current_user})
|
||||||
assert json_response(response, 200) == ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -368,7 +366,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
user = json_response(conn, 200)
|
user = json_response(conn, 200)
|
||||||
|
|
||||||
fetched_user = Repo.get_by(User, nickname: "lain")
|
fetched_user = Repo.get_by(User, nickname: "lain")
|
||||||
assert user == UserRepresenter.to_map(fetched_user)
|
assert user == UserView.render("show.json", %{user: fetched_user})
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns errors on a problem", %{conn: conn} do
|
test "it returns errors on a problem", %{conn: conn} do
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
|
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
alias Pleroma.Builders.{UserBuilder, ActivityBuilder}
|
alias Pleroma.Builders.{UserBuilder}
|
||||||
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
||||||
alias Pleroma.{Activity, User, Object, Repo}
|
alias Pleroma.{Activity, User, Object, Repo}
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.{ActivityRepresenter, UserRepresenter}
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
@ -73,113 +71,6 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
|
||||||
assert Enum.member?(get_in(reply.data, ["to"]), "some_cool_id")
|
assert Enum.member?(get_in(reply.data, ["to"]), "some_cool_id")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "fetch public statuses, excluding remote ones." do
|
|
||||||
%{ public: activity, user: user } = ActivityBuilder.public_and_non_public
|
|
||||||
insert(:note_activity, %{local: false})
|
|
||||||
|
|
||||||
follower = insert(:user, following: [User.ap_followers(user)])
|
|
||||||
|
|
||||||
statuses = TwitterAPI.fetch_public_statuses(follower)
|
|
||||||
|
|
||||||
assert length(statuses) == 1
|
|
||||||
assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: user, for: follower})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "fetch whole known network statuses" do
|
|
||||||
%{ public: activity, user: user } = ActivityBuilder.public_and_non_public
|
|
||||||
insert(:note_activity, %{local: false})
|
|
||||||
|
|
||||||
follower = insert(:user, following: [User.ap_followers(user)])
|
|
||||||
|
|
||||||
statuses = TwitterAPI.fetch_public_and_external_statuses(follower)
|
|
||||||
|
|
||||||
assert length(statuses) == 2
|
|
||||||
assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: user, for: follower})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "fetch friends' statuses" do
|
|
||||||
user = insert(:user, %{following: ["someguy/followers"]})
|
|
||||||
{:ok, activity} = ActivityBuilder.insert(%{"to" => ["someguy/followers"]})
|
|
||||||
{:ok, direct_activity} = ActivityBuilder.insert(%{"to" => [user.ap_id]})
|
|
||||||
|
|
||||||
statuses = TwitterAPI.fetch_friend_statuses(user)
|
|
||||||
|
|
||||||
activity_user = Repo.get_by(User, ap_id: activity.data["actor"])
|
|
||||||
direct_activity_user = Repo.get_by(User, ap_id: direct_activity.data["actor"])
|
|
||||||
|
|
||||||
assert length(statuses) == 2
|
|
||||||
assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: activity_user})
|
|
||||||
assert Enum.at(statuses, 1) == ActivityRepresenter.to_map(direct_activity, %{user: direct_activity_user, mentioned: [user]})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "fetch user's mentions" do
|
|
||||||
user = insert(:user)
|
|
||||||
{:ok, activity} = ActivityBuilder.insert(%{"to" => [user.ap_id]})
|
|
||||||
activity_user = Repo.get_by(User, ap_id: activity.data["actor"])
|
|
||||||
|
|
||||||
statuses = TwitterAPI.fetch_mentions(user)
|
|
||||||
|
|
||||||
assert length(statuses) == 1
|
|
||||||
assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: activity_user, mentioned: [user]})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "get a user by params" do
|
|
||||||
user1_result = {:ok, user1} = UserBuilder.insert(%{ap_id: "some id", email: "test@pleroma"})
|
|
||||||
{:ok, user2} = UserBuilder.insert(%{ap_id: "some other id", nickname: "testname2", email: "test2@pleroma"})
|
|
||||||
|
|
||||||
assert {:error, "You need to specify screen_name or user_id"} == TwitterAPI.get_user(nil, nil)
|
|
||||||
assert user1_result == TwitterAPI.get_user(nil, %{"user_id" => user1.id})
|
|
||||||
assert user1_result == TwitterAPI.get_user(nil, %{"screen_name" => user1.nickname})
|
|
||||||
assert user1_result == TwitterAPI.get_user(user1, nil)
|
|
||||||
assert user1_result == TwitterAPI.get_user(user2, %{"user_id" => user1.id})
|
|
||||||
assert user1_result == TwitterAPI.get_user(user2, %{"screen_name" => user1.nickname})
|
|
||||||
assert {:error, "No user with such screen_name"} == TwitterAPI.get_user(nil, %{"screen_name" => "Satan"})
|
|
||||||
assert {:error, "No user with such user_id"} == TwitterAPI.get_user(nil, %{"user_id" => 666})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "fetch user's statuses" do
|
|
||||||
{:ok, user1} = UserBuilder.insert(%{ap_id: "some id", email: "test@pleroma"})
|
|
||||||
{:ok, user2} = UserBuilder.insert(%{ap_id: "some other id", nickname: "testname2", email: "test2@pleroma"})
|
|
||||||
|
|
||||||
{:ok, status1} = ActivityBuilder.insert(%{"id" => 1}, %{user: user1})
|
|
||||||
{:ok, status2} = ActivityBuilder.insert(%{"id" => 2}, %{user: user2})
|
|
||||||
|
|
||||||
user1_statuses = TwitterAPI.fetch_user_statuses(user1, %{"actor_id" => user1.ap_id})
|
|
||||||
|
|
||||||
assert length(user1_statuses) == 1
|
|
||||||
assert Enum.at(user1_statuses, 0) == ActivityRepresenter.to_map(status1, %{user: user1})
|
|
||||||
|
|
||||||
user2_statuses = TwitterAPI.fetch_user_statuses(user1, %{"actor_id" => user2.ap_id})
|
|
||||||
|
|
||||||
assert length(user2_statuses) == 1
|
|
||||||
assert Enum.at(user2_statuses, 0) == ActivityRepresenter.to_map(status2, %{user: user2})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "fetch a single status" do
|
|
||||||
{:ok, activity} = ActivityBuilder.insert()
|
|
||||||
{:ok, user} = UserBuilder.insert()
|
|
||||||
actor = Repo.get_by!(User, ap_id: activity.data["actor"])
|
|
||||||
|
|
||||||
status = TwitterAPI.fetch_status(user, activity.id)
|
|
||||||
|
|
||||||
assert status == ActivityRepresenter.to_map(activity, %{for: user, user: actor})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "fetch statuses in a context using the conversation id" do
|
|
||||||
{:ok, user} = UserBuilder.insert()
|
|
||||||
{:ok, activity} = ActivityBuilder.insert(%{"context" => "2hu"})
|
|
||||||
{:ok, activity_two} = ActivityBuilder.insert(%{"context" => "2hu"})
|
|
||||||
{:ok, _activity_three} = ActivityBuilder.insert(%{"context" => "3hu"})
|
|
||||||
|
|
||||||
{:ok, object} = Object.context_mapping("2hu") |> Repo.insert
|
|
||||||
|
|
||||||
statuses = TwitterAPI.fetch_conversation(user, object.id)
|
|
||||||
|
|
||||||
assert length(statuses) == 2
|
|
||||||
assert Enum.at(statuses, 0)["id"] == activity.id
|
|
||||||
assert Enum.at(statuses, 1)["id"] == activity_two.id
|
|
||||||
end
|
|
||||||
|
|
||||||
test "upload a file" do
|
test "upload a file" do
|
||||||
file = %Plug.Upload{content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), filename: "an_image.jpg"}
|
file = %Plug.Upload{content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), filename: "an_image.jpg"}
|
||||||
|
|
||||||
|
@ -214,51 +105,6 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
|
||||||
assert TwitterAPI.add_user_links(text, mentions) == expected_text
|
assert TwitterAPI.add_user_links(text, mentions) == expected_text
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it favorites a status, returns the updated status" do
|
|
||||||
user = insert(:user)
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
activity_user = Repo.get_by!(User, ap_id: note_activity.data["actor"])
|
|
||||||
|
|
||||||
{:ok, status} = TwitterAPI.favorite(user, note_activity)
|
|
||||||
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
|
|
||||||
|
|
||||||
assert status == ActivityRepresenter.to_map(updated_activity, %{user: activity_user, for: user})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it unfavorites a status, returns the updated status" do
|
|
||||||
user = insert(:user)
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
activity_user = Repo.get_by!(User, ap_id: note_activity.data["actor"])
|
|
||||||
object = Object.get_by_ap_id(note_activity.data["object"]["id"])
|
|
||||||
|
|
||||||
{:ok, _like_activity, _object } = ActivityPub.like(user, object)
|
|
||||||
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
|
|
||||||
assert ActivityRepresenter.to_map(updated_activity, %{user: activity_user, for: user})["fave_num"] == 1
|
|
||||||
|
|
||||||
{:ok, status} = TwitterAPI.unfavorite(user, note_activity)
|
|
||||||
|
|
||||||
assert status["fave_num"] == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it retweets a status and returns the retweet" do
|
|
||||||
user = insert(:user)
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
activity_user = Repo.get_by!(User, ap_id: note_activity.data["actor"])
|
|
||||||
|
|
||||||
{:ok, status} = TwitterAPI.retweet(user, note_activity)
|
|
||||||
updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
|
|
||||||
|
|
||||||
assert status == ActivityRepresenter.to_map(updated_activity, %{user: activity_user, for: user})
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it assigns an integer conversation_id" do
|
|
||||||
note_activity = insert(:note_activity)
|
|
||||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
|
||||||
status = ActivityRepresenter.to_map(note_activity, %{user: user})
|
|
||||||
|
|
||||||
assert is_number(status["statusnet_conversation_id"])
|
|
||||||
end
|
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
Supervisor.terminate_child(Pleroma.Supervisor, Cachex)
|
Supervisor.terminate_child(Pleroma.Supervisor, Cachex)
|
||||||
Supervisor.restart_child(Pleroma.Supervisor, Cachex)
|
Supervisor.restart_child(Pleroma.Supervisor, Cachex)
|
||||||
|
|
Loading…
Reference in New Issue