Add API method for getting local timeline
This commit is contained in:
parent
da6ceadd51
commit
1ea55b5d1a
3 changed files with 99 additions and 1 deletions
|
@ -555,6 +555,34 @@ paths:
|
||||||
description: Post not found
|
description: Post not found
|
||||||
422:
|
422:
|
||||||
description: Transaction already registered
|
description: Transaction already registered
|
||||||
|
/api/v1/timelines/public:
|
||||||
|
get:
|
||||||
|
summary: View local public posts.
|
||||||
|
parameters:
|
||||||
|
- name: max_id
|
||||||
|
in: query
|
||||||
|
description: Return results older than this ID.
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
- name: limit
|
||||||
|
in: query
|
||||||
|
description: Maximum number of results to return.
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
default: 20
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
description: Post list
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Status'
|
||||||
/api/v1/timelines/tag/{hashtag}:
|
/api/v1/timelines/tag/{hashtag}:
|
||||||
get:
|
get:
|
||||||
summary: View public posts containing the given hashtag
|
summary: View public posts containing the given hashtag
|
||||||
|
|
|
@ -7,7 +7,11 @@ use crate::database::{Pool, get_database_client};
|
||||||
use crate::errors::HttpError;
|
use crate::errors::HttpError;
|
||||||
use crate::mastodon_api::oauth::auth::get_current_user;
|
use crate::mastodon_api::oauth::auth::get_current_user;
|
||||||
use crate::mastodon_api::statuses::helpers::build_status_list;
|
use crate::mastodon_api::statuses::helpers::build_status_list;
|
||||||
use crate::models::posts::queries::{get_home_timeline, get_posts_by_tag};
|
use crate::models::posts::queries::{
|
||||||
|
get_home_timeline,
|
||||||
|
get_local_timeline,
|
||||||
|
get_posts_by_tag,
|
||||||
|
};
|
||||||
use super::types::TimelineQueryParams;
|
use super::types::TimelineQueryParams;
|
||||||
|
|
||||||
#[get("/home")]
|
#[get("/home")]
|
||||||
|
@ -34,6 +38,31 @@ async fn home_timeline(
|
||||||
Ok(HttpResponse::Ok().json(statuses))
|
Ok(HttpResponse::Ok().json(statuses))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Local timeline ("local" parameter is ignored)
|
||||||
|
#[get("/public")]
|
||||||
|
async fn public_timeline(
|
||||||
|
auth: BearerAuth,
|
||||||
|
config: web::Data<Config>,
|
||||||
|
db_pool: web::Data<Pool>,
|
||||||
|
query_params: web::Query<TimelineQueryParams>,
|
||||||
|
) -> Result<HttpResponse, HttpError> {
|
||||||
|
let db_client = &**get_database_client(&db_pool).await?;
|
||||||
|
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||||
|
let posts = get_local_timeline(
|
||||||
|
db_client,
|
||||||
|
¤t_user.id,
|
||||||
|
query_params.max_id,
|
||||||
|
query_params.limit,
|
||||||
|
).await?;
|
||||||
|
let statuses = build_status_list(
|
||||||
|
db_client,
|
||||||
|
&config.instance_url(),
|
||||||
|
Some(¤t_user),
|
||||||
|
posts,
|
||||||
|
).await?;
|
||||||
|
Ok(HttpResponse::Ok().json(statuses))
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/tag/{hashtag}")]
|
#[get("/tag/{hashtag}")]
|
||||||
async fn hashtag_timeline(
|
async fn hashtag_timeline(
|
||||||
auth: Option<BearerAuth>,
|
auth: Option<BearerAuth>,
|
||||||
|
@ -66,5 +95,6 @@ async fn hashtag_timeline(
|
||||||
pub fn timeline_api_scope() -> Scope {
|
pub fn timeline_api_scope() -> Scope {
|
||||||
web::scope("/api/v1/timelines")
|
web::scope("/api/v1/timelines")
|
||||||
.service(home_timeline)
|
.service(home_timeline)
|
||||||
|
.service(public_timeline)
|
||||||
.service(hashtag_timeline)
|
.service(hashtag_timeline)
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,6 +344,46 @@ pub async fn get_home_timeline(
|
||||||
Ok(posts)
|
Ok(posts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_local_timeline(
|
||||||
|
db_client: &impl GenericClient,
|
||||||
|
current_user_id: &Uuid,
|
||||||
|
max_post_id: Option<Uuid>,
|
||||||
|
limit: i64,
|
||||||
|
) -> Result<Vec<Post>, DatabaseError> {
|
||||||
|
let statement = format!(
|
||||||
|
"
|
||||||
|
SELECT
|
||||||
|
post, actor_profile,
|
||||||
|
{related_attachments},
|
||||||
|
{related_mentions},
|
||||||
|
{related_tags}
|
||||||
|
FROM post
|
||||||
|
JOIN actor_profile ON post.author_id = actor_profile.id
|
||||||
|
WHERE
|
||||||
|
actor_profile.actor_json IS NULL
|
||||||
|
AND {visibility_filter}
|
||||||
|
AND ($max_post_id::uuid IS NULL OR post.id < $max_post_id)
|
||||||
|
ORDER BY post.id DESC
|
||||||
|
LIMIT $limit
|
||||||
|
",
|
||||||
|
related_attachments=RELATED_ATTACHMENTS,
|
||||||
|
related_mentions=RELATED_MENTIONS,
|
||||||
|
related_tags=RELATED_TAGS,
|
||||||
|
visibility_filter=build_visibility_filter(),
|
||||||
|
);
|
||||||
|
let query = query!(
|
||||||
|
&statement,
|
||||||
|
current_user_id=current_user_id,
|
||||||
|
max_post_id=max_post_id,
|
||||||
|
limit=limit,
|
||||||
|
)?;
|
||||||
|
let rows = db_client.query(query.sql(), query.parameters()).await?;
|
||||||
|
let posts: Vec<Post> = rows.iter()
|
||||||
|
.map(Post::try_from)
|
||||||
|
.collect::<Result<_, _>>()?;
|
||||||
|
Ok(posts)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_posts(
|
pub async fn get_posts(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
posts_ids: Vec<Uuid>,
|
posts_ids: Vec<Uuid>,
|
||||||
|
|
Loading…
Reference in a new issue