ff4fd002703e78ddb1e35057f86255275ede2e52
[akkoma] / lib / pleroma / web / api_spec / operations / search_operation.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ApiSpec.SearchOperation do
6 alias OpenApiSpex.Operation
7 alias OpenApiSpex.Schema
8 alias Pleroma.Web.ApiSpec.AccountOperation
9 alias Pleroma.Web.ApiSpec.Schemas.Account
10 alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
11 alias Pleroma.Web.ApiSpec.Schemas.FlakeID
12 alias Pleroma.Web.ApiSpec.Schemas.Status
13 alias Pleroma.Web.ApiSpec.Schemas.Tag
14
15 import Pleroma.Web.ApiSpec.Helpers
16
17 def open_api_operation(action) do
18 operation = String.to_existing_atom("#{action}_operation")
19 apply(__MODULE__, operation, [])
20 end
21
22 # Note: `with_relationships` param is not supported (PleromaFE uses this op for autocomplete)
23 def account_search_operation do
24 %Operation{
25 tags: ["Search"],
26 summary: "Search for matching accounts by username or display name",
27 operationId: "SearchController.account_search",
28 parameters: [
29 Operation.parameter(:q, :query, %Schema{type: :string}, "What to search for",
30 required: true
31 ),
32 Operation.parameter(
33 :limit,
34 :query,
35 %Schema{type: :integer, default: 40},
36 "Maximum number of results"
37 ),
38 Operation.parameter(
39 :resolve,
40 :query,
41 %Schema{allOf: [BooleanLike], default: false},
42 "Attempt WebFinger lookup. Use this when `q` is an exact address."
43 ),
44 Operation.parameter(
45 :following,
46 :query,
47 %Schema{allOf: [BooleanLike], default: false},
48 "Only include accounts that the user is following"
49 )
50 ],
51 responses: %{
52 200 =>
53 Operation.response(
54 "Array of Account",
55 "application/json",
56 AccountOperation.array_of_accounts()
57 )
58 }
59 }
60 end
61
62 def search_operation do
63 %Operation{
64 tags: ["Search"],
65 summary: "Search results",
66 security: [%{"oAuth" => ["read:search"]}],
67 operationId: "SearchController.search",
68 deprecated: true,
69 parameters: [
70 Operation.parameter(
71 :account_id,
72 :query,
73 FlakeID,
74 "If provided, statuses returned will be authored only by this account"
75 ),
76 Operation.parameter(
77 :type,
78 :query,
79 %Schema{type: :string, enum: ["accounts", "hashtags", "statuses"]},
80 "Search type"
81 ),
82 Operation.parameter(:q, :query, %Schema{type: :string}, "The search query", required: true),
83 Operation.parameter(
84 :resolve,
85 :query,
86 %Schema{allOf: [BooleanLike], default: false},
87 "Attempt WebFinger lookup"
88 ),
89 Operation.parameter(
90 :following,
91 :query,
92 %Schema{allOf: [BooleanLike], default: false},
93 "Only include accounts that the user is following"
94 ),
95 Operation.parameter(
96 :offset,
97 :query,
98 %Schema{type: :integer},
99 "Offset"
100 ),
101 with_relationships_param() | pagination_params()
102 ],
103 responses: %{
104 200 => Operation.response("Results", "application/json", results())
105 }
106 }
107 end
108
109 def search2_operation do
110 %Operation{
111 tags: ["Search"],
112 summary: "Search results",
113 security: [%{"oAuth" => ["read:search"]}],
114 operationId: "SearchController.search2",
115 parameters: [
116 Operation.parameter(
117 :account_id,
118 :query,
119 FlakeID,
120 "If provided, statuses returned will be authored only by this account"
121 ),
122 Operation.parameter(
123 :type,
124 :query,
125 %Schema{type: :string, enum: ["accounts", "hashtags", "statuses"]},
126 "Search type"
127 ),
128 Operation.parameter(:q, :query, %Schema{type: :string}, "What to search for",
129 required: true
130 ),
131 Operation.parameter(
132 :resolve,
133 :query,
134 %Schema{allOf: [BooleanLike], default: false},
135 "Attempt WebFinger lookup"
136 ),
137 Operation.parameter(
138 :following,
139 :query,
140 %Schema{allOf: [BooleanLike], default: false},
141 "Only include accounts that the user is following"
142 ),
143 with_relationships_param() | pagination_params()
144 ],
145 responses: %{
146 200 => Operation.response("Results", "application/json", results2())
147 }
148 }
149 end
150
151 defp results2 do
152 %Schema{
153 title: "SearchResults",
154 type: :object,
155 properties: %{
156 accounts: %Schema{
157 type: :array,
158 items: Account,
159 description: "Accounts which match the given query"
160 },
161 statuses: %Schema{
162 type: :array,
163 items: Status,
164 description: "Statuses which match the given query"
165 },
166 hashtags: %Schema{
167 type: :array,
168 items: Tag,
169 description: "Hashtags which match the given query"
170 }
171 },
172 example: %{
173 "accounts" => [Account.schema().example],
174 "statuses" => [Status.schema().example],
175 "hashtags" => [Tag.schema().example]
176 }
177 }
178 end
179
180 defp results do
181 %Schema{
182 title: "SearchResults",
183 type: :object,
184 properties: %{
185 accounts: %Schema{
186 type: :array,
187 items: Account,
188 description: "Accounts which match the given query"
189 },
190 statuses: %Schema{
191 type: :array,
192 items: Status,
193 description: "Statuses which match the given query"
194 },
195 hashtags: %Schema{
196 type: :array,
197 items: %Schema{type: :string},
198 description: "Hashtags which match the given query"
199 }
200 },
201 example: %{
202 "accounts" => [Account.schema().example],
203 "statuses" => [Status.schema().example],
204 "hashtags" => ["cofe"]
205 }
206 }
207 end
208 end