diff --git a/README.md b/README.md index e3c2919..1068b6f 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ The following activities are supported: - Like(Note) - Undo(Like) - Announce(Note) +- Undo(Announce) - Follow(Person) - Update(Person) diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 031a229..cbb37e4 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -5,6 +5,34 @@ info: version: 1.0.0 paths: + /api/v1/directory: + get: + summary: List accounts visible in the directory. + parameters: + - name: offset + in: query + description: How many accounts to skip before returning results. + required: false + schema: + type: integer + default: 0 + - name: limit + in: query + description: How many accounts to load. + required: false + schema: + type: integer + default: 40 + responses: + 200: + description: Successful operation + content: + application/json: + schema: + description: Profile list + type: array + items: + $ref: '#/components/schemas/Account' /api/v1/accounts/{account_id}/statuses: get: summary: Statuses posted to the given account. @@ -178,6 +206,21 @@ components: type: string format: uuid schemas: + Account: + type: object + properties: + id: + description: The account id. + type: string + format: uuid + username: + description: The username of the actor, not including domain. + type: string + example: user + acct: + description: The Webfinger account URI. Equal to username for local actors, or username@domain for remote actors. + type: string + example: user@example.com Status: type: object properties: diff --git a/src/mastodon_api/directory/mod.rs b/src/mastodon_api/directory/mod.rs index 38b4403..718ba5f 100644 --- a/src/mastodon_api/directory/mod.rs +++ b/src/mastodon_api/directory/mod.rs @@ -1 +1,2 @@ +mod types; pub mod views; diff --git a/src/mastodon_api/directory/types.rs b/src/mastodon_api/directory/types.rs new file mode 100644 index 0000000..88efd36 --- /dev/null +++ b/src/mastodon_api/directory/types.rs @@ -0,0 +1,13 @@ +use serde::Deserialize; + +fn default_page_size() -> i64 { 40 } + +/// https://docs.joinmastodon.org/methods/instance/directory/ +#[derive(Deserialize)] +pub struct DirectoryQueryParams { + #[serde(default)] + pub offset: i64, + + #[serde(default = "default_page_size")] + pub limit: i64, +} diff --git a/src/mastodon_api/directory/views.rs b/src/mastodon_api/directory/views.rs index 9f75f04..21cb29e 100644 --- a/src/mastodon_api/directory/views.rs +++ b/src/mastodon_api/directory/views.rs @@ -1,3 +1,4 @@ +/// https://docs.joinmastodon.org/methods/instance/directory/ use actix_web::{get, web, HttpResponse, Scope}; use actix_web_httpauth::extractors::bearer::BearerAuth; @@ -7,16 +8,23 @@ use crate::errors::HttpError; use crate::mastodon_api::accounts::types::Account; use crate::mastodon_api::oauth::auth::get_current_user; use crate::models::profiles::queries::get_profiles; +use super::types::DirectoryQueryParams; #[get("")] async fn profile_directory( auth: BearerAuth, config: web::Data, db_pool: web::Data, + query_params: web::Query, ) -> Result { let db_client = &**get_database_client(&db_pool).await?; get_current_user(db_client, auth.token()).await?; - let accounts: Vec = get_profiles(db_client).await? + let profiles = get_profiles( + db_client, + query_params.offset, + query_params.limit, + ).await?; + let accounts: Vec = profiles .into_iter() .map(|profile| Account::from_profile(profile, &config.instance_url())) .collect(); diff --git a/src/models/profiles/queries.rs b/src/models/profiles/queries.rs index b3203ec..34dfb19 100644 --- a/src/models/profiles/queries.rs +++ b/src/models/profiles/queries.rs @@ -144,14 +144,17 @@ pub async fn get_profile_by_acct( pub async fn get_profiles( db_client: &impl GenericClient, + offset: i64, + limit: i64, ) -> Result, DatabaseError> { let rows = db_client.query( " SELECT actor_profile FROM actor_profile ORDER BY username + LIMIT $1 OFFSET $2 ", - &[], + &[&limit, &offset], ).await?; let profiles = rows.iter() .map(|row| row.try_get("actor_profile"))