diff options
Diffstat (limited to 'lib')
20 files changed, 362 insertions, 128 deletions
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 47c0e5b68..40bff08c7 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -22,6 +22,8 @@ defmodule Pleroma.Application do def start(_type, _args) do import Cachex.Spec + Pleroma.Config.DeprecationWarnings.warn() + # Define workers and child supervisors to be supervised children = [ @@ -99,12 +101,15 @@ defmodule Pleroma.Application do ], id: :cachex_idem ), - worker(Pleroma.FlakeId, []), - worker(Pleroma.Web.Federator.RetryQueue, []), - worker(Pleroma.Web.Federator, []), - worker(Pleroma.Stats, []), - worker(Pleroma.Web.Push, []) + worker(Pleroma.FlakeId, []) ] ++ + hackney_pool_children() ++ + [ + worker(Pleroma.Web.Federator.RetryQueue, []), + worker(Pleroma.Web.Federator, []), + worker(Pleroma.Stats, []), + worker(Pleroma.Web.Push, []) + ] ++ streamer_child() ++ chat_child() ++ [ @@ -119,6 +124,20 @@ defmodule Pleroma.Application do Supervisor.start_link(children, opts) end + def enabled_hackney_pools() do + [:media] ++ + if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Hackney do + [:federation] + else + [] + end ++ + if Pleroma.Config.get([Pleroma.Uploader, :proxy_remote]) do + [:upload] + else + [] + end + end + if Mix.env() == :test do defp streamer_child(), do: [] defp chat_child(), do: [] @@ -135,4 +154,11 @@ defmodule Pleroma.Application do end end end + + defp hackney_pool_children() do + for pool <- enabled_hackney_pools() do + options = Pleroma.Config.get([:hackney_pools, pool]) + :hackney_pool.child_spec(pool, options) + end + end end diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex new file mode 100644 index 000000000..dc50682ee --- /dev/null +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -0,0 +1,20 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Config.DeprecationWarnings do + require Logger + + def check_frontend_config_mechanism() do + if Pleroma.Config.get(:fe) do + Logger.warn(""" + !!!DEPRECATION WARNING!!! + You are using the old configuration mechanism for the frontend. Please check config.md. + """) + end + end + + def warn do + check_frontend_config_mechanism() + end +end diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index fb602d6b6..bf5daa948 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -69,7 +69,7 @@ defmodule Pleroma.HTML do |> Floki.attribute("a", "href") |> Enum.at(0) - {:commit, result} + {:commit, {:ok, result}} end) end end diff --git a/lib/pleroma/http/connection.ex b/lib/pleroma/http/connection.ex index 699d80cd7..b798eaa5a 100644 --- a/lib/pleroma/http/connection.ex +++ b/lib/pleroma/http/connection.ex @@ -10,7 +10,8 @@ defmodule Pleroma.HTTP.Connection do @hackney_options [ timeout: 10000, recv_timeout: 20000, - follow_redirect: true + follow_redirect: true, + pool: :federation ] @adapter Application.get_env(:tesla, :adapter) diff --git a/lib/pleroma/uploaders/mdii.ex b/lib/pleroma/uploaders/mdii.ex index 530b34362..320b07abd 100644 --- a/lib/pleroma/uploaders/mdii.ex +++ b/lib/pleroma/uploaders/mdii.ex @@ -24,7 +24,8 @@ defmodule Pleroma.Uploaders.MDII do extension = String.split(upload.name, ".") |> List.last() query = "#{cgi}?#{extension}" - with {:ok, %{status: 200, body: body}} <- @httpoison.post(query, file_data) do + with {:ok, %{status: 200, body: body}} <- + @httpoison.post(query, file_data, adapter: [pool: :default]) do remote_file_name = String.split(body) |> List.first() public_url = "#{files}/#{remote_file_name}.#{extension}" {:ok, {:url, public_url}} diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1468cc133..33630ac7c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -39,6 +39,7 @@ defmodule Pleroma.User do field(:follower_address, :string) field(:search_rank, :float, virtual: true) field(:tags, {:array, :string}, default: []) + field(:bookmarks, {:array, :string}, default: []) field(:last_refreshed_at, :naive_datetime) has_many(:notifications, Notification) embeds_one(:info, Pleroma.User.Info) @@ -309,20 +310,30 @@ defmodule Pleroma.User do @doc "A mass follow for local users. Ignores blocks and has no side effects" @spec follow_all(User.t(), list(User.t())) :: {atom(), User.t()} def follow_all(follower, followeds) do - following = - (follower.following ++ Enum.map(followeds, fn %{follower_address: fa} -> fa end)) - |> Enum.uniq() + followed_addresses = Enum.map(followeds, fn %{follower_address: fa} -> fa end) + + q = + from(u in User, + where: u.id == ^follower.id, + update: [ + set: [ + following: + fragment( + "array(select distinct unnest (array_cat(?, ?)))", + u.following, + ^followed_addresses + ) + ] + ] + ) - {:ok, follower} = - follower - |> follow_changeset(%{following: following}) - |> update_and_set_cache + {1, [follower]} = Repo.update_all(q, [], returning: true) Enum.each(followeds, fn followed -> update_follower_count(followed) end) - {:ok, follower} + set_cache(follower) end def follow(%User{} = follower, %User{info: info} = followed) do @@ -343,18 +354,17 @@ defmodule Pleroma.User do Websub.subscribe(follower, followed) end - following = - [ap_followers | follower.following] - |> Enum.uniq() + q = + from(u in User, + where: u.id == ^follower.id, + update: [push: [following: ^ap_followers]] + ) - follower = - follower - |> follow_changeset(%{following: following}) - |> update_and_set_cache + {1, [follower]} = Repo.update_all(q, [], returning: true) {:ok, _} = update_follower_count(followed) - follower + set_cache(follower) end end @@ -362,17 +372,18 @@ defmodule Pleroma.User do ap_followers = followed.follower_address if following?(follower, followed) and follower.ap_id != followed.ap_id do - following = - follower.following - |> List.delete(ap_followers) + q = + from(u in User, + where: u.id == ^follower.id, + update: [pull: [following: ^ap_followers]] + ) - {:ok, follower} = - follower - |> follow_changeset(%{following: following}) - |> update_and_set_cache + {1, [follower]} = Repo.update_all(q, [], returning: true) {:ok, followed} = update_follower_count(followed) + set_cache(follower) + {:ok, follower, Utils.fetch_latest_follow(follower, followed)} else {:error, "Not subscribed!"} @@ -423,12 +434,16 @@ defmodule Pleroma.User do get_by_nickname(nickname) end + def set_cache(user) do + Cachex.put(:user_cache, "ap_id:#{user.ap_id}", user) + Cachex.put(:user_cache, "nickname:#{user.nickname}", user) + Cachex.put(:user_cache, "user_info:#{user.id}", user_info(user)) + {:ok, user} + end + def update_and_set_cache(changeset) do with {:ok, user} <- Repo.update(changeset) do - Cachex.put(:user_cache, "ap_id:#{user.ap_id}", user) - Cachex.put(:user_cache, "nickname:#{user.nickname}", user) - Cachex.put(:user_cache, "user_info:#{user.id}", user_info(user)) - {:ok, user} + set_cache(user) else e -> e end @@ -1156,6 +1171,22 @@ defmodule Pleroma.User do updated_user end + def bookmark(%User{} = user, status_id) do + bookmarks = Enum.uniq(user.bookmarks ++ [status_id]) + update_bookmarks(user, bookmarks) + end + + def unbookmark(%User{} = user, status_id) do + bookmarks = Enum.uniq(user.bookmarks -- [status_id]) + update_bookmarks(user, bookmarks) + end + + def update_bookmarks(%User{} = user, bookmarks) do + user + |> change(%{bookmarks: bookmarks}) + |> update_and_set_cache + end + defp normalize_tags(tags) do [tags] |> List.flatten() diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 4016808e8..06e8c3f1c 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -88,6 +88,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do recipients: recipients }) + Task.start(fn -> + Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + end) + Notification.create_notifications(activity) stream_out(activity) {:ok, activity} diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index c2ced51d8..43725c3db 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -453,9 +453,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"), %User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]), {:ok, activity} <- - ActivityPub.accept(%{ + ActivityPub.reject(%{ to: follow_activity.data["to"], - type: "Accept", + type: "Reject", actor: followed.ap_id, object: follow_activity.data["id"], local: false diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index e40d05fcd..3b0cdfe71 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -316,6 +316,25 @@ defmodule Pleroma.Web.ActivityPub.Utils do @doc """ Updates a follow activity's state (for locked accounts). """ + def update_follow_state( + %Activity{data: %{"actor" => actor, "object" => object, "state" => "pending"}} = activity, + state + ) do + try do + Ecto.Adapters.SQL.query!( + Repo, + "UPDATE activities SET data = jsonb_set(data, '{state}', $1) WHERE data->>'type' = 'Follow' AND data->>'actor' = $2 AND data->>'object' = $3 AND data->>'state' = 'pending'", + [state, actor, object] + ) + + activity = Repo.get(Activity, activity.id) + {:ok, activity} + rescue + e -> + {:error, e} + end + end + def update_follow_state(%Activity{} = activity, state) do with new_data <- activity.data diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index a366a149f..0726e6ac4 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -6,7 +6,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do use Pleroma.Web, :controller alias Pleroma.{Repo, Object, Activity, User, Notification, Stats} alias Pleroma.Web - alias Pleroma.HTML alias Pleroma.Web.MastodonAPI.{ StatusView, @@ -424,6 +423,28 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %Activity{} = activity <- Repo.get(Activity, id), + %User{} = user <- User.get_by_nickname(user.nickname), + true <- ActivityPub.visible_for_user?(activity, user), + {:ok, user} <- User.bookmark(user, activity.data["object"]["id"]) do + conn + |> put_view(StatusView) + |> try_render("status.json", %{activity: activity, for: user, as: :activity}) + end + end + + def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %Activity{} = activity <- Repo.get(Activity, id), + %User{} = user <- User.get_by_nickname(user.nickname), + true <- ActivityPub.visible_for_user?(activity, user), + {:ok, user} <- User.unbookmark(user, activity.data["object"]["id"]) do + conn + |> put_view(StatusView) + |> try_render("status.json", %{activity: activity, for: user, as: :activity}) + end + end + def notifications(%{assigns: %{user: user}} = conn, params) do notifications = Notification.for_user(user, params) @@ -500,7 +521,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def upload(%{assigns: %{user: user}} = conn, %{"file" => file} = data) do with {:ok, object} <- - ActivityPub.upload(file, + ActivityPub.upload( + file, actor: User.ap_id(user), description: Map.get(data, "description") ) do @@ -859,6 +881,19 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> render("index.json", %{activities: activities, for: user, as: :activity}) end + def bookmarks(%{assigns: %{user: user}} = conn, _) do + user = Repo.get(User, user.id) + + activities = + user.bookmarks + |> Enum.map(fn id -> Activity.get_create_by_object_ap_id(id) end) + |> Enum.reverse() + + conn + |> put_view(StatusView) + |> render("index.json", %{activities: activities, for: user, as: :activity}) + end + def get_lists(%{assigns: %{user: user}} = conn, opts) do lists = Pleroma.List.for_user(user, opts) res = ListView.render("lists.json", lists: lists) @@ -1101,7 +1136,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def login(conn, _) do with {:ok, app} <- get_or_make_app() do path = - o_auth_path(conn, :authorize, + o_auth_path( + conn, + :authorize, response_type: "code", client_id: app.client_id, redirect_uri: ".", @@ -1309,7 +1346,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do [], adapter: [ timeout: timeout, - recv_timeout: timeout + recv_timeout: timeout, + pool: :default ] ), {:ok, data} <- Jason.decode(body) do @@ -1342,29 +1380,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - def get_status_card(status_id) do + def status_card(conn, %{"id" => status_id}) do with %Activity{} = activity <- Repo.get(Activity, status_id), - true <- ActivityPub.is_public?(activity), - %Object{} = object <- Object.normalize(activity.data["object"]), - page_url <- HTML.extract_first_external_url(object, object.data["content"]), - {:ok, rich_media} <- Pleroma.Web.RichMedia.Parser.parse(page_url) do - page_url = rich_media[:url] || page_url - site_name = rich_media[:site_name] || URI.parse(page_url).host - - rich_media - |> Map.take([:image, :title, :description]) - |> Map.put(:type, "link") - |> Map.put(:provider_name, site_name) - |> Map.put(:url, page_url) + true <- ActivityPub.is_public?(activity) do + data = + StatusView.render( + "card.json", + Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + ) + + json(conn, data) else - _ -> %{} + _e -> + %{} end end - def status_card(conn, %{"id" => status_id}) do - json(conn, get_status_card(status_id)) - end - def try_render(conn, target, params) when is_binary(target) do res = render(conn, target, params) diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index ddfe6788c..d5b7e68c7 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -87,6 +87,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do favourites_count: 0, reblogged: false, favourited: false, + bookmarked: false, muted: false, pinned: pinned?(activity, user), sensitive: false, @@ -121,6 +122,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || []) favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || []) + bookmarked = opts[:for] && object["id"] in opts[:for].bookmarks attachment_data = object["attachment"] || [] attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment) @@ -139,6 +141,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do __MODULE__ ) + card = render("card.json", Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)) + %{ id: to_string(activity.id), uri: object["id"], @@ -147,6 +151,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do in_reply_to_id: reply_to && to_string(reply_to.id), in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id), reblog: nil, + card: card, content: content, created_at: created_at, reblogs_count: announcement_count, @@ -154,6 +159,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do favourites_count: like_count, reblogged: present?(repeated), favourited: present?(favorited), + bookmarked: present?(bookmarked), muted: false, pinned: pinned?(activity, user), sensitive: sensitive, @@ -175,6 +181,29 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do nil end + def render("card.json", %{rich_media: rich_media, page_url: page_url}) do + page_url = rich_media[:url] || page_url + page_url_data = URI.parse(page_url) + site_name = rich_media[:site_name] || page_url_data.host + + %{ + type: "link", + provider_name: site_name, + provider_url: page_url_data.scheme <> "://" <> page_url_data.host, + url: page_url, + image: rich_media[:image] |> MediaProxy.url(), + title: rich_media[:title], + description: rich_media[:description], + pleroma: %{ + opengraph: rich_media + } + } + end + + def render("card.json", _) do + nil + end + def render("attachment.json", %{attachment: attachment}) do [attachment_url | _] = attachment["url"] media_type = attachment_url["mediaType"] || attachment_url["mimeType"] || "image" diff --git a/lib/pleroma/web/rich_media/controllers/rich_media_controller.ex b/lib/pleroma/web/rich_media/controllers/rich_media_controller.ex deleted file mode 100644 index 91019961d..000000000 --- a/lib/pleroma/web/rich_media/controllers/rich_media_controller.ex +++ /dev/null @@ -1,17 +0,0 @@ -defmodule Pleroma.Web.RichMedia.RichMediaController do - use Pleroma.Web, :controller - - import Pleroma.Web.ControllerHelper, only: [json_response: 3] - - def parse(conn, %{"url" => url}) do - case Pleroma.Web.RichMedia.Parser.parse(url) do - {:ok, data} -> - conn - |> json_response(200, data) - - {:error, msg} -> - conn - |> json_response(404, msg) - end - end -end diff --git a/lib/pleroma/web/rich_media/helpers.ex b/lib/pleroma/web/rich_media/helpers.ex new file mode 100644 index 000000000..44e876777 --- /dev/null +++ b/lib/pleroma/web/rich_media/helpers.ex @@ -0,0 +1,19 @@ +# Pleroma: A lightweight social networking server +# Copyright _ 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.RichMedia.Helpers do + alias Pleroma.{Activity, Object, HTML} + alias Pleroma.Web.RichMedia.Parser + + def fetch_data_for_activity(%Activity{} = activity) do + with true <- Pleroma.Config.get([:rich_media, :enabled], true), + %Object{} = object <- Object.normalize(activity.data["object"]), + {:ok, page_url} <- HTML.extract_first_external_url(object, object.data["content"]), + {:ok, rich_media} <- Parser.parse(page_url) do + %{page_url: page_url, rich_media: rich_media} + else + _ -> %{} + end + end +end diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex index 947dc0c3c..32dec9887 100644 --- a/lib/pleroma/web/rich_media/parser.ex +++ b/lib/pleroma/web/rich_media/parser.ex @@ -1,3 +1,7 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Web.RichMedia.Parser do @parsers [ Pleroma.Web.RichMedia.Parsers.OGP, @@ -11,19 +15,26 @@ defmodule Pleroma.Web.RichMedia.Parser do def parse(url), do: parse_url(url) else def parse(url) do - with {:ok, data} <- Cachex.fetch(:rich_media_cache, url, fn _ -> parse_url(url) end) do - data - else - _e -> - {:error, "Parsing error"} + try do + Cachex.fetch!(:rich_media_cache, url, fn _ -> + {:commit, parse_url(url)} + end) + rescue + e -> + {:error, "Cachex error: #{inspect(e)}"} end end end defp parse_url(url) do - {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url) + try do + {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: [pool: :media]) - html |> maybe_parse() |> get_parsed_data() + html |> maybe_parse() |> clean_parsed_data() |> check_parsed_data() + rescue + e -> + {:error, "Parsing error: #{inspect(e)}"} + end end defp maybe_parse(html) do @@ -35,11 +46,33 @@ defmodule Pleroma.Web.RichMedia.Parser do end) end - defp get_parsed_data(data) when data == %{} do - {:error, "No metadata found"} + defp check_parsed_data(%{title: title} = data) when is_binary(title) and byte_size(title) > 0 do + {:ok, data} + end + + defp check_parsed_data(data) do + {:error, "Found metadata was invalid or incomplete: #{inspect(data)}"} end - defp get_parsed_data(data) do - {:ok, data} + defp string_is_valid_unicode(data) when is_binary(data) do + data + |> :unicode.characters_to_binary() + |> clean_string() + end + + defp string_is_valid_unicode(data), do: {:ok, data} + + defp clean_string({:error, _, _}), do: {:error, "Invalid data"} + defp clean_string(data), do: {:ok, data} + + defp clean_parsed_data(data) do + data + |> Enum.reject(fn {_, val} -> + case string_is_valid_unicode(val) do + {:ok, _} -> false + _ -> true + end + end) + |> Map.new() end end diff --git a/lib/pleroma/web/rich_media/parsers/oembed_parser.ex b/lib/pleroma/web/rich_media/parsers/oembed_parser.ex index ca7226faf..2530b8c9d 100644 --- a/lib/pleroma/web/rich_media/parsers/oembed_parser.ex +++ b/lib/pleroma/web/rich_media/parsers/oembed_parser.ex @@ -20,8 +20,12 @@ defmodule Pleroma.Web.RichMedia.Parsers.OEmbed do end defp get_oembed_data(url) do - {:ok, %Tesla.Env{body: json}} = Pleroma.HTTP.get(url) + {:ok, %Tesla.Env{body: json}} = Pleroma.HTTP.get(url, [], adapter: [pool: :media]) - {:ok, Poison.decode!(json)} + {:ok, data} = Jason.decode(json) + + data = data |> Map.new(fn {k, v} -> {String.to_atom(k), v} end) + + {:ok, data} end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 31f739738..c6b4d37ab 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -185,6 +185,7 @@ defmodule Pleroma.Web.Router do get("/timelines/direct", MastodonAPIController, :dm_timeline) get("/favourites", MastodonAPIController, :favourites) + get("/bookmarks", MastodonAPIController, :bookmarks) post("/statuses", MastodonAPIController, :post_status) delete("/statuses/:id", MastodonAPIController, :delete_status) @@ -195,6 +196,8 @@ defmodule Pleroma.Web.Router do post("/statuses/:id/unfavourite", MastodonAPIController, :unfav_status) post("/statuses/:id/pin", MastodonAPIController, :pin_status) post("/statuses/:id/unpin", MastodonAPIController, :unpin_status) + post("/statuses/:id/bookmark", MastodonAPIController, :bookmark_status) + post("/statuses/:id/unbookmark", MastodonAPIController, :unbookmark_status) post("/notifications/clear", MastodonAPIController, :clear_notifications) post("/notifications/dismiss", MastodonAPIController, :dismiss_notification) @@ -239,12 +242,6 @@ defmodule Pleroma.Web.Router do put("/settings", MastodonAPIController, :put_settings) end - scope "/api", Pleroma.Web.RichMedia do - pipe_through(:authenticated_api) - - get("/rich_media/parse", RichMediaController, :parse) - end - scope "/api/v1", Pleroma.Web.MastodonAPI do pipe_through(:api) get("/instance", MastodonAPIController, :masto_instance) @@ -284,6 +281,7 @@ defmodule Pleroma.Web.Router do post("/help/test", TwitterAPI.UtilController, :help_test) get("/statusnet/config", TwitterAPI.UtilController, :config) get("/statusnet/version", TwitterAPI.UtilController, :version) + get("/pleroma/frontend_configurations", TwitterAPI.UtilController, :frontend_configurations) end scope "/api", Pleroma.Web do diff --git a/lib/pleroma/web/templates/mastodon_api/mastodon/index.html.eex b/lib/pleroma/web/templates/mastodon_api/mastodon/index.html.eex index 0862412ea..9a725e420 100644 --- a/lib/pleroma/web/templates/mastodon_api/mastodon/index.html.eex +++ b/lib/pleroma/web/templates/mastodon_api/mastodon/index.html.eex @@ -1,23 +1,28 @@ <!DOCTYPE html> <html lang='en'> <head> +<meta charset='utf-8'> +<meta content='width=device-width, initial-scale=1' name='viewport'> <title> <%= Application.get_env(:pleroma, :instance)[:name] %> </title> -<meta charset='utf-8'> -<meta content='width=device-width, initial-scale=1' name='viewport'> <link rel="icon" type="image/png" href="/favicon.png"/> -<link rel="stylesheet" media="all" href="/packs/common.css" /> -<link rel="stylesheet" media="all" href="/packs/default.css" /> +<script crossorigin='anonymous' src="/packs/locales.js"></script> +<script crossorigin='anonymous' src="/packs/locales/glitch/en.js"></script> -<script src="/packs/common.js"></script> -<script src="/packs/locale_en.js"></script> -<link as='script' crossorigin='anonymous' href='/packs/features/getting_started.js' rel='preload'> -<link as='script' crossorigin='anonymous' href='/packs/features/compose.js' rel='preload'> -<link as='script' crossorigin='anonymous' href='/packs/features/home_timeline.js' rel='preload'> -<link as='script' crossorigin='anonymous' href='/packs/features/notifications.js' rel='preload'> +<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/getting_started.js'> +<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/compose.js'> +<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/home_timeline.js'> +<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/notifications.js'> <script id='initial-state' type='application/json'><%= raw @initial_state %></script> -<script src="/packs/application.js"></script> + +<script src="/packs/core/common.js"></script> +<link rel="stylesheet" media="all" href="/packs/core/common.css" /> + +<script src="/packs/flavours/glitch/common.js"></script> +<link rel="stylesheet" media="all" href="/packs/flavours/glitch/common.css" /> + +<script src="/packs/flavours/glitch/home.js"></script> </head> <body class='app-body no-reduce-motion system-font'> <div class='app-holder' data-props='{"locale":"en"}' id='mastodon'> diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index a79072f3d..b347faa71 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -183,25 +183,31 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do invitesEnabled: if(Keyword.get(instance, :invites_enabled, false), do: "1", else: "0") } - pleroma_fe = %{ - theme: Keyword.get(instance_fe, :theme), - background: Keyword.get(instance_fe, :background), - logo: Keyword.get(instance_fe, :logo), - logoMask: Keyword.get(instance_fe, :logo_mask), - logoMargin: Keyword.get(instance_fe, :logo_margin), - redirectRootNoLogin: Keyword.get(instance_fe, :redirect_root_no_login), - redirectRootLogin: Keyword.get(instance_fe, :redirect_root_login), - chatDisabled: !Keyword.get(instance_chat, :enabled), - showInstanceSpecificPanel: Keyword.get(instance_fe, :show_instance_panel), - scopeOptionsEnabled: Keyword.get(instance_fe, :scope_options_enabled), - formattingOptionsEnabled: Keyword.get(instance_fe, :formatting_options_enabled), - collapseMessageWithSubject: Keyword.get(instance_fe, :collapse_message_with_subject), - hidePostStats: Keyword.get(instance_fe, :hide_post_stats), - hideUserStats: Keyword.get(instance_fe, :hide_user_stats), - scopeCopy: Keyword.get(instance_fe, :scope_copy), - subjectLineBehavior: Keyword.get(instance_fe, :subject_line_behavior), - alwaysShowSubjectInput: Keyword.get(instance_fe, :always_show_subject_input) - } + pleroma_fe = + if instance_fe do + %{ + theme: Keyword.get(instance_fe, :theme), + background: Keyword.get(instance_fe, :background), + logo: Keyword.get(instance_fe, :logo), + logoMask: Keyword.get(instance_fe, :logo_mask), + logoMargin: Keyword.get(instance_fe, :logo_margin), + redirectRootNoLogin: Keyword.get(instance_fe, :redirect_root_no_login), + redirectRootLogin: Keyword.get(instance_fe, :redirect_root_login), + chatDisabled: !Keyword.get(instance_chat, :enabled), + showInstanceSpecificPanel: Keyword.get(instance_fe, :show_instance_panel), + scopeOptionsEnabled: Keyword.get(instance_fe, :scope_options_enabled), + formattingOptionsEnabled: Keyword.get(instance_fe, :formatting_options_enabled), + collapseMessageWithSubject: + Keyword.get(instance_fe, :collapse_message_with_subject), + hidePostStats: Keyword.get(instance_fe, :hide_post_stats), + hideUserStats: Keyword.get(instance_fe, :hide_user_stats), + scopeCopy: Keyword.get(instance_fe, :scope_copy), + subjectLineBehavior: Keyword.get(instance_fe, :subject_line_behavior), + alwaysShowSubjectInput: Keyword.get(instance_fe, :always_show_subject_input) + } + else + Pleroma.Config.get([:frontend_configurations, :pleroma_fe]) + end managed_config = Keyword.get(instance, :managed_config) @@ -216,6 +222,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end + def frontend_configurations(conn, _params) do + config = + Pleroma.Config.get(:frontend_configurations, %{}) + |> Enum.into(%{}) + + json(conn, config) + end + def version(conn, _params) do version = Pleroma.Application.named_version() diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex index 19b723586..c4025cbd7 100644 --- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/activity_representer.ex @@ -12,6 +12,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Formatter alias Pleroma.HTML + alias Pleroma.Web.MastodonAPI.StatusView defp user_by_ap_id(user_list, ap_id) do Enum.find(user_list, fn %{ap_id: user_id} -> ap_id == user_id end) @@ -186,6 +187,12 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do summary = HTML.strip_tags(object["summary"]) + card = + StatusView.render( + "card.json", + Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + ) + %{ "id" => activity.id, "uri" => activity.data["object"]["id"], @@ -214,7 +221,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do "possibly_sensitive" => possibly_sensitive, "visibility" => Pleroma.Web.MastodonAPI.StatusView.get_visibility(object), "summary" => summary, - "summary_html" => summary |> Formatter.emojify(object["emoji"]) + "summary_html" => summary |> Formatter.emojify(object["emoji"]), + "card" => card } end diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index a01ee0010..d0d1221c3 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -10,6 +10,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do alias Pleroma.Web.TwitterAPI.ActivityView alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter + alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Activity alias Pleroma.HTML alias Pleroma.Object @@ -274,6 +275,12 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do summary = HTML.strip_tags(summary) + card = + StatusView.render( + "card.json", + Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + ) + %{ "id" => activity.id, "uri" => activity.data["object"]["id"], @@ -300,9 +307,10 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do "tags" => tags, "activity_type" => "post", "possibly_sensitive" => possibly_sensitive, - "visibility" => Pleroma.Web.MastodonAPI.StatusView.get_visibility(object), + "visibility" => StatusView.get_visibility(object), "summary" => summary, - "summary_html" => summary |> Formatter.emojify(object["emoji"]) + "summary_html" => summary |> Formatter.emojify(object["emoji"]), + "card" => card } end |