Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into remake-remodel-dms
This commit is contained in:
commit
9c17109765
|
@ -387,56 +387,47 @@ defp render_timelines(user) do
|
|||
|
||||
favourites = ActivityPub.fetch_favourites(user)
|
||||
|
||||
output_relationships =
|
||||
!!Pleroma.Config.get([:extensions, :output_relationships_in_statuses_by_default])
|
||||
|
||||
Benchee.run(
|
||||
%{
|
||||
"Rendering home timeline" => fn ->
|
||||
StatusView.render("index.json", %{
|
||||
activities: home_activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: !output_relationships
|
||||
as: :activity
|
||||
})
|
||||
end,
|
||||
"Rendering direct timeline" => fn ->
|
||||
StatusView.render("index.json", %{
|
||||
activities: direct_activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: !output_relationships
|
||||
as: :activity
|
||||
})
|
||||
end,
|
||||
"Rendering public timeline" => fn ->
|
||||
StatusView.render("index.json", %{
|
||||
activities: public_activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: !output_relationships
|
||||
as: :activity
|
||||
})
|
||||
end,
|
||||
"Rendering tag timeline" => fn ->
|
||||
StatusView.render("index.json", %{
|
||||
activities: tag_activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: !output_relationships
|
||||
as: :activity
|
||||
})
|
||||
end,
|
||||
"Rendering notifications" => fn ->
|
||||
Pleroma.Web.MastodonAPI.NotificationView.render("index.json", %{
|
||||
notifications: notifications,
|
||||
for: user,
|
||||
skip_relationships: !output_relationships
|
||||
for: user
|
||||
})
|
||||
end,
|
||||
"Rendering favourites timeline" => fn ->
|
||||
StatusView.render("index.json", %{
|
||||
activities: favourites,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: !output_relationships
|
||||
as: :activity
|
||||
})
|
||||
end
|
||||
},
|
||||
|
|
|
@ -251,8 +251,6 @@
|
|||
]
|
||||
]
|
||||
|
||||
config :pleroma, :extensions, output_relationships_in_statuses_by_default: true
|
||||
|
||||
config :pleroma, :feed,
|
||||
post_title: %{
|
||||
max_length: 100,
|
||||
|
|
|
@ -679,15 +679,6 @@
|
|||
7
|
||||
]
|
||||
},
|
||||
%{
|
||||
key: :federation_publisher_modules,
|
||||
type: {:list, :module},
|
||||
description:
|
||||
"List of modules for federation publishing. Module names are shortened (removed leading `Pleroma.Web.` part), but on adding custom module you need to use full name.",
|
||||
suggestions: [
|
||||
Pleroma.Web.ActivityPub.Publisher
|
||||
]
|
||||
},
|
||||
%{
|
||||
key: :allow_relay,
|
||||
type: :boolean,
|
||||
|
@ -1105,32 +1096,97 @@
|
|||
description: "Settings for Pleroma FE",
|
||||
suggestions: [
|
||||
%{
|
||||
theme: "pleroma-dark",
|
||||
logo: "/static/logo.png",
|
||||
background: "/images/city.jpg",
|
||||
redirectRootNoLogin: "/main/all",
|
||||
redirectRootLogin: "/main/friends",
|
||||
showInstanceSpecificPanel: true,
|
||||
scopeOptionsEnabled: false,
|
||||
formattingOptionsEnabled: false,
|
||||
collapseMessageWithSubject: false,
|
||||
hidePostStats: false,
|
||||
hideUserStats: false,
|
||||
scopeCopy: true,
|
||||
subjectLineBehavior: "email",
|
||||
alwaysShowSubjectInput: true,
|
||||
logoMask: false,
|
||||
background: "/static/aurora_borealis.jpg",
|
||||
collapseMessageWithSubject: false,
|
||||
disableChat: false,
|
||||
greentext: false,
|
||||
hideFilteredStatuses: false,
|
||||
hideMutedPosts: false,
|
||||
hidePostStats: false,
|
||||
hideSitename: false,
|
||||
hideUserStats: false,
|
||||
loginMethod: "password",
|
||||
logo: "/static/logo.png",
|
||||
logoMargin: ".1em",
|
||||
stickers: false,
|
||||
enableEmojiPicker: false
|
||||
logoMask: true,
|
||||
minimalScopesMode: false,
|
||||
noAttachmentLinks: false,
|
||||
nsfwCensorImage: "",
|
||||
postContentType: "text/plain",
|
||||
redirectRootLogin: "/main/friends",
|
||||
redirectRootNoLogin: "/main/all",
|
||||
scopeCopy: true,
|
||||
showFeaturesPanel: true,
|
||||
showInstanceSpecificPanel: false,
|
||||
subjectLineBehavior: "email",
|
||||
theme: "pleroma-dark",
|
||||
webPushNotifications: false
|
||||
}
|
||||
],
|
||||
children: [
|
||||
%{
|
||||
key: :theme,
|
||||
key: :alwaysShowSubjectInput,
|
||||
label: "Always show subject input",
|
||||
type: :boolean,
|
||||
description: "When disabled, auto-hide the subject field if it's empty"
|
||||
},
|
||||
%{
|
||||
key: :background,
|
||||
type: :string,
|
||||
description: "Which theme to use, they are defined in styles.json",
|
||||
suggestions: ["pleroma-dark"]
|
||||
description:
|
||||
"URL of the background, unless viewing a user profile with a background that is set",
|
||||
suggestions: ["/images/city.jpg"]
|
||||
},
|
||||
%{
|
||||
key: :collapseMessageWithSubject,
|
||||
label: "Collapse message with subject",
|
||||
type: :boolean,
|
||||
description:
|
||||
"When a message has a subject (aka Content Warning), collapse it by default"
|
||||
},
|
||||
%{
|
||||
key: :disableChat,
|
||||
label: "PleromaFE Chat",
|
||||
type: :boolean,
|
||||
description: "Disables PleromaFE Chat component"
|
||||
},
|
||||
%{
|
||||
key: :greentext,
|
||||
label: "Greentext",
|
||||
type: :boolean,
|
||||
description: "Enables green text on lines prefixed with the > character."
|
||||
},
|
||||
%{
|
||||
key: :hideFilteredStatuses,
|
||||
label: "Hide Filtered Statuses",
|
||||
type: :boolean,
|
||||
description: "Hides filtered statuses from timelines."
|
||||
},
|
||||
%{
|
||||
key: :hideMutedPosts,
|
||||
label: "Hide Muted Posts",
|
||||
type: :boolean,
|
||||
description: "Hides muted statuses from timelines."
|
||||
},
|
||||
%{
|
||||
key: :hidePostStats,
|
||||
label: "Hide post stats",
|
||||
type: :boolean,
|
||||
description: "Hide notices statistics (repeats, favorites, ...)"
|
||||
},
|
||||
%{
|
||||
key: :hideSitename,
|
||||
label: "Hide Sitename",
|
||||
type: :boolean,
|
||||
description: "Hides instance name from PleromaFE banner."
|
||||
},
|
||||
%{
|
||||
key: :hideUserStats,
|
||||
label: "Hide user stats",
|
||||
type: :boolean,
|
||||
description:
|
||||
"Hide profile statistics (posts, posts per day, followers, followings, ...)"
|
||||
},
|
||||
%{
|
||||
key: :logo,
|
||||
|
@ -1139,11 +1195,44 @@
|
|||
suggestions: ["/static/logo.png"]
|
||||
},
|
||||
%{
|
||||
key: :background,
|
||||
key: :logoMargin,
|
||||
label: "Logo margin",
|
||||
type: :string,
|
||||
description:
|
||||
"URL of the background, unless viewing a user profile with a background that is set",
|
||||
suggestions: ["/images/city.jpg"]
|
||||
"Allows you to adjust vertical margins between logo boundary and navbar borders. " <>
|
||||
"The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout.",
|
||||
suggestions: [".1em"]
|
||||
},
|
||||
%{
|
||||
key: :logoMask,
|
||||
label: "Logo mask",
|
||||
type: :boolean,
|
||||
description:
|
||||
"By default it assumes logo used will be monochrome with alpha channel to be compatible with both light and dark themes. " <>
|
||||
"If you want a colorful logo you must disable logoMask."
|
||||
},
|
||||
%{
|
||||
key: :minimalScopesMode,
|
||||
label: "Minimal scopes mode",
|
||||
type: :boolean,
|
||||
description:
|
||||
"Limit scope selection to Direct, User default, and Scope of post replying to. " <>
|
||||
"Also prevents replying to a DM with a public post from PleromaFE."
|
||||
},
|
||||
%{
|
||||
key: :nsfwCensorImage,
|
||||
label: "NSFW Censor Image",
|
||||
type: :string,
|
||||
description:
|
||||
"URL of the image to use for hiding NSFW media attachments in the timeline.",
|
||||
suggestions: ["/static/img/nsfw.png"]
|
||||
},
|
||||
%{
|
||||
key: :postContentType,
|
||||
label: "Post Content Type",
|
||||
type: {:dropdown, :atom},
|
||||
description: "Default post formatting option.",
|
||||
suggestions: ["text/plain", "text/html", "text/markdown", "text/bbcode"]
|
||||
},
|
||||
%{
|
||||
key: :redirectRootNoLogin,
|
||||
|
@ -1161,51 +1250,25 @@
|
|||
"Relative URL which indicates where to redirect when a user is logged in",
|
||||
suggestions: ["/main/friends"]
|
||||
},
|
||||
%{
|
||||
key: :showInstanceSpecificPanel,
|
||||
label: "Show instance specific panel",
|
||||
type: :boolean,
|
||||
description: "Whenether to show the instance's specific panel"
|
||||
},
|
||||
%{
|
||||
key: :scopeOptionsEnabled,
|
||||
label: "Scope options enabled",
|
||||
type: :boolean,
|
||||
description: "Enable setting a notice visibility and subject/CW when posting"
|
||||
},
|
||||
%{
|
||||
key: :formattingOptionsEnabled,
|
||||
label: "Formatting options enabled",
|
||||
type: :boolean,
|
||||
description:
|
||||
"Enable setting a formatting different than plain-text (ie. HTML, Markdown) when posting, relates to `:instance`, `allowed_post_formats`"
|
||||
},
|
||||
%{
|
||||
key: :collapseMessageWithSubject,
|
||||
label: "Collapse message with subject",
|
||||
type: :boolean,
|
||||
description:
|
||||
"When a message has a subject (aka Content Warning), collapse it by default"
|
||||
},
|
||||
%{
|
||||
key: :hidePostStats,
|
||||
label: "Hide post stats",
|
||||
type: :boolean,
|
||||
description: "Hide notices statistics (repeats, favorites, ...)"
|
||||
},
|
||||
%{
|
||||
key: :hideUserStats,
|
||||
label: "Hide user stats",
|
||||
type: :boolean,
|
||||
description:
|
||||
"Hide profile statistics (posts, posts per day, followers, followings, ...)"
|
||||
},
|
||||
%{
|
||||
key: :scopeCopy,
|
||||
label: "Scope copy",
|
||||
type: :boolean,
|
||||
description: "Copy the scope (private/unlisted/public) in replies to posts by default"
|
||||
},
|
||||
%{
|
||||
key: :showFeaturesPanel,
|
||||
label: "Show instance features panel",
|
||||
type: :boolean,
|
||||
description:
|
||||
"Enables panel displaying functionality of the instance on the About page."
|
||||
},
|
||||
%{
|
||||
key: :showInstanceSpecificPanel,
|
||||
label: "Show instance specific panel",
|
||||
type: :boolean,
|
||||
description: "Whether to show the instance's custom panel"
|
||||
},
|
||||
%{
|
||||
key: :subjectLineBehavior,
|
||||
label: "Subject line behavior",
|
||||
|
@ -1217,38 +1280,10 @@
|
|||
suggestions: ["email", "masto", "noop"]
|
||||
},
|
||||
%{
|
||||
key: :alwaysShowSubjectInput,
|
||||
label: "Always show subject input",
|
||||
type: :boolean,
|
||||
description: "When disabled, auto-hide the subject field if it's empty"
|
||||
},
|
||||
%{
|
||||
key: :logoMask,
|
||||
label: "Logo mask",
|
||||
type: :boolean,
|
||||
description:
|
||||
"By default it assumes logo used will be monochrome with alpha channel to be compatible with both light and dark themes. " <>
|
||||
"If you want a colorful logo you must disable logoMask."
|
||||
},
|
||||
%{
|
||||
key: :logoMargin,
|
||||
label: "Logo margin",
|
||||
key: :theme,
|
||||
type: :string,
|
||||
description:
|
||||
"Allows you to adjust vertical margins between logo boundary and navbar borders. " <>
|
||||
"The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout.",
|
||||
suggestions: [".1em"]
|
||||
},
|
||||
%{
|
||||
key: :stickers,
|
||||
type: :boolean,
|
||||
description: "Enables stickers."
|
||||
},
|
||||
%{
|
||||
key: :enableEmojiPicker,
|
||||
label: "Emoji picker",
|
||||
type: :boolean,
|
||||
description: "Enables emoji picker."
|
||||
description: "Which theme to use. Available themes are defined in styles.json",
|
||||
suggestions: ["pleroma-dark"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1858,12 +1893,6 @@
|
|||
(see https://github.com/sorentwo/oban/issues/52).
|
||||
""",
|
||||
children: [
|
||||
%{
|
||||
key: :repo,
|
||||
type: :module,
|
||||
description: "Application's Ecto repo",
|
||||
suggestions: [Pleroma.Repo]
|
||||
},
|
||||
%{
|
||||
key: :verbose,
|
||||
type: {:dropdown, :atom},
|
||||
|
@ -2638,18 +2667,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
group: :http_signatures,
|
||||
type: :group,
|
||||
description: "HTTP Signatures settings",
|
||||
children: [
|
||||
%{
|
||||
key: :adapter,
|
||||
type: :module,
|
||||
suggestions: [Pleroma.Signature]
|
||||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
group: :pleroma,
|
||||
key: :http,
|
||||
|
|
|
@ -67,8 +67,7 @@ def run(["render_timeline", nickname | _] = args) do
|
|||
Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: true
|
||||
as: :activity
|
||||
})
|
||||
end
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
defmodule Mix.Tasks.Pleroma.Digest do
|
||||
use Mix.Task
|
||||
import Mix.Pleroma
|
||||
|
||||
@shortdoc "Manages digest emails"
|
||||
@moduledoc File.read!("docs/administration/CLI_tasks/digest.md")
|
||||
|
@ -22,12 +23,10 @@ def run(["test", nickname | opts]) do
|
|||
with %Swoosh.Email{} = email <- Pleroma.Emails.UserEmail.digest_email(patched_user) do
|
||||
{:ok, _} = Pleroma.Emails.Mailer.deliver(email)
|
||||
|
||||
Mix.shell().info("Digest email have been sent to #{nickname} (#{user.email})")
|
||||
shell_info("Digest email have been sent to #{nickname} (#{user.email})")
|
||||
else
|
||||
_ ->
|
||||
Mix.shell().info(
|
||||
"Cound't find any mentions for #{nickname} since #{last_digest_emailed_at}"
|
||||
)
|
||||
shell_info("Cound't find any mentions for #{nickname} since #{last_digest_emailed_at}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -278,6 +278,8 @@ defp do_convert({:proxy_url, {type, host, port}}) do
|
|||
}
|
||||
end
|
||||
|
||||
defp do_convert({:partial_chain, entity}), do: %{"tuple" => [":partial_chain", inspect(entity)]}
|
||||
|
||||
defp do_convert(entity) when is_tuple(entity) do
|
||||
value =
|
||||
entity
|
||||
|
@ -321,6 +323,15 @@ defp do_transform(%{"tuple" => [":proxy_url", %{"tuple" => [type, host, port]}]}
|
|||
{:proxy_url, {do_transform_string(type), parse_host(host), port}}
|
||||
end
|
||||
|
||||
defp do_transform(%{"tuple" => [":partial_chain", entity]}) do
|
||||
{partial_chain, []} =
|
||||
entity
|
||||
|> String.replace(~r/[^\w|^{:,[|^,|^[|^\]^}|^\/|^\.|^"]^\s/, "")
|
||||
|> Code.eval_string()
|
||||
|
||||
{:partial_chain, partial_chain}
|
||||
end
|
||||
|
||||
defp do_transform(%{"tuple" => entity}) do
|
||||
Enum.reduce(entity, {}, fn val, acc -> Tuple.append(acc, do_transform(val)) end)
|
||||
end
|
||||
|
|
|
@ -87,6 +87,22 @@ def dictionary(
|
|||
source_to_target_rel_types \\ nil,
|
||||
target_to_source_rel_types \\ nil
|
||||
)
|
||||
|
||||
def dictionary(
|
||||
_source_users,
|
||||
_target_users,
|
||||
[] = _source_to_target_rel_types,
|
||||
[] = _target_to_source_rel_types
|
||||
) do
|
||||
[]
|
||||
end
|
||||
|
||||
def dictionary(
|
||||
source_users,
|
||||
target_users,
|
||||
source_to_target_rel_types,
|
||||
target_to_source_rel_types
|
||||
)
|
||||
when is_list(source_users) and is_list(target_users) do
|
||||
source_user_ids = User.binary_id(source_users)
|
||||
target_user_ids = User.binary_id(target_users)
|
||||
|
@ -138,11 +154,16 @@ def view_relationships_option(nil = _reading_user, _actors, _opts) do
|
|||
|
||||
def view_relationships_option(%User{} = reading_user, actors, opts) do
|
||||
{source_to_target_rel_types, target_to_source_rel_types} =
|
||||
if opts[:source_mutes_only] do
|
||||
# This option is used for rendering statuses (FE needs `muted` flag for each one anyways)
|
||||
case opts[:subset] do
|
||||
:source_mutes ->
|
||||
# Used for statuses rendering (FE needs `muted` flag for each status when statuses load)
|
||||
{[:mute], []}
|
||||
else
|
||||
|
||||
nil ->
|
||||
{[:block, :mute, :notification_mute, :reblog_mute], [:block, :inverse_subscription]}
|
||||
|
||||
unknown ->
|
||||
raise "Unsupported :subset option value: #{inspect(unknown)}"
|
||||
end
|
||||
|
||||
user_relationships =
|
||||
|
@ -153,7 +174,17 @@ def view_relationships_option(%User{} = reading_user, actors, opts) do
|
|||
target_to_source_rel_types
|
||||
)
|
||||
|
||||
following_relationships = FollowingRelationship.all_between_user_sets([reading_user], actors)
|
||||
following_relationships =
|
||||
case opts[:subset] do
|
||||
:source_mutes ->
|
||||
[]
|
||||
|
||||
nil ->
|
||||
FollowingRelationship.all_between_user_sets([reading_user], actors)
|
||||
|
||||
unknown ->
|
||||
raise "Unsupported :subset option value: #{inspect(unknown)}"
|
||||
end
|
||||
|
||||
%{user_relationships: user_relationships, following_relationships: following_relationships}
|
||||
end
|
||||
|
|
|
@ -22,6 +22,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
alias Pleroma.Web.ActivityPub.Pipeline
|
||||
alias Pleroma.Web.ActivityPub.Relay
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.AdminAPI
|
||||
alias Pleroma.Web.AdminAPI.AccountView
|
||||
alias Pleroma.Web.AdminAPI.ConfigView
|
||||
alias Pleroma.Web.AdminAPI.ModerationLogView
|
||||
|
@ -30,8 +31,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
alias Pleroma.Web.AdminAPI.Search
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.MastodonAPI
|
||||
alias Pleroma.Web.MastodonAPI.AppView
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
alias Pleroma.Web.OAuth.App
|
||||
alias Pleroma.Web.Router
|
||||
|
||||
|
@ -280,8 +281,8 @@ def list_instance_statuses(conn, %{"instance" => instance} = params) do
|
|||
})
|
||||
|
||||
conn
|
||||
|> put_view(Pleroma.Web.AdminAPI.StatusView)
|
||||
|> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
|
||||
|> put_view(AdminAPI.StatusView)
|
||||
|> render("index.json", %{activities: activities, as: :activity})
|
||||
end
|
||||
|
||||
def list_user_statuses(conn, %{"nickname" => nickname} = params) do
|
||||
|
@ -299,8 +300,8 @@ def list_user_statuses(conn, %{"nickname" => nickname} = params) do
|
|||
})
|
||||
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
|
||||
|> put_view(MastodonAPI.StatusView)
|
||||
|> render("index.json", %{activities: activities, as: :activity})
|
||||
else
|
||||
_ -> {:error, :not_found}
|
||||
end
|
||||
|
@ -829,14 +830,14 @@ def list_statuses(%{assigns: %{user: _admin}} = conn, params) do
|
|||
})
|
||||
|
||||
conn
|
||||
|> put_view(Pleroma.Web.AdminAPI.StatusView)
|
||||
|> render("index.json", %{activities: activities, as: :activity, skip_relationships: false})
|
||||
|> put_view(AdminAPI.StatusView)
|
||||
|> render("index.json", %{activities: activities, as: :activity})
|
||||
end
|
||||
|
||||
def status_show(conn, %{"id" => id}) do
|
||||
with %Activity{} = activity <- Activity.get_by_id(id) do
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> put_view(MastodonAPI.StatusView)
|
||||
|> render("show.json", %{activity: activity})
|
||||
else
|
||||
_ -> errors(conn, {:error, :not_found})
|
||||
|
@ -861,7 +862,7 @@ def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
|
|||
})
|
||||
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> put_view(MastodonAPI.StatusView)
|
||||
|> render("show.json", %{activity: activity})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,9 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
|
|||
use Pleroma.Web, :view
|
||||
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.AdminAPI
|
||||
alias Pleroma.Web.AdminAPI.AccountView
|
||||
alias Pleroma.Web.MastodonAPI
|
||||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
def render("index.json", %{users: users, count: count, page_size: page_size}) do
|
||||
|
@ -119,6 +121,13 @@ def render("create-error.json", %{changeset: %Ecto.Changeset{changes: changes, e
|
|||
}
|
||||
end
|
||||
|
||||
def merge_account_views(%User{} = user) do
|
||||
MastodonAPI.AccountView.render("show.json", %{user: user})
|
||||
|> Map.merge(AdminAPI.AccountView.render("show.json", %{user: user}))
|
||||
end
|
||||
|
||||
def merge_account_views(_), do: %{}
|
||||
|
||||
defp parse_error([]), do: ""
|
||||
|
||||
defp parse_error(errors) do
|
||||
|
|
|
@ -7,10 +7,13 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
|
|||
|
||||
alias Pleroma.HTML
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.AdminAPI
|
||||
alias Pleroma.Web.AdminAPI.Report
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
|
||||
defdelegate merge_account_views(user), to: AdminAPI.AccountView
|
||||
|
||||
def render("index.json", %{reports: reports}) do
|
||||
%{
|
||||
reports:
|
||||
|
@ -41,8 +44,7 @@ def render("show.json", %{report: report, user: user, account: account, statuses
|
|||
statuses:
|
||||
StatusView.render("index.json", %{
|
||||
activities: statuses,
|
||||
as: :activity,
|
||||
skip_relationships: false
|
||||
as: :activity
|
||||
}),
|
||||
state: report.data["state"],
|
||||
notes: render(__MODULE__, "index_notes.json", %{notes: report.report_notes})
|
||||
|
@ -70,11 +72,4 @@ def render("show_note.json", %{
|
|||
created_at: Utils.to_masto_date(inserted_at)
|
||||
}
|
||||
end
|
||||
|
||||
defp merge_account_views(%User{} = user) do
|
||||
Pleroma.Web.MastodonAPI.AccountView.render("show.json", %{user: user})
|
||||
|> Map.merge(Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user}))
|
||||
end
|
||||
|
||||
defp merge_account_views(_), do: %{}
|
||||
end
|
||||
|
|
|
@ -7,24 +7,19 @@ defmodule Pleroma.Web.AdminAPI.StatusView do
|
|||
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
alias Pleroma.Web.AdminAPI
|
||||
alias Pleroma.Web.MastodonAPI
|
||||
|
||||
defdelegate merge_account_views(user), to: AdminAPI.AccountView
|
||||
|
||||
def render("index.json", opts) do
|
||||
safe_render_many(opts.activities, __MODULE__, "show.json", opts)
|
||||
end
|
||||
|
||||
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
|
||||
user = StatusView.get_user(activity.data["actor"])
|
||||
user = MastodonAPI.StatusView.get_user(activity.data["actor"])
|
||||
|
||||
StatusView.render("show.json", opts)
|
||||
MastodonAPI.StatusView.render("show.json", opts)
|
||||
|> Map.merge(%{account: merge_account_views(user)})
|
||||
end
|
||||
|
||||
defp merge_account_views(%User{} = user) do
|
||||
Pleroma.Web.MastodonAPI.AccountView.render("show.json", %{user: user})
|
||||
|> Map.merge(Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user}))
|
||||
end
|
||||
|
||||
defp merge_account_views(_), do: %{}
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.ApiSpec.Helpers do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
|
||||
|
||||
def request_body(description, schema_ref, opts \\ []) do
|
||||
media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"]
|
||||
|
@ -47,6 +48,15 @@ def pagination_params do
|
|||
]
|
||||
end
|
||||
|
||||
def with_relationships_param do
|
||||
Operation.parameter(
|
||||
:with_relationships,
|
||||
:query,
|
||||
BooleanLike,
|
||||
"Embed relationships into accounts."
|
||||
)
|
||||
end
|
||||
|
||||
def empty_object_response do
|
||||
Operation.response("Empty object", "application/json", %Schema{type: :object, example: %{}})
|
||||
end
|
||||
|
|
|
@ -155,8 +155,10 @@ def followers_operation do
|
|||
security: [%{"oAuth" => ["read:accounts"]}],
|
||||
description:
|
||||
"Accounts which follow the given account, if network is not hidden by the account owner.",
|
||||
parameters:
|
||||
[%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(),
|
||||
parameters: [
|
||||
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
|
||||
with_relationships_param() | pagination_params()
|
||||
],
|
||||
responses: %{
|
||||
200 => Operation.response("Accounts", "application/json", array_of_accounts())
|
||||
}
|
||||
|
@ -171,8 +173,10 @@ def following_operation do
|
|||
security: [%{"oAuth" => ["read:accounts"]}],
|
||||
description:
|
||||
"Accounts which the given account is following, if network is not hidden by the account owner.",
|
||||
parameters:
|
||||
[%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(),
|
||||
parameters: [
|
||||
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
|
||||
with_relationships_param() | pagination_params()
|
||||
],
|
||||
responses: %{200 => Operation.response("Accounts", "application/json", array_of_accounts())}
|
||||
}
|
||||
end
|
||||
|
|
132
lib/pleroma/web/api_spec/operations/media_operation.ex
Normal file
132
lib/pleroma/web/api_spec/operations/media_operation.ex
Normal file
|
@ -0,0 +1,132 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.MediaOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Helpers
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Attachment
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def create_operation do
|
||||
%Operation{
|
||||
tags: ["media"],
|
||||
summary: "Upload media as attachment",
|
||||
description: "Creates an attachment to be used with a new status.",
|
||||
operationId: "MediaController.create",
|
||||
security: [%{"oAuth" => ["write:media"]}],
|
||||
requestBody: Helpers.request_body("Parameters", create_request()),
|
||||
responses: %{
|
||||
200 => Operation.response("Media", "application/json", Attachment),
|
||||
401 => Operation.response("Media", "application/json", ApiError),
|
||||
422 => Operation.response("Media", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp create_request do
|
||||
%Schema{
|
||||
title: "MediaCreateRequest",
|
||||
description: "POST body for creating an attachment",
|
||||
type: :object,
|
||||
required: [:file],
|
||||
properties: %{
|
||||
file: %Schema{
|
||||
type: :string,
|
||||
format: :binary,
|
||||
description: "The file to be attached, using multipart form data."
|
||||
},
|
||||
description: %Schema{
|
||||
type: :string,
|
||||
description: "A plain-text description of the media, for accessibility purposes."
|
||||
},
|
||||
focus: %Schema{
|
||||
type: :string,
|
||||
description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0."
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["media"],
|
||||
summary: "Upload media as attachment",
|
||||
description: "Creates an attachment to be used with a new status.",
|
||||
operationId: "MediaController.update",
|
||||
security: [%{"oAuth" => ["write:media"]}],
|
||||
parameters: [id_param()],
|
||||
requestBody: Helpers.request_body("Parameters", update_request()),
|
||||
responses: %{
|
||||
200 => Operation.response("Media", "application/json", Attachment),
|
||||
400 => Operation.response("Media", "application/json", ApiError),
|
||||
401 => Operation.response("Media", "application/json", ApiError),
|
||||
422 => Operation.response("Media", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp update_request do
|
||||
%Schema{
|
||||
title: "MediaUpdateRequest",
|
||||
description: "POST body for updating an attachment",
|
||||
type: :object,
|
||||
properties: %{
|
||||
file: %Schema{
|
||||
type: :string,
|
||||
format: :binary,
|
||||
description: "The file to be attached, using multipart form data."
|
||||
},
|
||||
description: %Schema{
|
||||
type: :string,
|
||||
description: "A plain-text description of the media, for accessibility purposes."
|
||||
},
|
||||
focus: %Schema{
|
||||
type: :string,
|
||||
description: "Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0."
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["media"],
|
||||
summary: "Show Uploaded media attachment",
|
||||
operationId: "MediaController.show",
|
||||
parameters: [id_param()],
|
||||
security: [%{"oAuth" => ["read:media"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Media", "application/json", Attachment),
|
||||
401 => Operation.response("Media", "application/json", ApiError),
|
||||
422 => Operation.response("Media", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def create2_operation do
|
||||
%Operation{
|
||||
tags: ["media"],
|
||||
summary: "Upload media as attachment",
|
||||
description: "Creates an attachment to be used with a new status.",
|
||||
operationId: "MediaController.create2",
|
||||
security: [%{"oAuth" => ["write:media"]}],
|
||||
requestBody: Helpers.request_body("Parameters", create_request()),
|
||||
responses: %{
|
||||
202 => Operation.response("Media", "application/json", Attachment),
|
||||
422 => Operation.response("Media", "application/json", ApiError),
|
||||
500 => Operation.response("Media", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp id_param do
|
||||
Operation.parameter(:id, :path, :string, "The ID of the Attachment entity")
|
||||
end
|
||||
end
|
|
@ -19,6 +19,7 @@ def open_api_operation(action) do
|
|||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
# Note: `with_relationships` param is not supported (PleromaFE uses this op for autocomplete)
|
||||
def account_search_operation do
|
||||
%Operation{
|
||||
tags: ["Search"],
|
||||
|
@ -96,8 +97,8 @@ def search_operation do
|
|||
:query,
|
||||
%Schema{type: :integer},
|
||||
"Offset"
|
||||
)
|
||||
| pagination_params()
|
||||
),
|
||||
with_relationships_param() | pagination_params()
|
||||
],
|
||||
responses: %{
|
||||
200 => Operation.response("Results", "application/json", results())
|
||||
|
@ -138,8 +139,8 @@ def search2_operation do
|
|||
:query,
|
||||
%Schema{allOf: [BooleanLike], default: false},
|
||||
"Only include accounts that the user is following"
|
||||
)
|
||||
| pagination_params()
|
||||
),
|
||||
with_relationships_param() | pagination_params()
|
||||
],
|
||||
responses: %{
|
||||
200 => Operation.response("Results", "application/json", results2())
|
||||
|
|
|
@ -7,7 +7,6 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
|||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.AccountOperation
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
|
||||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Status
|
||||
|
@ -349,10 +348,7 @@ def bookmarks_operation do
|
|||
summary: "Bookmarked statuses",
|
||||
description: "Statuses the user has bookmarked",
|
||||
operationId: "StatusController.bookmarks",
|
||||
parameters: [
|
||||
Operation.parameter(:with_relationships, :query, BooleanLike, "Include relationships")
|
||||
| pagination_params()
|
||||
],
|
||||
parameters: pagination_params(),
|
||||
security: [%{"oAuth" => ["read:bookmarks"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Array of Statuses", "application/json", array_of_statuses())
|
||||
|
|
|
@ -27,8 +27,7 @@ def home_operation do
|
|||
local_param(),
|
||||
with_muted_param(),
|
||||
exclude_visibilities_param(),
|
||||
reply_visibility_param(),
|
||||
with_relationships_param() | pagination_params()
|
||||
reply_visibility_param() | pagination_params()
|
||||
],
|
||||
operationId: "TimelineController.home",
|
||||
responses: %{
|
||||
|
@ -63,8 +62,7 @@ def public_operation do
|
|||
only_media_param(),
|
||||
with_muted_param(),
|
||||
exclude_visibilities_param(),
|
||||
reply_visibility_param(),
|
||||
with_relationships_param() | pagination_params()
|
||||
reply_visibility_param() | pagination_params()
|
||||
],
|
||||
operationId: "TimelineController.public",
|
||||
responses: %{
|
||||
|
@ -109,8 +107,7 @@ def hashtag_operation do
|
|||
local_param(),
|
||||
only_media_param(),
|
||||
with_muted_param(),
|
||||
exclude_visibilities_param(),
|
||||
with_relationships_param() | pagination_params()
|
||||
exclude_visibilities_param() | pagination_params()
|
||||
],
|
||||
operationId: "TimelineController.hashtag",
|
||||
responses: %{
|
||||
|
@ -134,8 +131,7 @@ def list_operation do
|
|||
required: true
|
||||
),
|
||||
with_muted_param(),
|
||||
exclude_visibilities_param(),
|
||||
with_relationships_param() | pagination_params()
|
||||
exclude_visibilities_param() | pagination_params()
|
||||
],
|
||||
operationId: "TimelineController.list",
|
||||
responses: %{
|
||||
|
@ -153,10 +149,6 @@ defp array_of_statuses do
|
|||
}
|
||||
end
|
||||
|
||||
defp with_relationships_param do
|
||||
Operation.parameter(:with_relationships, :query, BooleanLike, "Include relationships")
|
||||
end
|
||||
|
||||
defp local_param do
|
||||
Operation.parameter(
|
||||
:local,
|
||||
|
|
|
@ -13,7 +13,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Attachment do
|
|||
type: :object,
|
||||
requried: [:id, :url, :preview_url],
|
||||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
id: %Schema{type: :string, description: "The ID of the attachment in the database."},
|
||||
url: %Schema{
|
||||
type: :string,
|
||||
format: :uri,
|
||||
|
|
|
@ -23,6 +23,7 @@ def handle_in("new_msg", %{"text" => text}, %{assigns: %{user_name: user_name}}
|
|||
if String.length(text) in 1..Pleroma.Config.get([:instance, :chat_limit]) do
|
||||
author = User.get_cached_by_nickname(user_name)
|
||||
author = Pleroma.Web.MastodonAPI.AccountView.render("show.json", user: author)
|
||||
|
||||
message = ChatChannelState.add_message(%{text: text, author: author})
|
||||
|
||||
broadcast!(socket, "new_msg", message)
|
||||
|
|
|
@ -65,10 +65,21 @@ defp validate_chat_content_length(content, _) do
|
|||
end
|
||||
|
||||
def unblock(blocker, blocked) do
|
||||
with %Activity{} = block <- Utils.fetch_latest_block(blocker, blocked),
|
||||
with {_, %Activity{} = block} <- {:fetch_block, Utils.fetch_latest_block(blocker, blocked)},
|
||||
{:ok, unblock_data, _} <- Builder.undo(blocker, block),
|
||||
{:ok, unblock, _} <- Pipeline.common_pipeline(unblock_data, local: true) do
|
||||
{:ok, unblock}
|
||||
else
|
||||
{:fetch_block, nil} ->
|
||||
if User.blocks?(blocker, blocked) do
|
||||
User.unblock(blocker, blocked)
|
||||
{:ok, :no_activity}
|
||||
else
|
||||
{:error, :not_blocking}
|
||||
end
|
||||
|
||||
e ->
|
||||
e
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
defmodule Pleroma.Web.ControllerHelper do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
alias Pleroma.Config
|
||||
|
||||
# As in Mastodon API, per https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
|
||||
@falsy_param_values [false, 0, "0", "f", "F", "false", "False", "FALSE", "off", "OFF"]
|
||||
|
||||
|
@ -106,13 +104,16 @@ def put_if_exist(map, _key, nil), do: map
|
|||
|
||||
def put_if_exist(map, key, value), do: Map.put(map, key, value)
|
||||
|
||||
@doc "Whether to skip rendering `[:account][:pleroma][:relationship]`for statuses/notifications"
|
||||
def skip_relationships?(params) do
|
||||
if Config.get([:extensions, :output_relationships_in_statuses_by_default]) do
|
||||
false
|
||||
else
|
||||
# BREAKING: older PleromaFE versions do not send this param but _do_ expect relationships.
|
||||
not truthy_param?(params["with_relationships"])
|
||||
end
|
||||
@doc """
|
||||
Returns true if request specifies to include embedded relationships in account objects.
|
||||
May only be used in selected account-related endpoints; has no effect for status- or
|
||||
notification-related endpoints.
|
||||
"""
|
||||
# Intended for PleromaFE: https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838
|
||||
def embed_relationships?(params) do
|
||||
# To do once OpenAPI transition mess is over: just `truthy_param?(params[:with_relationships])`
|
||||
params
|
||||
|> Map.get(:with_relationships, params["with_relationships"])
|
||||
|> truthy_param?()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,8 +10,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
|||
add_link_headers: 2,
|
||||
truthy_param?: 1,
|
||||
assign_account_by_id: 2,
|
||||
json_response: 3,
|
||||
skip_relationships?: 1
|
||||
embed_relationships?: 1,
|
||||
json_response: 3
|
||||
]
|
||||
|
||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||
|
@ -247,8 +247,7 @@ def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: reading_user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
else
|
||||
_e -> render_error(conn, :not_found, "Can't find user")
|
||||
|
@ -271,7 +270,13 @@ def followers(%{assigns: %{user: for_user, account: user}} = conn, params) do
|
|||
|
||||
conn
|
||||
|> add_link_headers(followers)
|
||||
|> render("index.json", for: for_user, users: followers, as: :user)
|
||||
# https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838#note_59223
|
||||
|> render("index.json",
|
||||
for: for_user,
|
||||
users: followers,
|
||||
as: :user,
|
||||
embed_relationships: embed_relationships?(params)
|
||||
)
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/accounts/:id/following"
|
||||
|
@ -290,7 +295,13 @@ def following(%{assigns: %{user: for_user, account: user}} = conn, params) do
|
|||
|
||||
conn
|
||||
|> add_link_headers(followers)
|
||||
|> render("index.json", for: for_user, users: followers, as: :user)
|
||||
# https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838#note_59223
|
||||
|> render("index.json",
|
||||
for: for_user,
|
||||
users: followers,
|
||||
as: :user,
|
||||
embed_relationships: embed_relationships?(params)
|
||||
)
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/accounts/:id/lists"
|
||||
|
|
|
@ -11,17 +11,20 @@ defmodule Pleroma.Web.MastodonAPI.MediaController do
|
|||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
|
||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)
|
||||
|
||||
plug(OAuthScopesPlug, %{scopes: ["write:media"]})
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.MediaOperation
|
||||
|
||||
@doc "POST /api/v1/media"
|
||||
def create(%{assigns: %{user: user}} = conn, %{"file" => file} = data) do
|
||||
def create(%{assigns: %{user: user}, body_params: %{file: file} = data} = conn, _) do
|
||||
with {:ok, object} <-
|
||||
ActivityPub.upload(
|
||||
file,
|
||||
actor: User.ap_id(user),
|
||||
description: Map.get(data, "description")
|
||||
description: Map.get(data, :description)
|
||||
) do
|
||||
attachment_data = Map.put(object.data, "id", object.id)
|
||||
|
||||
|
@ -29,9 +32,28 @@ def create(%{assigns: %{user: user}} = conn, %{"file" => file} = data) do
|
|||
end
|
||||
end
|
||||
|
||||
def create(_conn, _data), do: {:error, :bad_request}
|
||||
|
||||
@doc "POST /api/v2/media"
|
||||
def create2(%{assigns: %{user: user}, body_params: %{file: file} = data} = conn, _) do
|
||||
with {:ok, object} <-
|
||||
ActivityPub.upload(
|
||||
file,
|
||||
actor: User.ap_id(user),
|
||||
description: Map.get(data, :description)
|
||||
) do
|
||||
attachment_data = Map.put(object.data, "id", object.id)
|
||||
|
||||
conn
|
||||
|> put_status(202)
|
||||
|> render("attachment.json", %{attachment: attachment_data})
|
||||
end
|
||||
end
|
||||
|
||||
def create2(_conn, _data), do: {:error, :bad_request}
|
||||
|
||||
@doc "PUT /api/v1/media/:id"
|
||||
def update(%{assigns: %{user: user}} = conn, %{"id" => id, "description" => description})
|
||||
when is_binary(description) do
|
||||
def update(%{assigns: %{user: user}, body_params: %{description: description}} = conn, %{id: id}) do
|
||||
with %Object{} = object <- Object.get_by_id(id),
|
||||
true <- Object.authorize_mutation(object, user),
|
||||
{:ok, %Object{data: data}} <- Object.update_data(object, %{"name" => description}) do
|
||||
|
@ -41,5 +63,16 @@ def update(%{assigns: %{user: user}} = conn, %{"id" => id, "description" => desc
|
|||
end
|
||||
end
|
||||
|
||||
def update(_conn, _data), do: {:error, :bad_request}
|
||||
def update(conn, data), do: show(conn, data)
|
||||
|
||||
@doc "GET /api/v1/media/:id"
|
||||
def show(conn, %{id: id}) do
|
||||
with %Object{data: data, id: object_id} <- Object.get_by_id(id) do
|
||||
attachment_data = Map.put(data, "id", object_id)
|
||||
|
||||
render(conn, "attachment.json", %{attachment: attachment_data})
|
||||
end
|
||||
end
|
||||
|
||||
def get_media(_conn, _data), do: {:error, :bad_request}
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.NotificationController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1]
|
||||
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
|
||||
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Plugs.OAuthScopesPlug
|
||||
|
@ -50,8 +50,7 @@ def index(%{assigns: %{user: user}} = conn, params) do
|
|||
|> add_link_headers(notifications)
|
||||
|> render("index.json",
|
||||
notifications: notifications,
|
||||
for: user,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
for: user
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -5,14 +5,13 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.SearchController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper, only: [skip_relationships?: 1]
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.Plugs.RateLimiter
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web
|
||||
alias Pleroma.Web.ControllerHelper
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
|
||||
|
@ -34,7 +33,11 @@ def account_search(%{assigns: %{user: user}} = conn, %{q: query} = params) do
|
|||
|
||||
conn
|
||||
|> put_view(AccountView)
|
||||
|> render("index.json", users: accounts, for: user, as: :user)
|
||||
|> render("index.json",
|
||||
users: accounts,
|
||||
for: user,
|
||||
as: :user
|
||||
)
|
||||
end
|
||||
|
||||
def search2(conn, params), do: do_search(:v2, conn, params)
|
||||
|
@ -71,13 +74,13 @@ defp do_search(version, %{assigns: %{user: user}} = conn, %{q: query} = params)
|
|||
|
||||
defp search_options(params, user) do
|
||||
[
|
||||
skip_relationships: skip_relationships?(params),
|
||||
resolve: params[:resolve],
|
||||
following: params[:following],
|
||||
limit: params[:limit],
|
||||
offset: params[:offset],
|
||||
type: params[:type],
|
||||
author: get_author(params),
|
||||
embed_relationships: ControllerHelper.embed_relationships?(params),
|
||||
for_user: user
|
||||
]
|
||||
|> Enum.filter(&elem(&1, 1))
|
||||
|
@ -90,7 +93,7 @@ defp resource_search(_, "accounts", query, options) do
|
|||
users: accounts,
|
||||
for: options[:for_user],
|
||||
as: :user,
|
||||
skip_relationships: false
|
||||
embed_relationships: options[:embed_relationships]
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -100,8 +103,7 @@ defp resource_search(_, "statuses", query, options) do
|
|||
StatusView.render("index.json",
|
||||
activities: statuses,
|
||||
for: options[:for_user],
|
||||
as: :activity,
|
||||
skip_relationships: options[:skip_relationships]
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
|||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper,
|
||||
only: [try_render: 3, add_link_headers: 2, skip_relationships?: 1]
|
||||
only: [try_render: 3, add_link_headers: 2]
|
||||
|
||||
require Ecto.Query
|
||||
|
||||
|
@ -105,7 +105,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
|||
|
||||
`ids` query param is required
|
||||
"""
|
||||
def index(%{assigns: %{user: user}} = conn, %{ids: ids} = params) do
|
||||
def index(%{assigns: %{user: user}} = conn, %{ids: ids} = _params) do
|
||||
limit = 100
|
||||
|
||||
activities =
|
||||
|
@ -117,8 +117,7 @@ def index(%{assigns: %{user: user}} = conn, %{ids: ids} = params) do
|
|||
render(conn, "index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -383,8 +382,7 @@ def favourites(%{assigns: %{user: %User{} = user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -406,8 +404,7 @@ def bookmarks(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper,
|
||||
only: [add_link_headers: 2, add_link_headers: 3, skip_relationships?: 1]
|
||||
only: [add_link_headers: 2, add_link_headers: 3]
|
||||
|
||||
alias Pleroma.Pagination
|
||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||
|
@ -63,8 +63,7 @@ def home(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -88,8 +87,7 @@ def direct(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -125,8 +123,7 @@ def public(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -173,8 +170,7 @@ def hashtag(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -203,8 +199,7 @@ def list(%{assigns: %{user: user}} = conn, %{list_id: id} = params) do
|
|||
render(conn, "index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
else
|
||||
_e -> render_error(conn, :forbidden, "Error.")
|
||||
|
|
|
@ -15,13 +15,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
|
|||
def render("index.json", %{users: users} = opts) do
|
||||
reading_user = opts[:for]
|
||||
|
||||
# Note: :skip_relationships option is currently intentionally not supported for accounts
|
||||
relationships_opt =
|
||||
cond do
|
||||
Map.has_key?(opts, :relationships) ->
|
||||
opts[:relationships]
|
||||
|
||||
is_nil(reading_user) ->
|
||||
is_nil(reading_user) || !opts[:embed_relationships] ->
|
||||
UserRelationship.view_relationships_option(nil, [])
|
||||
|
||||
true ->
|
||||
|
@ -193,14 +192,14 @@ defp do_render("show.json", %{user: user} = opts) do
|
|||
end)
|
||||
|
||||
relationship =
|
||||
if opts[:skip_relationships] do
|
||||
%{}
|
||||
else
|
||||
if opts[:embed_relationships] do
|
||||
render("relationship.json", %{
|
||||
user: opts[:for],
|
||||
target: user,
|
||||
relationships: opts[:relationships]
|
||||
})
|
||||
else
|
||||
%{}
|
||||
end
|
||||
|
||||
%{
|
||||
|
|
|
@ -53,9 +53,7 @@ def render("index.json", %{notifications: notifications, for: reading_user} = op
|
|||
|> Enum.filter(& &1)
|
||||
|> Kernel.++(move_activities_targets)
|
||||
|
||||
UserRelationship.view_relationships_option(reading_user, actors,
|
||||
source_mutes_only: opts[:skip_relationships]
|
||||
)
|
||||
UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
|
||||
end
|
||||
|
||||
opts =
|
||||
|
@ -99,15 +97,13 @@ def render(
|
|||
type
|
||||
end
|
||||
|
||||
render_opts = %{
|
||||
relationships: opts[:relationships],
|
||||
skip_relationships: opts[:skip_relationships]
|
||||
}
|
||||
# Note: :relationships contain user mutes (needed for :muted flag in :status)
|
||||
status_render_opts = %{relationships: opts[:relationships]}
|
||||
|
||||
with %{id: _} = account <-
|
||||
AccountView.render(
|
||||
"show.json",
|
||||
Map.merge(render_opts, %{user: actor, for: reading_user})
|
||||
%{user: actor, for: reading_user}
|
||||
) do
|
||||
response = %{
|
||||
id: to_string(notification.id),
|
||||
|
@ -121,25 +117,24 @@ def render(
|
|||
|
||||
case mastodon_type do
|
||||
"mention" ->
|
||||
put_status(response, activity, reading_user, render_opts)
|
||||
put_status(response, activity, reading_user, status_render_opts)
|
||||
|
||||
"favourite" ->
|
||||
put_status(response, parent_activity_fn.(), reading_user, render_opts)
|
||||
put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
|
||||
|
||||
"reblog" ->
|
||||
put_status(response, parent_activity_fn.(), reading_user, render_opts)
|
||||
put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
|
||||
|
||||
"move" ->
|
||||
# Note: :skip_relationships option being applied to _account_ rendering (here)
|
||||
put_target(response, activity, reading_user, render_opts)
|
||||
put_target(response, activity, reading_user, %{})
|
||||
|
||||
"pleroma:emoji_reaction" ->
|
||||
response
|
||||
|> put_status(parent_activity_fn.(), reading_user, render_opts)
|
||||
|> put_status(parent_activity_fn.(), reading_user, status_render_opts)
|
||||
|> put_emoji(activity)
|
||||
|
||||
"pleroma:chat_mention" ->
|
||||
put_chat_message(response, activity, reading_user, render_opts)
|
||||
put_chat_message(response, activity, reading_user, status_render_opts)
|
||||
|
||||
type when type in ["follow", "follow_request"] ->
|
||||
response
|
||||
|
|
|
@ -107,9 +107,7 @@ def render("index.json", opts) do
|
|||
|> Enum.map(&get_user(&1.data["actor"], false))
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
UserRelationship.view_relationships_option(reading_user, actors,
|
||||
source_mutes_only: opts[:skip_relationships]
|
||||
)
|
||||
UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
|
||||
end
|
||||
|
||||
opts =
|
||||
|
@ -162,9 +160,7 @@ def render(
|
|||
account:
|
||||
AccountView.render("show.json", %{
|
||||
user: user,
|
||||
for: opts[:for],
|
||||
relationships: opts[:relationships],
|
||||
skip_relationships: opts[:skip_relationships]
|
||||
for: opts[:for]
|
||||
}),
|
||||
in_reply_to_id: nil,
|
||||
in_reply_to_account_id: nil,
|
||||
|
@ -330,9 +326,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
|||
account:
|
||||
AccountView.render("show.json", %{
|
||||
user: user,
|
||||
for: opts[:for],
|
||||
relationships: opts[:relationships],
|
||||
skip_relationships: opts[:skip_relationships]
|
||||
for: opts[:for]
|
||||
}),
|
||||
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),
|
||||
|
|
|
@ -6,7 +6,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
|||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper,
|
||||
only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2, skip_relationships?: 1]
|
||||
only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2]
|
||||
|
||||
alias Ecto.Changeset
|
||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||
|
@ -149,8 +149,7 @@ def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: for_user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1]
|
||||
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Conversation.Participation
|
||||
|
@ -69,7 +69,12 @@ def emoji_reactions_by(%{assigns: %{user: user}} = conn, %{"id" => activity_id}
|
|||
%{
|
||||
name: emoji,
|
||||
count: length(users),
|
||||
accounts: AccountView.render("index.json", %{users: users, for: user, as: :user}),
|
||||
accounts:
|
||||
AccountView.render("index.json", %{
|
||||
users: users,
|
||||
for: user,
|
||||
as: :user
|
||||
}),
|
||||
me: !!(user && user.ap_id in user_ap_ids)
|
||||
}
|
||||
end
|
||||
|
@ -145,8 +150,7 @@ def conversation_statuses(
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
as: :activity
|
||||
)
|
||||
else
|
||||
_error ->
|
||||
|
@ -201,7 +205,7 @@ def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"id" => notif
|
|||
end
|
||||
end
|
||||
|
||||
def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => max_id} = params) do
|
||||
def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => max_id}) do
|
||||
with notifications <- Notification.set_read_up_to(user, max_id) do
|
||||
notifications = Enum.take(notifications, 80)
|
||||
|
||||
|
@ -209,8 +213,7 @@ def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => m
|
|||
|> put_view(NotificationView)
|
||||
|> render("index.json",
|
||||
notifications: notifications,
|
||||
for: user,
|
||||
skip_relationships: skip_relationships?(params)
|
||||
for: user
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -415,6 +415,7 @@ defmodule Pleroma.Web.Router do
|
|||
post("/markers", MarkerController, :upsert)
|
||||
|
||||
post("/media", MediaController, :create)
|
||||
get("/media/:id", MediaController, :show)
|
||||
put("/media/:id", MediaController, :update)
|
||||
|
||||
get("/notifications", NotificationController, :index)
|
||||
|
@ -509,6 +510,8 @@ defmodule Pleroma.Web.Router do
|
|||
scope "/api/v2", Pleroma.Web.MastodonAPI do
|
||||
pipe_through(:api)
|
||||
get("/search", SearchController, :search2)
|
||||
|
||||
post("/media", MediaController, :create2)
|
||||
end
|
||||
|
||||
scope "/api", Pleroma.Web do
|
||||
|
|
578
priv/gettext/nl/LC_MESSAGES/errors.po
Normal file
578
priv/gettext/nl/LC_MESSAGES/errors.po
Normal file
|
@ -0,0 +1,578 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-15 09:37+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Translate Toolkit 2.5.1\n"
|
||||
|
||||
## This file is a PO Template file.
|
||||
##
|
||||
## `msgid`s here are often extracted from source code.
|
||||
## Add new translations manually only if they're dynamic
|
||||
## translations that can't be statically extracted.
|
||||
##
|
||||
## Run `mix gettext.extract` to bring this file up to
|
||||
## date. Leave `msgstr`s empty as changing them here as no
|
||||
## effect: edit them in PO (`.po`) files instead.
|
||||
## From Ecto.Changeset.cast/4
|
||||
msgid "can't be blank"
|
||||
msgstr ""
|
||||
|
||||
## From Ecto.Changeset.unique_constraint/3
|
||||
msgid "has already been taken"
|
||||
msgstr ""
|
||||
|
||||
## From Ecto.Changeset.put_change/3
|
||||
msgid "is invalid"
|
||||
msgstr ""
|
||||
|
||||
## From Ecto.Changeset.validate_format/3
|
||||
msgid "has invalid format"
|
||||
msgstr ""
|
||||
|
||||
## From Ecto.Changeset.validate_subset/3
|
||||
msgid "has an invalid entry"
|
||||
msgstr ""
|
||||
|
||||
## From Ecto.Changeset.validate_exclusion/3
|
||||
msgid "is reserved"
|
||||
msgstr ""
|
||||
|
||||
## From Ecto.Changeset.validate_confirmation/3
|
||||
msgid "does not match confirmation"
|
||||
msgstr ""
|
||||
|
||||
## From Ecto.Changeset.no_assoc_constraint/3
|
||||
msgid "is still associated with this entry"
|
||||
msgstr ""
|
||||
|
||||
msgid "are still associated with this entry"
|
||||
msgstr ""
|
||||
|
||||
## From Ecto.Changeset.validate_length/3
|
||||
msgid "should be %{count} character(s)"
|
||||
msgid_plural "should be %{count} character(s)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "should have %{count} item(s)"
|
||||
msgid_plural "should have %{count} item(s)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "should be at least %{count} character(s)"
|
||||
msgid_plural "should be at least %{count} character(s)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "should have at least %{count} item(s)"
|
||||
msgid_plural "should have at least %{count} item(s)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "should be at most %{count} character(s)"
|
||||
msgid_plural "should be at most %{count} character(s)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "should have at most %{count} item(s)"
|
||||
msgid_plural "should have at most %{count} item(s)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
## From Ecto.Changeset.validate_number/3
|
||||
msgid "must be less than %{number}"
|
||||
msgstr ""
|
||||
|
||||
msgid "must be greater than %{number}"
|
||||
msgstr ""
|
||||
|
||||
msgid "must be less than or equal to %{number}"
|
||||
msgstr ""
|
||||
|
||||
msgid "must be greater than or equal to %{number}"
|
||||
msgstr ""
|
||||
|
||||
msgid "must be equal to %{number}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:421
|
||||
#, elixir-format
|
||||
msgid "Account not found"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:249
|
||||
#, elixir-format
|
||||
msgid "Already voted"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:360
|
||||
#, elixir-format
|
||||
msgid "Bad request"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:425
|
||||
#, elixir-format
|
||||
msgid "Can't delete object"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:196
|
||||
#, elixir-format
|
||||
msgid "Can't delete this post"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/controller_helper.ex:95
|
||||
#: lib/pleroma/web/controller_helper.ex:101
|
||||
#, elixir-format
|
||||
msgid "Can't display this activity"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:227
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:254
|
||||
#, elixir-format
|
||||
msgid "Can't find user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:114
|
||||
#, elixir-format
|
||||
msgid "Can't get favorites"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:437
|
||||
#, elixir-format
|
||||
msgid "Can't like object"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/utils.ex:556
|
||||
#, elixir-format
|
||||
msgid "Cannot post an empty status without attachments"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/utils.ex:504
|
||||
#, elixir-format
|
||||
msgid "Comment must be up to %{max_size} characters"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/config/config_db.ex:222
|
||||
#, elixir-format
|
||||
msgid "Config with params %{params} not found"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:95
|
||||
#, elixir-format
|
||||
msgid "Could not delete"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:141
|
||||
#, elixir-format
|
||||
msgid "Could not favorite"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:370
|
||||
#, elixir-format
|
||||
msgid "Could not pin"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:112
|
||||
#, elixir-format
|
||||
msgid "Could not repeat"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:188
|
||||
#, elixir-format
|
||||
msgid "Could not unfavorite"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:380
|
||||
#, elixir-format
|
||||
msgid "Could not unpin"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:126
|
||||
#, elixir-format
|
||||
msgid "Could not unrepeat"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:428
|
||||
#: lib/pleroma/web/common_api/common_api.ex:437
|
||||
#, elixir-format
|
||||
msgid "Could not update state"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:202
|
||||
#, elixir-format
|
||||
msgid "Error."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:106
|
||||
#, elixir-format
|
||||
msgid "Invalid CAPTCHA"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:117
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:569
|
||||
#, elixir-format
|
||||
msgid "Invalid credentials"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:38
|
||||
#, elixir-format
|
||||
msgid "Invalid credentials."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:265
|
||||
#, elixir-format
|
||||
msgid "Invalid indices"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:1147
|
||||
#, elixir-format
|
||||
msgid "Invalid parameters"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/utils.ex:411
|
||||
#, elixir-format
|
||||
msgid "Invalid password."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:187
|
||||
#, elixir-format
|
||||
msgid "Invalid request"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:109
|
||||
#, elixir-format
|
||||
msgid "Kocaptcha service unavailable"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:113
|
||||
#, elixir-format
|
||||
msgid "Missing parameters"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/utils.ex:540
|
||||
#, elixir-format
|
||||
msgid "No such conversation"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:439
|
||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:465 lib/pleroma/web/admin_api/admin_api_controller.ex:507
|
||||
#, elixir-format
|
||||
msgid "No such permission_group"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/uploaded_media.ex:74
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:485 lib/pleroma/web/admin_api/admin_api_controller.ex:1135
|
||||
#: lib/pleroma/web/feed/user_controller.ex:73 lib/pleroma/web/ostatus/ostatus_controller.ex:143
|
||||
#, elixir-format
|
||||
msgid "Not found"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:241
|
||||
#, elixir-format
|
||||
msgid "Poll's author can't vote"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20
|
||||
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:37 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:49
|
||||
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:50 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:290
|
||||
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71
|
||||
#, elixir-format
|
||||
msgid "Record not found"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:1153
|
||||
#: lib/pleroma/web/feed/user_controller.ex:79 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:32
|
||||
#: lib/pleroma/web/ostatus/ostatus_controller.ex:149
|
||||
#, elixir-format
|
||||
msgid "Something went wrong"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/activity_draft.ex:107
|
||||
#, elixir-format
|
||||
msgid "The message visibility must be direct"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/utils.ex:566
|
||||
#, elixir-format
|
||||
msgid "The status is over the character limit"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:31
|
||||
#, elixir-format
|
||||
msgid "This resource requires authentication."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/rate_limiter/rate_limiter.ex:206
|
||||
#, elixir-format
|
||||
msgid "Throttled"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:266
|
||||
#, elixir-format
|
||||
msgid "Too many choices"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:442
|
||||
#, elixir-format
|
||||
msgid "Unhandled activity type"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:536
|
||||
#, elixir-format
|
||||
msgid "You can't revoke your own admin status."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:218
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:309
|
||||
#, elixir-format
|
||||
msgid "Your account is currently disabled"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:180
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:332
|
||||
#, elixir-format
|
||||
msgid "Your login is missing a confirmed e-mail address"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:389
|
||||
#, elixir-format
|
||||
msgid "can't read inbox of %{nickname} as %{as_nickname}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:472
|
||||
#, elixir-format
|
||||
msgid "can't update outbox of %{nickname} as %{as_nickname}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:388
|
||||
#, elixir-format
|
||||
msgid "conversation is already muted"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:316
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:491
|
||||
#, elixir-format
|
||||
msgid "error"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:29
|
||||
#, elixir-format
|
||||
msgid "mascots can only be images"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:60
|
||||
#, elixir-format
|
||||
msgid "not found"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:395
|
||||
#, elixir-format
|
||||
msgid "Bad OAuth request."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:115
|
||||
#, elixir-format
|
||||
msgid "CAPTCHA already used"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:112
|
||||
#, elixir-format
|
||||
msgid "CAPTCHA expired"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/uploaded_media.ex:55
|
||||
#, elixir-format
|
||||
msgid "Failed"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:411
|
||||
#, elixir-format
|
||||
msgid "Failed to authenticate: %{message}."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:442
|
||||
#, elixir-format
|
||||
msgid "Failed to set up user account."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/oauth_scopes_plug.ex:38
|
||||
#, elixir-format
|
||||
msgid "Insufficient permissions: %{permissions}."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/uploaded_media.ex:94
|
||||
#, elixir-format
|
||||
msgid "Internal Error"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/fallback_controller.ex:22
|
||||
#: lib/pleroma/web/oauth/fallback_controller.ex:29
|
||||
#, elixir-format
|
||||
msgid "Invalid Username/Password"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:118
|
||||
#, elixir-format
|
||||
msgid "Invalid answer data"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:128
|
||||
#, elixir-format
|
||||
msgid "Nodeinfo schema version not handled"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:169
|
||||
#, elixir-format
|
||||
msgid "This action is outside the authorized scopes"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/fallback_controller.ex:14
|
||||
#, elixir-format
|
||||
msgid "Unknown error, please check the details and try again."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:116
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:155
|
||||
#, elixir-format
|
||||
msgid "Unlisted redirect_uri."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:391
|
||||
#, elixir-format
|
||||
msgid "Unsupported OAuth provider: %{provider}."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/uploaders/uploader.ex:72
|
||||
#, elixir-format
|
||||
msgid "Uploader callback timeout"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/uploader_controller.ex:23
|
||||
#, elixir-format
|
||||
msgid "bad request"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:103
|
||||
#, elixir-format
|
||||
msgid "CAPTCHA Error"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:200
|
||||
#, elixir-format
|
||||
msgid "Could not add reaction emoji"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/common_api/common_api.ex:211
|
||||
#, elixir-format
|
||||
msgid "Could not remove reaction emoji"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/twitter_api/twitter_api.ex:129
|
||||
#, elixir-format
|
||||
msgid "Invalid CAPTCHA (Missing parameter: %{name})"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:92
|
||||
#, elixir-format
|
||||
msgid "List not found"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:124
|
||||
#, elixir-format
|
||||
msgid "Missing parameter: %{name}"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:207
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:322
|
||||
#, elixir-format
|
||||
msgid "Password reset is required"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/tests/auth_test_controller.ex:9
|
||||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/admin_api_controller.ex:6
|
||||
#: lib/pleroma/web/controller_helper.ex:6 lib/pleroma/web/fallback_redirect_controller.ex:6
|
||||
#: lib/pleroma/web/feed/tag_controller.ex:6 lib/pleroma/web/feed/user_controller.ex:6
|
||||
#: lib/pleroma/web/mailer/subscription_controller.ex:2 lib/pleroma/web/masto_fe_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/app_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/auth_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/filter_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/instance_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/marker_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex:14 lib/pleroma/web/mastodon_api/controllers/media_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/notification_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/report_controller.ex:8 lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/search_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:7 lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex:6
|
||||
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:6 lib/pleroma/web/media_proxy/media_proxy_controller.ex:6
|
||||
#: lib/pleroma/web/mongooseim/mongoose_im_controller.ex:6 lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:6
|
||||
#: lib/pleroma/web/oauth/fallback_controller.ex:6 lib/pleroma/web/oauth/mfa_controller.ex:10
|
||||
#: lib/pleroma/web/oauth/oauth_controller.ex:6 lib/pleroma/web/ostatus/ostatus_controller.ex:6
|
||||
#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:2
|
||||
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex:6
|
||||
#: lib/pleroma/web/pleroma_api/controllers/scrobble_controller.ex:6
|
||||
#: lib/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller.ex:7 lib/pleroma/web/static_fe/static_fe_controller.ex:6
|
||||
#: lib/pleroma/web/twitter_api/controllers/password_controller.ex:10 lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex:6
|
||||
#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:6 lib/pleroma/web/twitter_api/twitter_api_controller.ex:6
|
||||
#: lib/pleroma/web/uploader_controller.ex:6 lib/pleroma/web/web_finger/web_finger_controller.ex:6
|
||||
#, elixir-format
|
||||
msgid "Security violation: OAuth scopes check was neither handled nor explicitly skipped."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:28
|
||||
#, elixir-format
|
||||
msgid "Two-factor authentication enabled, you must use a access token."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:210
|
||||
#, elixir-format
|
||||
msgid "Unexpected error occurred while adding file to pack."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:138
|
||||
#, elixir-format
|
||||
msgid "Unexpected error occurred while creating pack."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:278
|
||||
#, elixir-format
|
||||
msgid "Unexpected error occurred while removing file from pack."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:250
|
||||
#, elixir-format
|
||||
msgid "Unexpected error occurred while updating file in pack."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex:179
|
||||
#, elixir-format
|
||||
msgid "Unexpected error occurred while updating pack metadata."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/plugs/user_is_admin_plug.ex:40
|
||||
#, elixir-format
|
||||
msgid "User is not an admin or OAuth admin scope is not granted."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61
|
||||
#, elixir-format
|
||||
msgid "Web push subscription is disabled on this Pleroma instance"
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/admin_api/admin_api_controller.ex:502
|
||||
#, elixir-format
|
||||
msgid "You can't revoke your own admin/moderator status."
|
||||
msgstr ""
|
||||
|
||||
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:105
|
||||
#, elixir-format
|
||||
msgid "authorization required for timeline view"
|
||||
msgstr ""
|
|
@ -3,8 +3,8 @@ msgstr ""
|
|||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-13 16:37+0000\n"
|
||||
"PO-Revision-Date: 2020-05-14 14:37+0000\n"
|
||||
"Last-Translator: Michał Sidor <pleromeme@meekchopp.es>\n"
|
||||
"PO-Revision-Date: 2020-05-16 17:13+0000\n"
|
||||
"Last-Translator: Jędrzej Tomaszewski <jederow@hotmail.com>\n"
|
||||
"Language-Team: Polish <https://translate.pleroma.social/projects/pleroma/"
|
||||
"pleroma/pl/>\n"
|
||||
"Language: pl\n"
|
||||
|
@ -46,7 +46,7 @@ msgstr "ma niepoprawny wpis"
|
|||
|
||||
## From Ecto.Changeset.validate_exclusion/3
|
||||
msgid "is reserved"
|
||||
msgstr ""
|
||||
msgstr "jest zarezerwowany"
|
||||
|
||||
## From Ecto.Changeset.validate_confirmation/3
|
||||
msgid "does not match confirmation"
|
||||
|
@ -54,17 +54,17 @@ msgstr ""
|
|||
|
||||
## From Ecto.Changeset.no_assoc_constraint/3
|
||||
msgid "is still associated with this entry"
|
||||
msgstr ""
|
||||
msgstr "jest wciąż powiązane z tym wpisem"
|
||||
|
||||
msgid "are still associated with this entry"
|
||||
msgstr ""
|
||||
msgstr "są wciąż powiązane z tym wpisem"
|
||||
|
||||
## From Ecto.Changeset.validate_length/3
|
||||
msgid "should be %{count} character(s)"
|
||||
msgid_plural "should be %{count} character(s)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
msgstr[0] "powinno mieć %{count} znak"
|
||||
msgstr[1] "powinno mieć %{count} znaki"
|
||||
msgstr[2] "powinno mieć %{count} znaków"
|
||||
|
||||
msgid "should have %{count} item(s)"
|
||||
msgid_plural "should have %{count} item(s)"
|
||||
|
|
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.18fea621d430000acc27.css rel=stylesheet><link href=/static/css/app.613cef07981cd95ccceb.css rel=stylesheet><link href=/static/fontello.1588947937982.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.561a1c605d1dfb0e6f74.js></script><script type=text/javascript src=/static/js/app.996428ccaaaa7f28cb8d.js></script></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.18fea621d430000acc27.css rel=stylesheet><link href=/static/css/app.613cef07981cd95ccceb.css rel=stylesheet><link href=/static/fontello.1589385935077.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.561a1c605d1dfb0e6f74.js></script><script type=text/javascript src=/static/js/app.838ffa9aecf210c7d744.js></script></body></html>
|
|
@ -1,23 +1,28 @@
|
|||
{
|
||||
"theme": "pleroma-dark",
|
||||
"background": "/static/aurora_borealis.jpg",
|
||||
"logo": "/static/logo.png",
|
||||
"logoMask": true,
|
||||
"logoMargin": ".1em",
|
||||
"redirectRootNoLogin": "/main/all",
|
||||
"redirectRootLogin": "/main/friends",
|
||||
"showInstanceSpecificPanel": false,
|
||||
"collapseMessageWithSubject": false,
|
||||
"scopeCopy": true,
|
||||
"subjectLineBehavior": "email",
|
||||
"postContentType": "text/plain",
|
||||
"alwaysShowSubjectInput": true,
|
||||
"background": "/static/aurora_borealis.jpg",
|
||||
"collapseMessageWithSubject": false,
|
||||
"disableChat": false,
|
||||
"greentext": false,
|
||||
"hideFilteredStatuses": false,
|
||||
"hideMutedPosts": false,
|
||||
"hidePostStats": false,
|
||||
"hideSitename": false,
|
||||
"hideUserStats": false,
|
||||
"loginMethod": "password",
|
||||
"webPushNotifications": false,
|
||||
"logo": "/static/logo.png",
|
||||
"logoMargin": ".1em",
|
||||
"logoMask": true,
|
||||
"minimalScopesMode": false,
|
||||
"noAttachmentLinks": false,
|
||||
"nsfwCensorImage": "",
|
||||
"postContentType": "text/plain",
|
||||
"redirectRootLogin": "/main/friends",
|
||||
"redirectRootNoLogin": "/main/all",
|
||||
"scopeCopy": true,
|
||||
"showFeaturesPanel": true,
|
||||
"minimalScopesMode": false
|
||||
"showInstanceSpecificPanel": false,
|
||||
"subjectLineBehavior": "email",
|
||||
"theme": "pleroma-dark",
|
||||
"webPushNotifications": false
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Binary file not shown.
Binary file not shown.
BIN
priv/static/static/font/fontello.1589385935077.woff2
Normal file
BIN
priv/static/static/font/fontello.1589385935077.woff2
Normal file
Binary file not shown.
|
@ -1,11 +1,11 @@
|
|||
@font-face {
|
||||
font-family: "Icons";
|
||||
src: url("./font/fontello.1588947937982.eot");
|
||||
src: url("./font/fontello.1588947937982.eot") format("embedded-opentype"),
|
||||
url("./font/fontello.1588947937982.woff2") format("woff2"),
|
||||
url("./font/fontello.1588947937982.woff") format("woff"),
|
||||
url("./font/fontello.1588947937982.ttf") format("truetype"),
|
||||
url("./font/fontello.1588947937982.svg") format("svg");
|
||||
src: url("./font/fontello.1589385935077.eot");
|
||||
src: url("./font/fontello.1589385935077.eot") format("embedded-opentype"),
|
||||
url("./font/fontello.1589385935077.woff2") format("woff2"),
|
||||
url("./font/fontello.1589385935077.woff") format("woff"),
|
||||
url("./font/fontello.1589385935077.ttf") format("truetype"),
|
||||
url("./font/fontello.1589385935077.svg") format("svg");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
2
priv/static/static/js/app.838ffa9aecf210c7d744.js
Normal file
2
priv/static/static/js/app.838ffa9aecf210c7d744.js
Normal file
File diff suppressed because one or more lines are too long
1
priv/static/static/js/app.838ffa9aecf210c7d744.js.map
Normal file
1
priv/static/static/js/app.838ffa9aecf210c7d744.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
var serviceWorkerOption = {"assets":["/static/fontello.1588947937982.css","/static/font/fontello.1588947937982.eot","/static/font/fontello.1588947937982.svg","/static/font/fontello.1588947937982.ttf","/static/font/fontello.1588947937982.woff","/static/font/fontello.1588947937982.woff2","/static/img/nsfw.74818f9.png","/static/css/app.613cef07981cd95ccceb.css","/static/js/app.996428ccaaaa7f28cb8d.js","/static/css/vendors~app.18fea621d430000acc27.css","/static/js/vendors~app.561a1c605d1dfb0e6f74.js","/static/js/2.18e4adec273c4ce867a8.js"]};
|
||||
var serviceWorkerOption = {"assets":["/static/fontello.1589385935077.css","/static/font/fontello.1589385935077.eot","/static/font/fontello.1589385935077.svg","/static/font/fontello.1589385935077.ttf","/static/font/fontello.1589385935077.woff","/static/font/fontello.1589385935077.woff2","/static/img/nsfw.74818f9.png","/static/css/app.613cef07981cd95ccceb.css","/static/js/app.838ffa9aecf210c7d744.js","/static/css/vendors~app.18fea621d430000acc27.css","/static/js/vendors~app.561a1c605d1dfb0e6f74.js","/static/js/2.18e4adec273c4ce867a8.js"]};
|
||||
|
||||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/",t(t.s=1)}([function(e,n){
|
||||
/*!
|
||||
|
|
|
@ -476,6 +476,14 @@ test "simple keyword" do
|
|||
assert ConfigDB.from_binary(binary) == [key: "value"]
|
||||
end
|
||||
|
||||
test "keyword with partial_chain key" do
|
||||
binary =
|
||||
ConfigDB.transform([%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}])
|
||||
|
||||
assert binary == :erlang.term_to_binary(partial_chain: &:hackney_connect.partial_chain/1)
|
||||
assert ConfigDB.from_binary(binary) == [partial_chain: &:hackney_connect.partial_chain/1]
|
||||
end
|
||||
|
||||
test "keyword" do
|
||||
binary =
|
||||
ConfigDB.transform([
|
||||
|
|
|
@ -2509,6 +2509,7 @@ test "common config example", %{conn: conn} do
|
|||
%{"tuple" => [":seconds_valid", 60]},
|
||||
%{"tuple" => [":path", ""]},
|
||||
%{"tuple" => [":key1", nil]},
|
||||
%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
|
||||
%{"tuple" => [":regex1", "~r/https:\/\/example.com/"]},
|
||||
%{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]},
|
||||
%{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]},
|
||||
|
@ -2532,6 +2533,7 @@ test "common config example", %{conn: conn} do
|
|||
%{"tuple" => [":seconds_valid", 60]},
|
||||
%{"tuple" => [":path", ""]},
|
||||
%{"tuple" => [":key1", nil]},
|
||||
%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
|
||||
%{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]},
|
||||
%{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]},
|
||||
%{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]},
|
||||
|
@ -2544,6 +2546,7 @@ test "common config example", %{conn: conn} do
|
|||
":seconds_valid",
|
||||
":path",
|
||||
":key1",
|
||||
":partial_chain",
|
||||
":regex1",
|
||||
":regex2",
|
||||
":regex3",
|
||||
|
|
|
@ -98,6 +98,18 @@ test "it reject messages over the local limit" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "unblocking" do
|
||||
test "it works even without an existing block activity" do
|
||||
blocked = insert(:user)
|
||||
blocker = insert(:user)
|
||||
User.block(blocker, blocked)
|
||||
|
||||
assert User.blocks?(blocker, blocked)
|
||||
assert {:ok, :no_activity} == CommonAPI.unblock(blocker, blocked)
|
||||
refute User.blocks?(blocker, blocked)
|
||||
end
|
||||
end
|
||||
|
||||
describe "deletion" do
|
||||
test "it works with pruned objects" do
|
||||
user = insert(:user)
|
||||
|
|
|
@ -11,7 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
|||
|
||||
setup do: oauth_access(["write:media"])
|
||||
|
||||
describe "media upload" do
|
||||
describe "Upload media" do
|
||||
setup do
|
||||
image = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
|
@ -25,13 +25,14 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
|||
setup do: clear_config([:media_proxy])
|
||||
setup do: clear_config([Pleroma.Upload])
|
||||
|
||||
test "returns uploaded image", %{conn: conn, image: image} do
|
||||
test "/api/v1/media", %{conn: conn, image: image} do
|
||||
desc = "Description of the image"
|
||||
|
||||
media =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/v1/media", %{"file" => image, "description" => desc})
|
||||
|> json_response(:ok)
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert media["type"] == "image"
|
||||
assert media["description"] == desc
|
||||
|
@ -40,9 +41,32 @@ test "returns uploaded image", %{conn: conn, image: image} do
|
|||
object = Object.get_by_id(media["id"])
|
||||
assert object.data["actor"] == User.ap_id(conn.assigns[:user])
|
||||
end
|
||||
|
||||
test "/api/v2/media", %{conn: conn, image: image} do
|
||||
desc = "Description of the image"
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/v2/media", %{"file" => image, "description" => desc})
|
||||
|> json_response_and_validate_schema(202)
|
||||
|
||||
assert media_id = response["id"]
|
||||
|
||||
media =
|
||||
conn
|
||||
|> get("/api/v1/media/#{media_id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert media["type"] == "image"
|
||||
assert media["description"] == desc
|
||||
assert media["id"]
|
||||
object = Object.get_by_id(media["id"])
|
||||
assert object.data["actor"] == User.ap_id(conn.assigns[:user])
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /api/v1/media/:id" do
|
||||
describe "Update media description" do
|
||||
setup %{user: actor} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
|
@ -60,23 +84,45 @@ test "returns uploaded image", %{conn: conn, image: image} do
|
|||
[object: object]
|
||||
end
|
||||
|
||||
test "updates name of media", %{conn: conn, object: object} do
|
||||
test "/api/v1/media/:id good request", %{conn: conn, object: object} do
|
||||
media =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> put("/api/v1/media/#{object.id}", %{"description" => "test-media"})
|
||||
|> json_response(:ok)
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert media["description"] == "test-media"
|
||||
assert refresh_record(object).data["name"] == "test-media"
|
||||
end
|
||||
end
|
||||
|
||||
test "returns error when request is bad", %{conn: conn, object: object} do
|
||||
describe "Get media by id" do
|
||||
setup %{user: actor} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, %Object{} = object} =
|
||||
ActivityPub.upload(
|
||||
file,
|
||||
actor: User.ap_id(actor),
|
||||
description: "test-media"
|
||||
)
|
||||
|
||||
[object: object]
|
||||
end
|
||||
|
||||
test "/api/v1/media/:id", %{conn: conn, object: object} do
|
||||
media =
|
||||
conn
|
||||
|> put("/api/v1/media/#{object.id}", %{})
|
||||
|> json_response(400)
|
||||
|> get("/api/v1/media/#{object.id}")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert media == %{"error" => "bad_request"}
|
||||
assert media["description"] == "test-media"
|
||||
assert media["type"] == "image"
|
||||
assert media["id"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,9 +12,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "does NOT render account/pleroma/relationship if this is disabled by default" do
|
||||
clear_config([:extensions, :output_relationships_in_statuses_by_default], false)
|
||||
|
||||
test "does NOT render account/pleroma/relationship by default" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
||||
|
|
|
@ -1176,7 +1176,7 @@ test "replaces missing description with an empty string", %{conn: conn, user: us
|
|||
end
|
||||
|
||||
test "bookmarks" do
|
||||
bookmarks_uri = "/api/v1/bookmarks?with_relationships=true"
|
||||
bookmarks_uri = "/api/v1/bookmarks"
|
||||
|
||||
%{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"])
|
||||
author = insert(:user)
|
||||
|
|
|
@ -20,12 +20,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
describe "home" do
|
||||
setup do: oauth_access(["read:statuses"])
|
||||
|
||||
test "does NOT render account/pleroma/relationship if this is disabled by default", %{
|
||||
test "does NOT embed account/pleroma/relationship in statuses", %{
|
||||
user: user,
|
||||
conn: conn
|
||||
} do
|
||||
clear_config([:extensions, :output_relationships_in_statuses_by_default], false)
|
||||
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
|
||||
|
@ -41,75 +39,6 @@ test "does NOT render account/pleroma/relationship if this is disabled by defaul
|
|||
end)
|
||||
end
|
||||
|
||||
test "the home timeline", %{user: user, conn: conn} do
|
||||
uri = "/api/v1/timelines/home?with_relationships=1"
|
||||
|
||||
following = insert(:user, nickname: "followed")
|
||||
third_user = insert(:user, nickname: "repeated")
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(following, %{status: "post"})
|
||||
{:ok, activity} = CommonAPI.post(third_user, %{status: "repeated post"})
|
||||
{:ok, _, _} = CommonAPI.repeat(activity.id, following)
|
||||
|
||||
# This one should not show up in the TL
|
||||
{:ok, _activity} = CommonAPI.post_chat_message(third_user, user, ":gun:")
|
||||
|
||||
ret_conn = get(conn, uri)
|
||||
|
||||
assert Enum.empty?(json_response_and_validate_schema(ret_conn, :ok))
|
||||
|
||||
{:ok, _user} = User.follow(user, following)
|
||||
|
||||
ret_conn = get(conn, uri)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"reblog" => %{
|
||||
"content" => "repeated post",
|
||||
"account" => %{
|
||||
"pleroma" => %{
|
||||
"relationship" => %{"following" => false, "followed_by" => false}
|
||||
}
|
||||
}
|
||||
},
|
||||
"account" => %{"pleroma" => %{"relationship" => %{"following" => true}}}
|
||||
},
|
||||
%{
|
||||
"content" => "post",
|
||||
"account" => %{
|
||||
"acct" => "followed",
|
||||
"pleroma" => %{"relationship" => %{"following" => true}}
|
||||
}
|
||||
}
|
||||
] = json_response_and_validate_schema(ret_conn, :ok)
|
||||
|
||||
{:ok, _user} = User.follow(third_user, user)
|
||||
|
||||
ret_conn = get(conn, uri)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"reblog" => %{
|
||||
"content" => "repeated post",
|
||||
"account" => %{
|
||||
"acct" => "repeated",
|
||||
"pleroma" => %{
|
||||
"relationship" => %{"following" => false, "followed_by" => true}
|
||||
}
|
||||
}
|
||||
},
|
||||
"account" => %{"pleroma" => %{"relationship" => %{"following" => true}}}
|
||||
},
|
||||
%{
|
||||
"content" => "post",
|
||||
"account" => %{
|
||||
"acct" => "followed",
|
||||
"pleroma" => %{"relationship" => %{"following" => true}}
|
||||
}
|
||||
}
|
||||
] = json_response_and_validate_schema(ret_conn, :ok)
|
||||
end
|
||||
|
||||
test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do
|
||||
{:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
|
||||
{:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
|
||||
|
|
|
@ -304,83 +304,6 @@ test "represent a relationship for the user with a pending follow request" do
|
|||
end
|
||||
end
|
||||
|
||||
test "represent an embedded relationship" do
|
||||
user =
|
||||
insert(:user, %{
|
||||
follower_count: 0,
|
||||
note_count: 5,
|
||||
actor_type: "Service",
|
||||
nickname: "shp@shitposter.club",
|
||||
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
||||
})
|
||||
|
||||
other_user = insert(:user)
|
||||
{:ok, other_user} = User.follow(other_user, user)
|
||||
{:ok, _user_relationship} = User.block(other_user, user)
|
||||
{:ok, _} = User.follow(insert(:user), user)
|
||||
|
||||
expected = %{
|
||||
id: to_string(user.id),
|
||||
username: "shp",
|
||||
acct: user.nickname,
|
||||
display_name: user.name,
|
||||
locked: false,
|
||||
created_at: "2017-08-15T15:47:06.000Z",
|
||||
followers_count: 1,
|
||||
following_count: 0,
|
||||
statuses_count: 5,
|
||||
note: user.bio,
|
||||
url: user.ap_id,
|
||||
avatar: "http://localhost:4001/images/avi.png",
|
||||
avatar_static: "http://localhost:4001/images/avi.png",
|
||||
header: "http://localhost:4001/images/banner.png",
|
||||
header_static: "http://localhost:4001/images/banner.png",
|
||||
emojis: [],
|
||||
fields: [],
|
||||
bot: true,
|
||||
source: %{
|
||||
note: user.bio,
|
||||
sensitive: false,
|
||||
pleroma: %{
|
||||
actor_type: "Service",
|
||||
discoverable: false
|
||||
},
|
||||
fields: []
|
||||
},
|
||||
pleroma: %{
|
||||
ap_id: user.ap_id,
|
||||
background_image: nil,
|
||||
confirmation_pending: false,
|
||||
tags: [],
|
||||
is_admin: false,
|
||||
is_moderator: false,
|
||||
hide_favorites: true,
|
||||
hide_followers: false,
|
||||
hide_follows: false,
|
||||
hide_followers_count: false,
|
||||
hide_follows_count: false,
|
||||
relationship: %{
|
||||
id: to_string(user.id),
|
||||
following: false,
|
||||
followed_by: false,
|
||||
blocking: true,
|
||||
blocked_by: false,
|
||||
subscribing: false,
|
||||
muting: false,
|
||||
muting_notifications: false,
|
||||
requested: false,
|
||||
domain_blocking: false,
|
||||
showing_reblogs: true,
|
||||
endorsed: false
|
||||
},
|
||||
skip_thread_containment: false
|
||||
}
|
||||
}
|
||||
|
||||
assert expected ==
|
||||
AccountView.render("show.json", %{user: refresh_record(user), for: other_user})
|
||||
end
|
||||
|
||||
test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
|
||||
user = insert(:user, pleroma_settings_store: %{fe: "test"})
|
||||
|
||||
|
|
|
@ -68,7 +68,11 @@ test "Mention notification" do
|
|||
id: to_string(notification.id),
|
||||
pleroma: %{is_seen: false},
|
||||
type: "mention",
|
||||
account: AccountView.render("show.json", %{user: user, for: mentioned_user}),
|
||||
account:
|
||||
AccountView.render("show.json", %{
|
||||
user: user,
|
||||
for: mentioned_user
|
||||
}),
|
||||
status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}),
|
||||
created_at: Utils.to_masto_date(notification.inserted_at)
|
||||
}
|
||||
|
|
|
@ -576,7 +576,7 @@ test "a rich media card with all relevant data renders correctly" do
|
|||
end
|
||||
end
|
||||
|
||||
test "embeds a relationship in the account" do
|
||||
test "does not embed a relationship in the account" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
|
@ -587,13 +587,11 @@ test "embeds a relationship in the account" do
|
|||
|
||||
result = StatusView.render("show.json", %{activity: activity, for: other_user})
|
||||
|
||||
assert result[:account][:pleroma][:relationship] ==
|
||||
AccountView.render("relationship.json", %{user: other_user, target: user})
|
||||
|
||||
assert result[:account][:pleroma][:relationship] == %{}
|
||||
assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
|
||||
end
|
||||
|
||||
test "embeds a relationship in the account in reposts" do
|
||||
test "does not embed a relationship in the account in reposts" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
|
@ -606,12 +604,8 @@ test "embeds a relationship in the account in reposts" do
|
|||
|
||||
result = StatusView.render("show.json", %{activity: activity, for: user})
|
||||
|
||||
assert result[:account][:pleroma][:relationship] ==
|
||||
AccountView.render("relationship.json", %{user: user, target: other_user})
|
||||
|
||||
assert result[:reblog][:account][:pleroma][:relationship] ==
|
||||
AccountView.render("relationship.json", %{user: user, target: user})
|
||||
|
||||
assert result[:account][:pleroma][:relationship] == %{}
|
||||
assert result[:reblog][:account][:pleroma][:relationship] == %{}
|
||||
assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue