feat: start on CRUD ops for new types

This commit is contained in:
nullishamy 2025-04-28 23:21:59 +01:00
parent d252131e0d
commit e6b654a0b3
Signed by: amy
SSH key fingerprint: SHA256:WmV0uk6WgAQvDJlM8Ld4mFPHZo02CLXXP5VkwQ5xtyk
6 changed files with 149 additions and 32 deletions

View file

@ -51,7 +51,8 @@ pub async fn home(
display_name: String,
username: String
}
// FIXME: query! can't cope with this. returns a type error
let posts = sqlx::query_as::<_, Post>(
r#"
WITH RECURSIVE get_home_timeline_with_boosts(
@ -84,8 +85,6 @@ pub async fn home(
.await
.unwrap();
dbg!(&posts);
let mut out = Vec::<TimelineStatus>::new();
for record in posts.iter() {
let mut boost: Option<Box<TimelineStatus>> = None;

View file

@ -89,11 +89,11 @@ pub async fn test(
outbound: &State<OutboundQueue>,
mut db: Connection<Db>
) -> &'static str {
use main::types_rewrite::{ObjectUuid, fetch, api};
use main::types_rewrite::{ObjectUuid, get, api};
outbound.0.send(ap::QueueMessage::Heartbeat);
let id = ObjectUuid("9b9d497b-2731-435f-a929-e609ca69dac9".to_string());
let user= dbg!(fetch::user_by_id(id, &mut **db).await.unwrap());
let user= dbg!(get::user_by_id(id, &mut **db).await.unwrap());
let apu: api::Account = user.into();
dbg!(apu);

View file

@ -4,12 +4,15 @@ use main::ap;
use rocket::serde::json::serde_json;
use rocket::{State, post};
use rocket_db_pools::Connection;
use sqlx::SqliteConnection;
use sqlx::Sqlite;
use url::Url;
use uuid::Uuid;
use tracing::{event, span, Level, debug, warn, info, error};
use crate::http_wrapper::HttpWrapper;
use main::types_rewrite::{make, db, ObjectUuid, ObjectUri, self};
use crate::{
Db,
http::HttpClient,
@ -103,22 +106,92 @@ async fn create_follow(
.unwrap();
}
struct RemoteInfo {
acct: String,
web_url: String,
is_remote: bool,
}
fn get_remote_info(actor_url: &str, person: &Person) -> RemoteInfo {
let url = Url::parse(&actor_url).unwrap();
let host = url.host_str().unwrap();
let (acct, remote) = if host != "ferri.amy.mov" {
(format!("{}@{}", person.preferred_username, host), true)
} else {
(person.preferred_username.clone(), false)
};
let url = format!("https://ferri.amy.mov/{}", acct);
RemoteInfo {
acct: acct.to_string(),
web_url: url,
is_remote: remote
}
}
async fn resolve_actor<'a>(
actor_url: &str,
http: &HttpWrapper<'a>,
conn: &mut SqliteConnection
) -> Result<db::User, types_rewrite::DbError> {
let person = {
let res = http.get_person(&actor_url).await;
if let Err(e) = res {
error!("could not load user {}: {}", actor_url, e.to_string());
return Err(types_rewrite::DbError::FetchError(
format!("could not load user {}: {}", actor_url, e.to_string())
))
}
res.unwrap()
};
let user_id = ObjectUuid::new();
let remote_info = get_remote_info(actor_url, &person);
let actor = db::Actor {
id: ObjectUri(actor_url.to_string()),
inbox: person.inbox.clone(),
outbox: person.outbox.clone(),
};
info!("creating actor {}", actor_url);
let actor = make::new_actor(actor.clone(), conn).await.unwrap_or(actor);
info!("creating user {} ({:#?})", remote_info.acct, person);
let user = db::User {
id: user_id,
actor,
username: person.name,
display_name: person.preferred_username,
acct: remote_info.acct,
remote: remote_info.is_remote,
url: remote_info.web_url,
created_at: main::ap::now(),
posts: db::UserPosts {
last_post_at: None
}
};
Ok(make::new_user(user.clone(), conn).await.unwrap_or(user))
}
async fn handle_follow_activity<'a>(
followed_account: &str,
activity: activity::FollowActivity,
http: HttpWrapper<'a>,
mut db: Connection<Db>,
) {
let user = http.get_person(&activity.actor).await;
if let Err(e) = user {
error!("could not load user {}: {}", activity.actor, e.to_string());
return
}
let user = user.unwrap();
let actor = resolve_actor(&activity.actor, &http, &mut **db)
.await.unwrap();
create_actor(&user, &activity.actor, &mut **db).await;
create_user(&user, &activity.actor, &mut **db).await;
info!("{:?} follows {}", actor, followed_account);
create_follow(&activity, &mut **db).await;
let follower = ap::User::from_actor_id(&activity.actor, &mut **db).await;
@ -226,15 +299,18 @@ async fn handle_boost_activity<'a>(
let reblog_id = ap::new_id();
let attr_id = attributed_user.id();
// HACK: ON CONFLICT is to avoid duplicate remote posts coming in
// check this better in future
sqlx::query!("
INSERT INTO post (id, uri, user_id, content, created_at)
VALUES (?1, ?2, ?3, ?4, ?5)
ON CONFLICT(uri) DO NOTHING
", reblog_id, post.id, attr_id, post.content, post.ts)
.execute(&mut **db)
.await
.unwrap();
let uri = format!("https://ferri.amy.mov/users/{}/posts/{}", actor_user.id(), post.id);
let uri = format!("https://ferri.amy.mov/users/{}/posts/{}", actor_user.id(), base_id);
let user_id = actor_user.id();
sqlx::query!("