diff --git a/migrations/20260422183446_posts.sql b/migrations/20260422183446_posts.sql index 6f03e1f..f4434ba 100644 --- a/migrations/20260422183446_posts.sql +++ b/migrations/20260422183446_posts.sql @@ -5,5 +5,6 @@ CREATE TABLE IF NOT EXISTS posts created TIMESTAMP NOT NULL, indexed TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, author TEXT NOT NULL, - rkey TEXT NOT NULL + rkey TEXT NOT NULL, + cid TEXT NOT NULL ); diff --git a/migrations/20260423190103_reposts.sql b/migrations/20260423190103_reposts.sql index d535dce..b5ee2a9 100644 --- a/migrations/20260423190103_reposts.sql +++ b/migrations/20260423190103_reposts.sql @@ -6,5 +6,6 @@ CREATE TABLE IF NOT EXISTS reposts indexed TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, author TEXT NOT NULL, rkey TEXT NOT NULL, - subject TEXT NOT NULL + subject TEXT NOT NULL, + cid TEXT NOT NULL ); diff --git a/readme.md b/readme.md index 1cac005..a6ff39e 100644 --- a/readme.md +++ b/readme.md @@ -24,10 +24,12 @@ It is not (at the moment) supposed to be a complex appview, just a way for a use - [x] For each user call the `/repos/add` endpoint on tap to add the follow to be tracked - [x] Call `/repos/add` for the user of the appview - [ ] - Handle the events for tracked users - - [ ] Ignore anything other than the post lexicon types for the follows (work out what lexicon types need to be used for the user using the appview) + - [x] Ignore anything other than the post lexicon types for the follows (work out what lexicon types need to be used for the user using the appview) - [ ] Ignore if older than x amount of days (configurable number of days) - appview doesn't really need full history, only fairly recent and live - - [ ] Store and index the data in sqlite (schema TBD) - - [ ] MAYBE..... If the post is part of a reply, quote etc, maybe all relevant posts should be fetched too? Not sure how that will look yet, but that will be needed to render the posts in the app correctly I think. + - [x] Store and index the data in sqlite (schema TBD) + - [x] If it's a repost, store the subject too + - [ ] If it's a reply store the parent and root + - [ ] If it's a quote store the post that's quoted - [ ] - Start to implement the endpoints required to make this an appview (looking at a [similar project konbini](https://tangled.org/why.bsky.team/konbini/) by [@why.bsky.team](https://bsky.app/profile/why.bsky.team)) - [x] `GET /.well-known/did.json` - [ ] `GET /xrpc/com.atproto.identity.resolveHandle` diff --git a/src/tap.rs b/src/tap.rs index d02fe8a..55d0dbb 100644 --- a/src/tap.rs +++ b/src/tap.rs @@ -118,11 +118,16 @@ async fn handle_user_follow_event(record: &RecordEvent, pool: &sqlx::SqlitePool) async fn handle_post_event(record: &RecordEvent, pool: &sqlx::SqlitePool) { match record.action { RecordAction::Create => { + let cid: String = match record.cid.clone() { + Some(x) => x.to_string(), + None => "".to_string(), + }; let mut post = PostRecord { created: Utc::now(), indexed: Utc::now(), author: record.did.clone().to_string(), rkey: record.rkey.to_string(), + cid: cid, }; let tap_post: TapPost = record.parse_record().unwrap(); // TODO: better error handling here @@ -150,13 +155,17 @@ async fn handle_repost_event(record: &RecordEvent, pool: &sqlx::SqlitePool) { match record.action { RecordAction::Create => { let tap_post: TapRepost = record.parse_record().unwrap(); // TODO: better error handling here - + let cid: String = match record.cid.clone() { + Some(x) => x.to_string(), + None => "".to_string(), + }; let mut repost = RepostRecord { created: Utc::now(), indexed: Utc::now(), author: record.did.clone().to_string(), rkey: record.rkey.to_string(), subject: tap_post.subject.uri, + cid: cid, }; let created_at = DateTime::parse_from_rfc3339(&tap_post.created_at); @@ -224,6 +233,7 @@ struct PostRecord { indexed: chrono::DateTime, author: String, rkey: String, + cid: String, // TODO: other fields like reply to etc } @@ -234,18 +244,21 @@ struct RepostRecord { author: String, rkey: String, subject: String, + cid: String, // TODO: other fields like reply to etc } async fn insert_post(post: PostRecord, pool: &sqlx::SqlitePool) { - let result = - sqlx::query("INSERT INTO posts (created, indexed, author, rkey) VALUES ($1, $2, $3, $4)") - .bind(post.created) - .bind(post.indexed) - .bind(post.author) - .bind(post.rkey) - .execute(pool) - .await; + let result = sqlx::query( + "INSERT INTO posts (created, indexed, author, rkey, cid) VALUES ($1, $2, $3, $4, $5)", + ) + .bind(post.created) + .bind(post.indexed) + .bind(post.author) + .bind(post.rkey) + .bind(post.cid) + .execute(pool) + .await; if result.is_err() { println!("Error inserting post into the database: {result:?}"); @@ -254,13 +267,14 @@ async fn insert_post(post: PostRecord, pool: &sqlx::SqlitePool) { async fn insert_repost(repost: RepostRecord, pool: &sqlx::SqlitePool) { let result = sqlx::query( - "INSERT INTO reposts (created, indexed, author, rkey, subject) VALUES ($1, $2, $3, $4, $5)", + "INSERT INTO reposts (created, indexed, author, rkey, subject, cid) VALUES ($1, $2, $3, $4, $5, $6)", ) .bind(repost.created) .bind(repost.indexed) .bind(repost.author) .bind(repost.rkey) .bind(repost.subject) + .bind(repost.cid) .execute(pool) .await;