diff options
author | dtluna <dtluna@openmailbox.org> | 2017-04-16 17:18:34 +0300 |
---|---|---|
committer | dtluna <dtluna@openmailbox.org> | 2017-04-16 17:18:34 +0300 |
commit | ef5033d7a7f744607235e974c7beb96b014c2b61 (patch) | |
tree | b885af1dedf3978ad265cf769713915d04510d0f /lib | |
parent | a8e50d602ba25b2062e0e676e1dd115da64c2565 (diff) | |
parent | e158e32124a62f2c93a8910bf3edc4519c4a13e6 (diff) | |
download | pleroma-ef5033d7a7f744607235e974c7beb96b014c2b61.tar.gz |
Merge branch 'develop' of ssh.gitgud.io:lambadalambda/pleroma into bugfix/repeated-follow-unfollow
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mix/tasks/register_user.ex | 8 | ||||
-rw-r--r-- | lib/pleroma/activity.ex | 12 | ||||
-rw-r--r-- | lib/pleroma/application.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/upload.ex | 25 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 37 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 107 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/representers/activity_representer.ex | 57 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/representers/user_representer.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api.ex | 138 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api_controller.ex | 58 |
11 files changed, 431 insertions, 28 deletions
diff --git a/lib/mix/tasks/register_user.ex b/lib/mix/tasks/register_user.ex index e2f36c34c..48236439b 100644 --- a/lib/mix/tasks/register_user.ex +++ b/lib/mix/tasks/register_user.ex @@ -6,15 +6,17 @@ defmodule Mix.Tasks.RegisterUser do @shortdoc "Register user" def run([name, nickname, email, bio, password]) do ensure_started(Repo, []) - user = %User{ + + params = %{ name: name, nickname: nickname, email: email, - password_hash: Comeonin.Pbkdf2.hashpwsalt(password), + password: password, + password_confirmation: password, bio: bio } - user = %{ user | ap_id: User.ap_id(user) } + user = User.register_changeset(%User{}, params) Repo.insert!(user) end diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index c4efc6283..46568bb13 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -1,9 +1,21 @@ defmodule Pleroma.Activity do use Ecto.Schema + alias Pleroma.{Repo, Activity} + import Ecto.Query schema "activities" do field :data, :map timestamps() end + + def get_by_ap_id(ap_id) do + Repo.one(from activity in Activity, + where: fragment("? @> ?", activity.data, ^%{id: ap_id})) + end + + def all_by_object_ap_id(ap_id) do + Repo.all(from activity in Activity, + where: fragment("? @> ?", activity.data, ^%{object: %{id: ap_id}})) + end end diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index e88a85196..e5bd17ced 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -14,6 +14,10 @@ defmodule Pleroma.Application do supervisor(Pleroma.Web.Endpoint, []), # Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3) # worker(Pleroma.Worker, [arg1, arg2, arg3]), + supervisor(ConCache, [[ + ttl_check: :timer.seconds(1), + ttl: :timer.seconds(5) + ], [name: :users]]) ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index d22421d37..3aabf8157 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -18,6 +18,31 @@ defmodule Pleroma.Upload do } end + def store(%{"img" => "data:image/" <> image_data}) do + parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data) + data = Base.decode64!(parsed["data"]) + uuid = Ecto.UUID.generate + upload_folder = Path.join(upload_path(), uuid) + File.mkdir_p!(upload_folder) + filename = Base.encode16(:crypto.hash(:sha256, data)) <> ".#{parsed["filetype"]}" + result_file = Path.join(upload_folder, filename) + + File.write!(result_file, data) + + content_type = "image/#{parsed["filetype"]}" + + %{ + "type" => "Image", + "url" => [%{ + "type" => "Link", + "mediaType" => content_type, + "href" => url_for(Path.join(uuid, filename)) + }], + "name" => filename, + "uuid" => uuid + } + end + defp upload_path do Application.get_env(:pleroma, Pleroma.Upload) |> Keyword.fetch!(:uploads) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 5f5bc1c38..418522172 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -9,8 +9,11 @@ defmodule Pleroma.User do field :name, :string field :nickname, :string field :password_hash, :string + field :password, :string, virtual: true + field :password_confirmation, :string, virtual: true field :following, { :array, :string }, default: [] field :ap_id, :string + field :avatar, :map timestamps() end @@ -29,6 +32,27 @@ defmodule Pleroma.User do |> validate_required([:following]) end + def register_changeset(struct, params \\ %{}) do + changeset = struct + |> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation]) + |> validate_required([:bio, :email, :name, :nickname, :password, :password_confirmation]) + |> validate_confirmation(:password) + |> unique_constraint(:email) + |> unique_constraint(:nickname) + + if changeset.valid? do + hashed = Comeonin.Pbkdf2.hashpwsalt(changeset.changes[:password]) + ap_id = User.ap_id(%User{nickname: changeset.changes[:nickname]}) + followers = User.ap_followers(%User{nickname: changeset.changes[:nickname]}) + changeset + |> put_change(:password_hash, hashed) + |> put_change(:ap_id, ap_id) + |> put_change(:following, [followers]) + else + changeset + end + end + def follow(%User{} = follower, %User{} = followed) do ap_followers = User.ap_followers(followed) if following?(follower, followed) do @@ -61,4 +85,17 @@ defmodule Pleroma.User do def following?(%User{} = follower, %User{} = followed) do Enum.member?(follower.following, User.ap_followers(followed)) end + + def get_cached_by_ap_id(ap_id) do + ConCache.get_or_store(:users, "ap_id:#{ap_id}", fn() -> + # Return false so the cache will store it. + Repo.get_by(User, ap_id: ap_id) || false + end) + end + + def get_cached_by_nickname(nickname) do + ConCache.get_or_store(:users, "nickname:#{nickname}", fn() -> + Repo.get_by(User, nickname: nickname) || false + end) + end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 75e4101f2..125473b96 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1,10 +1,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do alias Pleroma.Repo - alias Pleroma.{Activity, Object, Upload} + alias Pleroma.{Activity, Object, Upload, User} import Ecto.Query def insert(map) when is_map(map) do - map = Map.put_new_lazy(map, "id", &generate_activity_id/0) + map = map + |> Map.put_new_lazy("id", &generate_activity_id/0) + |> Map.put_new_lazy("published", &make_date/0) map = if is_map(map["object"]) do object = Map.put_new_lazy(map["object"], "id", &generate_object_id/0) @@ -17,6 +19,77 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do Repo.insert(%Activity{data: map}) end + def like(%User{ap_id: ap_id} = user, %Object{data: %{ "id" => id}} = object) do + cond do + # There's already a like here, so return the original activity. + ap_id in (object.data["likes"] || []) -> + query = from activity in Activity, + where: fragment("? @> ?", activity.data, ^%{actor: ap_id, object: id, type: "Like"}) + + activity = Repo.one(query) + {:ok, activity, object} + true -> + data = %{ + "type" => "Like", + "actor" => ap_id, + "object" => id, + "to" => [User.ap_followers(user), object.data["actor"]] + } + + {:ok, activity} = insert(data) + + likes = [ap_id | (object.data["likes"] || [])] |> Enum.uniq + + new_data = object.data + |> Map.put("like_count", length(likes)) + |> Map.put("likes", likes) + + changeset = Ecto.Changeset.change(object, data: new_data) + {:ok, object} = Repo.update(changeset) + + update_object_in_activities(object) + + {:ok, activity, object} + end + end + + defp update_object_in_activities(%{data: %{"id" => id}} = object) do + # Update activities that already had this. Could be done in a seperate process. + relevant_activities = Activity.all_by_object_ap_id(id) + Enum.map(relevant_activities, fn (activity) -> + new_activity_data = activity.data |> Map.put("object", object.data) + changeset = Ecto.Changeset.change(activity, data: new_activity_data) + Repo.update(changeset) + end) + end + + def unlike(%User{ap_id: ap_id}, %Object{data: %{ "id" => id}} = object) do + query = from activity in Activity, + where: fragment("? @> ?", activity.data, ^%{actor: ap_id, object: id, type: "Like"}) + + activity = Repo.one(query) + + if activity do + # just delete for now... + {:ok, _activity} = Repo.delete(activity) + + likes = (object.data["likes"] || []) |> List.delete(ap_id) + + new_data = object.data + |> Map.put("like_count", length(likes)) + |> Map.put("likes", likes) + + changeset = Ecto.Changeset.change(object, data: new_data) + {:ok, object} = Repo.update(changeset) + + update_object_in_activities(object) + + {:ok, object} + else + {:ok, object} + end + end + def generate_activity_id do generate_id("activities") end @@ -64,14 +137,42 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> Enum.reverse end + def announce(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object) do + data = %{ + "type" => "Announce", + "actor" => ap_id, + "object" => id, + "to" => [User.ap_followers(user), object.data["actor"]] + } + + {:ok, activity} = insert(data) + + announcements = [ap_id | (object.data["announcements"] || [])] |> Enum.uniq + + new_data = object.data + |> Map.put("announcement_count", length(announcements)) + |> Map.put("announcements", announcements) + + changeset = Ecto.Changeset.change(object, data: new_data) + {:ok, object} = Repo.update(changeset) + + update_object_in_activities(object) + + {:ok, activity, object} + end + def fetch_activities_for_context(context) do query = from activity in Activity, where: fragment("? @> ?", activity.data, ^%{ context: context }) Repo.all(query) end - def upload(%Plug.Upload{} = file) do + def upload(file) do data = Upload.store(file) Repo.insert(%Object{data: data}) end + + defp make_date do + DateTime.utc_now() |> DateTime.to_iso8601 + end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 40350ad0c..2d7c25b50 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -26,6 +26,7 @@ defmodule Pleroma.Web.Router do get "/statuses/show/:id", TwitterAPI.Controller, :fetch_status get "/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation get "/statusnet/config", TwitterAPI.Controller, :config + post "/account/register", TwitterAPI.Controller, :register end scope "/api", Pleroma.Web do @@ -39,5 +40,11 @@ defmodule Pleroma.Web.Router do post "/friendships/create", TwitterAPI.Controller, :follow post "/friendships/destroy", TwitterAPI.Controller, :unfollow post "/statusnet/media/upload", TwitterAPI.Controller, :upload + post "/media/upload", TwitterAPI.Controller, :upload_json + post "/favorites/create/:id", TwitterAPI.Controller, :favorite + post "/favorites/create", TwitterAPI.Controller, :favorite + post "/favorites/destroy/:id", TwitterAPI.Controller, :unfavorite + post "/statuses/retweet/:id", TwitterAPI.Controller, :retweet + post "/qvitter/update_avatar", TwitterAPI.Controller, :update_avatar 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 9e4ffaefe..f2bf93abb 100644 --- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/activity_representer.ex @@ -4,6 +4,51 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do alias Pleroma.Activity + 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}} = activity, %{users: users, announced_activity: announced_activity} = opts) do + user = user_by_ap_id(users, actor) + created_at = get_in(activity.data, ["published"]) + |> 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 + } + end + + def to_map(%Activity{data: %{"type" => "Like"}} = activity, %{user: user, liked_activity: liked_activity} = opts) do + created_at = get_in(activity.data, ["published"]) + |> date_to_asctime + + text = "#{user.nickname} favorited a status." + + %{ + "id" => activity.id, + "user" => UserRepresenter.to_map(user, opts), + "statusnet_html" => text, # TODO: add summary + "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, + } + end + def to_map(%Activity{data: %{"type" => "Follow"}} = activity, %{user: user} = opts) do created_at = get_in(activity.data, ["published"]) |> date_to_asctime @@ -25,6 +70,10 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do content = get_in(activity.data, ["object", "content"]) created_at = get_in(activity.data, ["object", "published"]) |> date_to_asctime + like_count = get_in(activity.data, ["object", "like_count"]) || 0 + announcement_count = get_in(activity.data, ["object", "announcement_count"]) || 0 + favorited = opts[:for] && opts[:for].ap_id in (activity.data["object"]["likes"] || []) + repeated = opts[:for] && opts[:for].ap_id in (activity.data["object"]["announcements"] || []) mentions = opts[:mentioned] || [] @@ -45,14 +94,18 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do "in_reply_to_status_id" => activity.data["object"]["inReplyToStatusId"], "statusnet_conversation_id" => activity.data["object"]["statusnetConversationId"], "attachments" => (activity.data["object"]["attachment"] || []) |> ObjectRepresenter.enum_to_list(opts), - "attentions" => attentions + "attentions" => attentions, + "fave_num" => like_count, + "repeat_num" => announcement_count, + "favorited" => !!favorited, + "repeated" => !!repeated, } end defp date_to_asctime(date) do with {:ok, date, _offset} <- date |> DateTime.from_iso8601 do Calendar.Strftime.strftime!(date, "%a %b %d %H:%M:%S %z %Y") - else e -> + else _e -> "" end end diff --git a/lib/pleroma/web/twitter_api/representers/user_representer.ex b/lib/pleroma/web/twitter_api/representers/user_representer.ex index d8f98488e..2ee4ee254 100644 --- a/lib/pleroma/web/twitter_api/representers/user_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/user_representer.ex @@ -4,8 +4,10 @@ defmodule Pleroma.Web.TwitterAPI.Representers.UserRepresenter do alias Pleroma.User def to_map(user, opts) do - - image = "https://placehold.it/48x48" + image = case user.avatar do + %{"url" => [%{"href" => href} | _]} -> href + _ -> "https://placehold.it/48x48" + end following = if opts[:for] do User.following?(opts[:for], user) diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index f4ab5bdc6..7984b2e63 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -1,7 +1,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do alias Pleroma.{User, Activity, Repo, Object} alias Pleroma.Web.ActivityPub.ActivityPub - alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter + alias Pleroma.Web.TwitterAPI.Representers.{ActivityRepresenter, UserRepresenter} import Ecto.Query @@ -13,6 +13,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do context = ActivityPub.generate_context_id content = HtmlSanitizeEx.strip_tags(data["status"]) + |> String.replace("\n", "<br>") mentions = parse_mentions(content) @@ -37,7 +38,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do "content" => content_html, "published" => date, "context" => context, - "attachment" => attachments + "attachment" => attachments, + "actor" => user.ap_id }, "published" => date, "context" => context @@ -127,25 +129,74 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end end - def upload(%Plug.Upload{} = file) do + 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 {:ok, object} = ActivityPub.upload(file) url = List.first(object.data["url"]) href = url["href"] type = url["mediaType"] - # Fake this as good as possible... - """ - <?xml version="1.0" encoding="UTF-8"?> - <rsp stat="ok" xmlns:atom="http://www.w3.org/2005/Atom"> - <mediaid>#{object.id}</mediaid> - <media_id>#{object.id}</media_id> - <media_id_string>#{object.id}</media_id_string> - <media_url>#{href}</media_url> - <mediaurl>#{href}</mediaurl> - <atom:link rel="enclosure" href="#{href}" type="#{type}"></atom:link> - </rsp> - """ + case format do + "xml" -> + # Fake this as good as possible... + """ + <?xml version="1.0" encoding="UTF-8"?> + <rsp stat="ok" xmlns:atom="http://www.w3.org/2005/Atom"> + <mediaid>#{object.id}</mediaid> + <media_id>#{object.id}</media_id> + <media_id_string>#{object.id}</media_id_string> + <media_url>#{href}</media_url> + <mediaurl>#{href}</mediaurl> + <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 + } |> Poison.encode! + end end def parse_mentions(text) do @@ -155,7 +206,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do Regex.scan(regex, text) |> List.flatten |> Enum.uniq - |> Enum.map(fn ("@" <> match = full_match) -> {full_match, Repo.get_by(User, nickname: match)} end) + |> Enum.map(fn ("@" <> match = full_match) -> {full_match, User.get_cached_by_nickname(match)} end) |> Enum.filter(fn ({_match, user}) -> user end) end @@ -171,21 +222,72 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do |> put_in(["object", "statusnetConversationId"], activity.id) |> put_in(["statusnetConversationId"], activity.id) + object = Object.get_by_ap_id(activity.data["object"]["id"]) + + changeset = Ecto.Changeset.change(object, data: data["object"]) + Repo.update(changeset) + changeset = Ecto.Changeset.change(activity, data: data) Repo.update(changeset) end end + def register_user(params) do + params = %{ + nickname: params["nickname"], + name: params["fullname"], + bio: params["bio"], + email: params["email"], + password: params["password"], + password_confirmation: params["confirm"] + } + + changeset = User.register_changeset(%User{}, params) + + with {:ok, user} <- Repo.insert(changeset) do + {:ok, UserRepresenter.to_map(user)} + else + {:error, changeset} -> + errors = Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} -> msg end) + |> Poison.encode! + {:error, %{error: errors}} + 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 = Repo.get_by!(User, ap_id: actor) - mentioned_users = Repo.all(from user in User, where: user.ap_id in ^activity.data["to"]) + 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 diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 13de1661d..bafd878fc 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -2,6 +2,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do use Pleroma.Web, :controller alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter} + alias Pleroma.{Repo, Activity} + alias Pleroma.Web.ActivityPub.ActivityPub def verify_credentials(%{assigns: %{user: user}} = conn, _params) do response = user |> UserRepresenter.to_json(%{for: user}) @@ -86,6 +88,12 @@ defmodule Pleroma.Web.TwitterAPI.Controller do |> send_resp(200, response) end + def upload_json(conn, %{"media" => media}) do + response = TwitterAPI.upload(media, "json") + conn + |> json_reply(200, response) + end + def config(conn, _params) do response = %{ site: %{ @@ -100,6 +108,56 @@ defmodule Pleroma.Web.TwitterAPI.Controller do |> 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) + {:ok, status} = TwitterAPI.retweet(user, activity) + response = Poison.encode!(status) + + conn + |> json_reply(200, response) + end + + def register(conn, params) do + with {:ok, user} <- TwitterAPI.register_user(params) do + conn + |> json_reply(200, Poison.encode!(user)) + else + {:error, errors} -> + conn + |> json_reply(400, Poison.encode!(errors)) + end + end + + def update_avatar(%{assigns: %{user: user}} = conn, params) do + {:ok, object} = ActivityPub.upload(params) + change = Ecto.Changeset.change(user, %{avatar: object.data}) + {:ok, user} = Repo.update(change) + + response = UserRepresenter.to_map(user, %{for: user}) + |> Poison.encode! + + conn + |> json_reply(200, response) + end + defp json_reply(conn, status, json) do conn |> put_resp_content_type("application/json") |