Enable profile directory pagination

This commit is contained in:
silverpill 2021-12-16 23:00:52 +00:00
parent 3989a40825
commit a07f118159
6 changed files with 71 additions and 2 deletions

View file

@ -94,6 +94,7 @@ The following activities are supported:
- Like(Note) - Like(Note)
- Undo(Like) - Undo(Like)
- Announce(Note) - Announce(Note)
- Undo(Announce)
- Follow(Person) - Follow(Person)
- Update(Person) - Update(Person)

View file

@ -5,6 +5,34 @@ info:
version: 1.0.0 version: 1.0.0
paths: 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: /api/v1/accounts/{account_id}/statuses:
get: get:
summary: Statuses posted to the given account. summary: Statuses posted to the given account.
@ -178,6 +206,21 @@ components:
type: string type: string
format: uuid format: uuid
schemas: 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: Status:
type: object type: object
properties: properties:

View file

@ -1 +1,2 @@
mod types;
pub mod views; pub mod views;

View file

@ -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,
}

View file

@ -1,3 +1,4 @@
/// https://docs.joinmastodon.org/methods/instance/directory/
use actix_web::{get, web, HttpResponse, Scope}; use actix_web::{get, web, HttpResponse, Scope};
use actix_web_httpauth::extractors::bearer::BearerAuth; 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::accounts::types::Account;
use crate::mastodon_api::oauth::auth::get_current_user; use crate::mastodon_api::oauth::auth::get_current_user;
use crate::models::profiles::queries::get_profiles; use crate::models::profiles::queries::get_profiles;
use super::types::DirectoryQueryParams;
#[get("")] #[get("")]
async fn profile_directory( async fn profile_directory(
auth: BearerAuth, auth: BearerAuth,
config: web::Data<Config>, config: web::Data<Config>,
db_pool: web::Data<Pool>, db_pool: web::Data<Pool>,
query_params: web::Query<DirectoryQueryParams>,
) -> Result<HttpResponse, HttpError> { ) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?; let db_client = &**get_database_client(&db_pool).await?;
get_current_user(db_client, auth.token()).await?; get_current_user(db_client, auth.token()).await?;
let accounts: Vec<Account> = get_profiles(db_client).await? let profiles = get_profiles(
db_client,
query_params.offset,
query_params.limit,
).await?;
let accounts: Vec<Account> = profiles
.into_iter() .into_iter()
.map(|profile| Account::from_profile(profile, &config.instance_url())) .map(|profile| Account::from_profile(profile, &config.instance_url()))
.collect(); .collect();

View file

@ -144,14 +144,17 @@ pub async fn get_profile_by_acct(
pub async fn get_profiles( pub async fn get_profiles(
db_client: &impl GenericClient, db_client: &impl GenericClient,
offset: i64,
limit: i64,
) -> Result<Vec<DbActorProfile>, DatabaseError> { ) -> Result<Vec<DbActorProfile>, DatabaseError> {
let rows = db_client.query( let rows = db_client.query(
" "
SELECT actor_profile SELECT actor_profile
FROM actor_profile FROM actor_profile
ORDER BY username ORDER BY username
LIMIT $1 OFFSET $2
", ",
&[], &[&limit, &offset],
).await?; ).await?;
let profiles = rows.iter() let profiles = rows.iter()
.map(|row| row.try_get("actor_profile")) .map(|row| row.try_get("actor_profile"))