Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add user id model
Browse files Browse the repository at this point in the history
SHAcollision committed Aug 27, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 61202a4 commit 631f51b
Showing 7 changed files with 68 additions and 28 deletions.
2 changes: 1 addition & 1 deletion pubky
Submodule pubky updated from a5dfff to 9131ce
2 changes: 1 addition & 1 deletion src/db/graph/queries/write.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ pub fn create_user(user: &UserDetails) -> Query {
"MERGE (u:User {id: $id})
SET u.name = $name, u.bio = $bio, u.status = $status, u.links = $links, u.indexed_at = $indexed_at;",
)
.param("id", user.id.to_string())
.param("id", user.id.as_ref())
.param("name", user.name.to_string())
.param("bio", user.bio.as_ref().unwrap_or(&"null".to_string()).to_string())
.param("status", user.status.as_ref().unwrap_or(&"null".to_string()).to_string())
40 changes: 22 additions & 18 deletions src/events/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::models::{
homeserver::HomeserverUser,
traits::Collection,
user::{UserCounts, UserDetails},
user::{UserCounts, UserDetails, UserId},
};
use log::{debug, error, info};
use pubky::PubkyClient;
@@ -81,20 +81,29 @@ impl Event {
})
}

fn get_user_id(&self) -> Option<String> {
// Extract the part of the URI between "pubky://" and "/pub/". That's the user_id.
fn get_user_id(&self) -> Result<UserId, Box<dyn std::error::Error + Send + Sync>> {
// Define the patterns we are looking for in the URI
let pattern = "pubky://";
let pub_segment = "/pub/";

if let Some(start) = self.uri.path.find(pattern) {
let start_idx = start + pattern.len();
if let Some(end_idx) = self.uri.path[start_idx..].find(pub_segment) {
let user_id = self.uri.path[start_idx..start_idx + end_idx].to_string();
return Some(user_id);
}
}
// Find the starting position of the user_id part in the URI
let start_idx = self
.uri
.path
.find(pattern)
.map(|start| start + pattern.len())
.ok_or("Pattern not found in URI")?;

// Find the ending position of the user_id part
let end_idx = self.uri.path[start_idx..]
.find(pub_segment)
.ok_or("Pub segment not found in URI")?;

None
// Extract the user_id and attempt to convert it into a UserId
let user_id_str = &self.uri.path[start_idx..start_idx + end_idx];
let user_id = UserId::try_from(user_id_str)?;

Ok(user_id)
}

async fn handle(&self) -> Result<(), Box<dyn std::error::Error + Sync + Send>> {
@@ -128,13 +137,8 @@ impl Event {
let user = HomeserverUser::try_from(&blob).await?;

// Create UserDetails object
let user_details = match self.get_user_id() {
Some(user_id) => UserDetails::from_homeserver(&user_id, user).await?,
None => {
error!("Error getting user_id from event uri. Skipping event.");
return Ok(());
}
};
let user_id = self.get_user_id()?;
let user_details = UserDetails::from_homeserver(user_id, user).await?;

// Index new user event into the Graph and Index
user_details.save().await?;
12 changes: 5 additions & 7 deletions src/models/user/details.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::id::UserId;
use super::UserSearch;
use crate::db::graph::exec::exec_single_row;
use crate::models::homeserver::{HomeserverUser, UserLink};
@@ -6,7 +7,6 @@ use crate::{queries, RedisOps};
use axum::async_trait;
use chrono::Utc;
use neo4rs::Query;
use pkarr::PublicKey;
use serde::{Deserialize, Deserializer, Serialize};
use serde_json;
use utoipa::ToSchema;
@@ -39,7 +39,7 @@ impl Collection for UserDetails {
pub struct UserDetails {
pub name: String,
pub bio: Option<String>,
pub id: String,
pub id: UserId,
#[serde(deserialize_with = "deserialize_user_links")]
pub links: Option<Vec<UserLink>>,
pub status: Option<String>,
@@ -66,17 +66,15 @@ impl UserDetails {
}

pub async fn from_homeserver(
user_id: &str,
user_id: UserId,
homeserver_user: HomeserverUser,
) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
// Validate user_id is a valid pkarr public key
PublicKey::try_from(user_id)?;
Ok(UserDetails {
name: homeserver_user.name,
bio: homeserver_user.bio,
status: homeserver_user.status,
links: homeserver_user.links,
id: user_id.to_string(),
id: user_id,
indexed_at: Utc::now().timestamp_millis(),
})
}
@@ -162,7 +160,7 @@ mod tests {

for (i, details) in user_details.iter().enumerate() {
if let Some(details) = details {
assert_eq!(details.id, USER_IDS[i]);
assert_eq!(details.id.as_ref(), USER_IDS[i]);
}
}
}
36 changes: 36 additions & 0 deletions src/models/user/id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use pkarr::PublicKey;
use serde::{Deserialize, Serialize};
use std::fmt;
use utoipa::ToSchema;

/// Represents user data with name, bio, image, links, and status.
#[derive(Serialize, Deserialize, ToSchema, Default, Clone, Debug)]
pub struct UserId(pub String);

impl UserId {
pub fn try_from(str: &str) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
// Validate string is a valid Pkarr public key
PublicKey::try_from(str)?;
Ok(UserId(str.to_string()))
}
}

impl fmt::Display for UserId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}

impl std::ops::Deref for UserId {
type Target = String;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl AsRef<str> for UserId {
fn as_ref(&self) -> &str {
&self.0
}
}
2 changes: 2 additions & 0 deletions src/models/user/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod counts;
mod details;
mod follows;
mod id;
mod relationship;
mod search;
mod stream;
@@ -10,6 +11,7 @@ mod view;
pub use counts::UserCounts;
pub use details::UserDetails;
pub use follows::{Followers, Following, Friends, UserFollows};
pub use id::UserId;
pub use relationship::Relationship;
pub use search::UserSearch;
pub use stream::{UserStream, UserStreamType};
2 changes: 1 addition & 1 deletion src/models/user/search.rs
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ impl UserSearch {
let score = details.indexed_at as f64;

// The value in the sorted set will be `username:user_id`
let member = format!("{}:{}", username, user_id);
let member = format!("{}:{}", username, user_id.0);

items.push((score, member));
}

0 comments on commit 631f51b

Please sign in to comment.