Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into develop

This commit is contained in:
Roger Braun 2017-11-12 14:23:39 +01:00
commit 5fc6e9d467
7 changed files with 347 additions and 24 deletions

View file

@ -36,6 +36,37 @@ defmodule Pleroma.Notification do
Repo.all(query)
end
def get(%{id: user_id} = _user, id) do
query = from n in Notification,
where: n.id == ^id,
preload: [:activity]
notification = Repo.one(query)
case notification do
%{user_id: ^user_id} ->
{:ok, notification}
_ ->
{:error, "Cannot get notification"}
end
end
def clear(user) do
query = from n in Notification,
where: n.user_id == ^user.id
Repo.delete_all(query)
end
def dismiss(%{id: user_id} = _user, id) do
notification = Repo.get(Notification, id)
case notification do
%{user_id: ^user_id} ->
Repo.delete(notification)
_ ->
{:error, "Cannot dismiss notification"}
end
end
def create_notifications(%Activity{id: id, data: %{"to" => to, "type" => type}} = activity) when type in ["Create", "Like", "Announce", "Follow"] do
users = User.get_notified_from_activity(activity)

View file

@ -9,9 +9,8 @@ defmodule Pleroma.Upload do
File.cp!(file.path, result_file)
# fix content type on some image uploads
matches = Regex.named_captures(~r/\.(?<ext>(jpg|jpeg|png|gif))$/i, file.filename)
content_type = if file.content_type == "application/octet-stream" and matches do
if matches["ext"] == "jpg", do: "image/jpeg", else: "image/#{matches["ext"]}"
content_type = if file.content_type == "application/octet-stream" do
get_content_type(file.path)
else
file.content_type
end
@ -61,4 +60,34 @@ defmodule Pleroma.Upload do
defp url_for(file) do
"#{Web.base_url()}/media/#{file}"
end
def get_content_type(file) do
match = File.open(file, [:read], fn(f) ->
case IO.binread(f, 8) do
<<0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a>> ->
"image/png"
<<0x47, 0x49, 0x46, 0x38, _, 0x61, _, _>> ->
"image/gif"
<<0xff, 0xd8, 0xff, _, _, _, _, _>> ->
"image/jpeg"
<<0x1a, 0x45, 0xdf, 0xa3, _, _, _, _>> ->
"video/webm"
<<0x00, 0x00, 0x00, _, 0x66, 0x74, 0x79, 0x70>> ->
"video/mp4"
<<0x49, 0x44, 0x33, _, _, _, _, _>> ->
"audio/mpeg"
<<0x4f, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00>> ->
"audio/ogg"
<<0x52, 0x49, 0x46, 0x46, _, _, _, _>> ->
"audio/wav"
_ ->
"application/octet-stream"
end
end)
case match do
{:ok, type} -> type
_e -> "application/octet-stream"
end
end
end

View file

@ -24,6 +24,57 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
end
def update_credentials(%{assigns: %{user: user}} = conn, params) do
params = if bio = params["note"] do
Map.put(params, "bio", bio)
else
params
end
params = if name = params["display_name"] do
Map.put(params, "name", name)
else
params
end
user = if avatar = params["avatar"] do
with %Plug.Upload{} <- avatar,
{:ok, object} <- ActivityPub.upload(avatar),
change = Ecto.Changeset.change(user, %{avatar: object.data}),
{:ok, user} = Repo.update(change) do
user
else
_e -> user
end
else
user
end
user = if banner = params["header"] do
with %Plug.Upload{} <- banner,
{:ok, object} <- ActivityPub.upload(banner),
new_info <- Map.put(user.info, "banner", object.data),
change <- User.info_changeset(user, %{info: new_info}),
{:ok, user} <- Repo.update(change) do
user
else
_e -> user
end
else
user
end
with changeset <- User.update_changeset(user, params),
{:ok, user} <- Repo.update(changeset) do
json conn, AccountView.render("account.json", %{user: user})
else
_e ->
conn
|> put_status(403)
|> json(%{error: "Invalid request"})
end
end
def verify_credentials(%{assigns: %{user: user}} = conn, params) do
account = AccountView.render("account.json", %{user: user})
json(conn, account)
@ -194,23 +245,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def notifications(%{assigns: %{user: user}} = conn, params) do
notifications = Notification.for_user(user, params)
result = Enum.map(notifications, fn (%{id: id, activity: activity, inserted_at: created_at}) ->
actor = User.get_cached_by_ap_id(activity.data["actor"])
created_at = NaiveDateTime.to_iso8601(created_at)
|> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
case activity.data["type"] do
"Create" ->
%{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})}
"Like" ->
liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
%{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})}
"Announce" ->
announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
%{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})}
"Follow" ->
%{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})}
_ -> nil
end
result = Enum.map(notifications, fn x ->
render_notification(user, x)
end)
|> Enum.filter(&(&1))
@ -219,6 +255,33 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|> json(result)
end
def get_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
with {:ok, notification} <- Notification.get(user, id) do
json(conn, render_notification(user, notification))
else
{:error, reason} ->
conn
|> put_resp_content_type("application/json")
|> send_resp(403, Poison.encode!(%{"error" => reason}))
end
end
def clear_notifications(%{assigns: %{user: user}} = conn, _params) do
Notification.clear(user)
json(conn, %{})
end
def dismiss_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
with {:ok, _notif} <- Notification.dismiss(user, id) do
json(conn, %{})
else
{:error, reason} ->
conn
|> put_resp_content_type("application/json")
|> send_resp(403, Poison.encode!(%{"error" => reason}))
end
end
def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do
id = List.wrap(id)
q = from u in User,
@ -527,4 +590,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
Logger.debug("Unimplemented, returning an empty array")
json(conn, [])
end
defp render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do
actor = User.get_cached_by_ap_id(activity.data["actor"])
created_at = NaiveDateTime.to_iso8601(created_at)
|> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
case activity.data["type"] do
"Create" ->
%{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})}
"Like" ->
liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
%{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})}
"Announce" ->
announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
%{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})}
"Follow" ->
%{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})}
_ -> nil
end
end
end

View file

@ -60,6 +60,7 @@ defmodule Pleroma.Web.Router do
scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through :authenticated_api
patch "/accounts/update_credentials", MastodonAPIController, :update_credentials
get "/accounts/verify_credentials", MastodonAPIController, :verify_credentials
get "/accounts/relationships", MastodonAPIController, :relationships
get "/accounts/search", MastodonAPIController, :account_search
@ -89,7 +90,10 @@ defmodule Pleroma.Web.Router do
post "/statuses/:id/favourite", MastodonAPIController, :fav_status
post "/statuses/:id/unfavourite", MastodonAPIController, :unfav_status
post "/notifications/clear", MastodonAPIController, :clear_notifications
post "/notifications/dismiss", MastodonAPIController, :dismiss_notification
get "/notifications", MastodonAPIController, :notifications
get "/notifications/:id", MastodonAPIController, :get_notification
post "/media", MastodonAPIController, :upload
end

File diff suppressed because one or more lines are too long