mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-19 19:46:50 +00:00
GLOBALS.people replaced with a People Manager object that keeps memory and database in sync. [plus a lot of dead code commented out]
This commit is contained in:
parent
59abfdd15b
commit
8a7e35ac9b
@ -1,7 +1,4 @@
|
|||||||
use crate::error::Error;
|
|
||||||
use crate::globals::GLOBALS;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::task::spawn_blocking;
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct DbContact {
|
pub struct DbContact {
|
||||||
@ -12,7 +9,7 @@ pub struct DbContact {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DbContact {
|
impl DbContact {
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbContact>, Error> {
|
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbContact>, Error> {
|
||||||
let sql = "SELECT source, contact, relay, petname FROM contact".to_owned();
|
let sql = "SELECT source, contact, relay, petname FROM contact".to_owned();
|
||||||
let sql = match criteria {
|
let sql = match criteria {
|
||||||
@ -44,8 +41,9 @@ impl DbContact {
|
|||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn insert(contact: DbContact) -> Result<(), Error> {
|
pub async fn insert(contact: DbContact) -> Result<(), Error> {
|
||||||
let sql = "INSERT OR IGNORE INTO contact (source, contact, relay, petname) \
|
let sql = "INSERT OR IGNORE INTO contact (source, contact, relay, petname) \
|
||||||
VALUES (?1, ?2, ?3, ?4)";
|
VALUES (?1, ?2, ?3, ?4)";
|
||||||
@ -67,8 +65,9 @@ impl DbContact {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
||||||
let sql = format!("DELETE FROM contact WHERE {}", criteria);
|
let sql = format!("DELETE FROM contact WHERE {}", criteria);
|
||||||
|
|
||||||
@ -82,4 +81,5 @@ impl DbContact {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ impl DbEvent {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
||||||
let sql = format!("DELETE FROM event WHERE {}", criteria);
|
let sql = format!("DELETE FROM event WHERE {}", criteria);
|
||||||
|
|
||||||
@ -162,8 +162,9 @@ impl DbEvent {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn get_author(id: IdHex) -> Result<Option<PublicKeyHex>, Error> {
|
pub async fn get_author(id: IdHex) -> Result<Option<PublicKeyHex>, Error> {
|
||||||
let sql = "SELECT pubkey FROM event WHERE id=?";
|
let sql = "SELECT pubkey FROM event WHERE id=?";
|
||||||
|
|
||||||
@ -179,6 +180,7 @@ impl DbEvent {
|
|||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn repeat_vars(count: usize) -> String {
|
fn repeat_vars(count: usize) -> String {
|
||||||
|
@ -25,7 +25,7 @@ impl DbEventHashtag {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn get_events_with_hashtag(hashtag: String) -> Result<Vec<DbEventHashtag>, Error> {
|
pub async fn get_events_with_hashtag(hashtag: String) -> Result<Vec<DbEventHashtag>, Error> {
|
||||||
let sql = "SELECT event FROM event_hashtag WHERE hashtag=?";
|
let sql = "SELECT event FROM event_hashtag WHERE hashtag=?";
|
||||||
let output: Result<Vec<DbEventHashtag>, Error> = spawn_blocking(move || {
|
let output: Result<Vec<DbEventHashtag>, Error> = spawn_blocking(move || {
|
||||||
@ -47,4 +47,5 @@ impl DbEventHashtag {
|
|||||||
.await?;
|
.await?;
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::globals::GLOBALS;
|
use crate::globals::GLOBALS;
|
||||||
use nostr_types::Id;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::task::spawn_blocking;
|
use tokio::task::spawn_blocking;
|
||||||
|
|
||||||
@ -30,7 +29,7 @@ impl DbEventRelationship {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn get_events_referring_to(id: Id) -> Result<Vec<DbEventRelationship>, Error> {
|
pub async fn get_events_referring_to(id: Id) -> Result<Vec<DbEventRelationship>, Error> {
|
||||||
let sql =
|
let sql =
|
||||||
"SELECT referring, relationship, content FROM event_relationship WHERE original=?";
|
"SELECT referring, relationship, content FROM event_relationship WHERE original=?";
|
||||||
@ -55,4 +54,5 @@ impl DbEventRelationship {
|
|||||||
.await?;
|
.await?;
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ pub struct DbEventSeen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DbEventSeen {
|
impl DbEventSeen {
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbEventSeen>, Error> {
|
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbEventSeen>, Error> {
|
||||||
let sql = "SELECT event, relay, when_seen FROM event_seen".to_owned();
|
let sql = "SELECT event, relay, when_seen FROM event_seen".to_owned();
|
||||||
let sql = match criteria {
|
let sql = match criteria {
|
||||||
@ -42,6 +42,7 @@ impl DbEventSeen {
|
|||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub async fn replace(event_seen: DbEventSeen) -> Result<(), Error> {
|
pub async fn replace(event_seen: DbEventSeen) -> Result<(), Error> {
|
||||||
let sql = "REPLACE INTO event_seen (event, relay, when_seen) \
|
let sql = "REPLACE INTO event_seen (event, relay, when_seen) \
|
||||||
@ -60,7 +61,7 @@ impl DbEventSeen {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
||||||
let sql = format!("DELETE FROM event_seen WHERE {}", criteria);
|
let sql = format!("DELETE FROM event_seen WHERE {}", criteria);
|
||||||
|
|
||||||
@ -74,4 +75,5 @@ impl DbEventSeen {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ pub struct DbEventTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DbEventTag {
|
impl DbEventTag {
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbEventTag>, Error> {
|
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbEventTag>, Error> {
|
||||||
let sql =
|
let sql =
|
||||||
"SELECT event, seq, label, field0, field1, field2, field3 FROM event_tag".to_owned();
|
"SELECT event, seq, label, field0, field1, field2, field3 FROM event_tag".to_owned();
|
||||||
@ -51,6 +51,7 @@ impl DbEventTag {
|
|||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub async fn insert(event_tag: DbEventTag) -> Result<(), Error> {
|
pub async fn insert(event_tag: DbEventTag) -> Result<(), Error> {
|
||||||
let sql =
|
let sql =
|
||||||
@ -78,7 +79,7 @@ impl DbEventTag {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
||||||
let sql = format!("DELETE FROM event_tag WHERE {}", criteria);
|
let sql = format!("DELETE FROM event_tag WHERE {}", criteria);
|
||||||
|
|
||||||
@ -92,4 +93,5 @@ impl DbEventTag {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::globals::GLOBALS;
|
use crate::globals::GLOBALS;
|
||||||
use nostr_types::{Metadata, PublicKeyHex, Unixtime};
|
use nostr_types::PublicKeyHex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::task::spawn_blocking;
|
use tokio::task::spawn_blocking;
|
||||||
|
|
||||||
@ -18,20 +18,6 @@ pub struct DbPerson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DbPerson {
|
impl DbPerson {
|
||||||
pub fn new(pubkey: PublicKeyHex) -> DbPerson {
|
|
||||||
DbPerson {
|
|
||||||
pubkey,
|
|
||||||
name: None,
|
|
||||||
about: None,
|
|
||||||
picture: None,
|
|
||||||
dns_id: None,
|
|
||||||
dns_id_valid: 0,
|
|
||||||
dns_id_last_checked: None,
|
|
||||||
metadata_at: None,
|
|
||||||
followed: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbPerson>, Error> {
|
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbPerson>, Error> {
|
||||||
let sql =
|
let sql =
|
||||||
"SELECT pubkey, name, about, picture, dns_id, dns_id_valid, dns_id_last_checked, metadata_at, followed FROM person".to_owned();
|
"SELECT pubkey, name, about, picture, dns_id, dns_id_valid, dns_id_last_checked, metadata_at, followed FROM person".to_owned();
|
||||||
@ -108,62 +94,6 @@ impl DbPerson {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(person: DbPerson) -> Result<(), Error> {
|
|
||||||
let sql =
|
|
||||||
"UPDATE person SET name=?, about=?, picture=?, dns_id=?, dns_id_valid=?, dns_id_last_checked=?, metadata_at=?, followed=? WHERE pubkey=?";
|
|
||||||
|
|
||||||
spawn_blocking(move || {
|
|
||||||
let maybe_db = GLOBALS.db.blocking_lock();
|
|
||||||
let db = maybe_db.as_ref().unwrap();
|
|
||||||
|
|
||||||
let mut stmt = db.prepare(sql)?;
|
|
||||||
stmt.execute((
|
|
||||||
&person.name,
|
|
||||||
&person.about,
|
|
||||||
&person.picture,
|
|
||||||
&person.dns_id,
|
|
||||||
&person.dns_id_valid,
|
|
||||||
&person.dns_id_last_checked,
|
|
||||||
&person.metadata_at,
|
|
||||||
&person.followed,
|
|
||||||
&person.pubkey.0,
|
|
||||||
))?;
|
|
||||||
Ok::<(), Error>(())
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update metadata without clobbering anything else
|
|
||||||
pub async fn update_metadata(
|
|
||||||
pubkey: PublicKeyHex,
|
|
||||||
metadata: Metadata,
|
|
||||||
created_at: Unixtime,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let sql =
|
|
||||||
"UPDATE person SET name=?, about=?, picture=?, dns_id=?, metadata_at=? WHERE pubkey=?";
|
|
||||||
|
|
||||||
spawn_blocking(move || {
|
|
||||||
let maybe_db = GLOBALS.db.blocking_lock();
|
|
||||||
let db = maybe_db.as_ref().unwrap();
|
|
||||||
|
|
||||||
let mut stmt = db.prepare(sql)?;
|
|
||||||
stmt.execute((
|
|
||||||
&metadata.name,
|
|
||||||
&metadata.about,
|
|
||||||
&metadata.picture,
|
|
||||||
&metadata.nip05,
|
|
||||||
&created_at.0,
|
|
||||||
&pubkey.0,
|
|
||||||
))?;
|
|
||||||
Ok::<(), Error>(())
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn upsert_valid_nip05(
|
pub async fn upsert_valid_nip05(
|
||||||
pubkey: PublicKeyHex,
|
pubkey: PublicKeyHex,
|
||||||
dns_id: String,
|
dns_id: String,
|
||||||
@ -209,7 +139,7 @@ impl DbPerson {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
||||||
let sql = format!("DELETE FROM person WHERE {}", criteria);
|
let sql = format!("DELETE FROM person WHERE {}", criteria);
|
||||||
|
|
||||||
@ -223,18 +153,5 @@ impl DbPerson {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
pub async fn populate_new_people() -> Result<(), Error> {
|
|
||||||
let sql = "INSERT or IGNORE INTO person (pubkey) SELECT DISTINCT pubkey FROM EVENT";
|
|
||||||
|
|
||||||
spawn_blocking(move || {
|
|
||||||
let maybe_db = GLOBALS.db.blocking_lock();
|
|
||||||
let db = maybe_db.as_ref().unwrap();
|
|
||||||
db.execute(sql, [])?;
|
|
||||||
Ok::<(), Error>(())
|
|
||||||
})
|
|
||||||
.await??;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ pub struct DbPersonRelay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DbPersonRelay {
|
impl DbPersonRelay {
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbPersonRelay>, Error> {
|
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbPersonRelay>, Error> {
|
||||||
let sql = "SELECT person, relay, last_fetched, last_suggested_kind2, last_suggested_kind3, last_suggested_nip23, last_suggested_nip35, last_suggested_bytag FROM person_relay".to_owned();
|
let sql = "SELECT person, relay, last_fetched, last_suggested_kind2, last_suggested_kind3, last_suggested_nip23, last_suggested_nip35, last_suggested_bytag FROM person_relay".to_owned();
|
||||||
let sql = match criteria {
|
let sql = match criteria {
|
||||||
@ -53,6 +53,7 @@ impl DbPersonRelay {
|
|||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/// Fetch records matching the given public keys, ordered from highest to lowest rank
|
/// Fetch records matching the given public keys, ordered from highest to lowest rank
|
||||||
pub async fn fetch_for_pubkeys(pubkeys: &[PublicKeyHex]) -> Result<Vec<DbPersonRelay>, Error> {
|
pub async fn fetch_for_pubkeys(pubkeys: &[PublicKeyHex]) -> Result<Vec<DbPersonRelay>, Error> {
|
||||||
@ -101,8 +102,8 @@ impl DbPersonRelay {
|
|||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/// Fetch oldest last_fetched among a set of public keys for a relay
|
/// Fetch oldest last_fetched among a set of public keys for a relay
|
||||||
#[allow(dead_code)]
|
|
||||||
pub async fn fetch_oldest_last_fetched(
|
pub async fn fetch_oldest_last_fetched(
|
||||||
pubkeys: &[PublicKeyHex],
|
pubkeys: &[PublicKeyHex],
|
||||||
relay: &str,
|
relay: &str,
|
||||||
@ -136,6 +137,7 @@ impl DbPersonRelay {
|
|||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub async fn insert(person_relay: DbPersonRelay) -> Result<(), Error> {
|
pub async fn insert(person_relay: DbPersonRelay) -> Result<(), Error> {
|
||||||
let sql = "INSERT OR IGNORE INTO person_relay (person, relay, last_fetched, \
|
let sql = "INSERT OR IGNORE INTO person_relay (person, relay, last_fetched, \
|
||||||
@ -241,7 +243,7 @@ impl DbPersonRelay {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
||||||
let sql = format!("DELETE FROM person_relay WHERE {}", criteria);
|
let sql = format!("DELETE FROM person_relay WHERE {}", criteria);
|
||||||
|
|
||||||
@ -255,6 +257,7 @@ impl DbPersonRelay {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn repeat_vars(count: usize) -> String {
|
fn repeat_vars(count: usize) -> String {
|
||||||
|
@ -167,7 +167,7 @@ impl DbRelay {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
pub async fn delete(criteria: &str) -> Result<(), Error> {
|
||||||
let sql = format!("DELETE FROM relay WHERE {}", criteria);
|
let sql = format!("DELETE FROM relay WHERE {}", criteria);
|
||||||
|
|
||||||
@ -181,6 +181,7 @@ impl DbRelay {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub async fn populate_new_relays() -> Result<(), Error> {
|
pub async fn populate_new_relays() -> Result<(), Error> {
|
||||||
// Get relays from person_relay list
|
// Get relays from person_relay list
|
||||||
|
@ -39,6 +39,9 @@ pub enum Error {
|
|||||||
#[error("I/O Error: {0}")]
|
#[error("I/O Error: {0}")]
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
|
|
||||||
|
#[error("INTERNAL: {0}")]
|
||||||
|
Internal(String),
|
||||||
|
|
||||||
#[error("Invalid DNS ID (nip-05 / nip-35), should be user@domain")]
|
#[error("Invalid DNS ID (nip-05 / nip-35), should be user@domain")]
|
||||||
InvalidDnsId,
|
InvalidDnsId,
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use crate::comms::BusMessage;
|
use crate::comms::BusMessage;
|
||||||
use crate::db::{DbEvent, DbPerson, DbPersonRelay, DbRelay};
|
use crate::db::{DbEvent, DbRelay};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::feed::Feed;
|
use crate::feed::Feed;
|
||||||
|
use crate::people::People;
|
||||||
use crate::relationship::Relationship;
|
use crate::relationship::Relationship;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
use crate::signer::Signer;
|
use crate::signer::Signer;
|
||||||
use nostr_types::{Event, Id, IdHex, PublicKey, PublicKeyHex, Unixtime, Url};
|
use nostr_types::{Event, Id, IdHex, Unixtime, Url};
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
@ -56,7 +57,8 @@ pub struct Globals {
|
|||||||
pub desired_events: RwLock<HashMap<Id, Vec<Url>>>,
|
pub desired_events: RwLock<HashMap<Id, Vec<Url>>>,
|
||||||
|
|
||||||
/// All nostr people records currently loaded into memory, keyed by pubkey
|
/// All nostr people records currently loaded into memory, keyed by pubkey
|
||||||
pub people: RwLock<HashMap<PublicKey, DbPerson>>,
|
//pub people: RwLock<HashMap<PublicKey, DbPerson>>,
|
||||||
|
pub people: RwLock<People>,
|
||||||
|
|
||||||
/// All nostr relay records we have
|
/// All nostr relay records we have
|
||||||
pub relays: RwLock<HashMap<Url, DbRelay>>,
|
pub relays: RwLock<HashMap<Url, DbRelay>>,
|
||||||
@ -105,7 +107,7 @@ lazy_static! {
|
|||||||
relationships: RwLock::new(HashMap::new()),
|
relationships: RwLock::new(HashMap::new()),
|
||||||
last_reply: RwLock::new(HashMap::new()),
|
last_reply: RwLock::new(HashMap::new()),
|
||||||
desired_events: RwLock::new(HashMap::new()),
|
desired_events: RwLock::new(HashMap::new()),
|
||||||
people: RwLock::new(HashMap::new()),
|
people: RwLock::new(People::new()),
|
||||||
relays: RwLock::new(HashMap::new()),
|
relays: RwLock::new(HashMap::new()),
|
||||||
shutting_down: AtomicBool::new(false),
|
shutting_down: AtomicBool::new(false),
|
||||||
settings: RwLock::new(Settings::default()),
|
settings: RwLock::new(Settings::default()),
|
||||||
@ -202,7 +204,7 @@ impl Globals {
|
|||||||
Ok((output, orphans))
|
Ok((output, orphans))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub async fn get_desired_events_for_url(url: Url) -> Result<Vec<Id>, Error> {
|
pub async fn get_desired_events_for_url(url: Url) -> Result<Vec<Id>, Error> {
|
||||||
Globals::get_desired_events_prelude().await?;
|
Globals::get_desired_events_prelude().await?;
|
||||||
|
|
||||||
@ -216,6 +218,7 @@ impl Globals {
|
|||||||
|
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub async fn add_relationship(id: Id, related: Id, relationship: Relationship) {
|
pub async fn add_relationship(id: Id, related: Id, relationship: Relationship) {
|
||||||
let r = (related, relationship);
|
let r = (related, relationship);
|
||||||
@ -283,68 +286,3 @@ impl Globals {
|
|||||||
v
|
v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn followed_pubkeys() -> Vec<PublicKeyHex> {
|
|
||||||
let people = GLOBALS.people.read().await;
|
|
||||||
people
|
|
||||||
.iter()
|
|
||||||
.map(|(_, p)| p)
|
|
||||||
.filter(|p| p.followed == 1)
|
|
||||||
.map(|p| p.pubkey.clone())
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub async fn follow_key_and_relay(pubkey: String, relay: String) -> Result<DbPerson, String> {
|
|
||||||
let pubkeyhex = PublicKeyHex(pubkey.clone());
|
|
||||||
|
|
||||||
// Validate the url
|
|
||||||
let u = Url::new(&relay);
|
|
||||||
if !u.is_valid() {
|
|
||||||
return Err(format!("Invalid url: {}", relay));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create or update them
|
|
||||||
let person = match DbPerson::fetch_one(pubkeyhex.clone())
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("{}", e))?
|
|
||||||
{
|
|
||||||
Some(mut person) => {
|
|
||||||
person.followed = 1;
|
|
||||||
DbPerson::update(person.clone())
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("{}", e))?;
|
|
||||||
person
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let mut person = DbPerson::new(pubkeyhex.clone());
|
|
||||||
person.followed = 1;
|
|
||||||
DbPerson::insert(person.clone())
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("{}", e))?;
|
|
||||||
person
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Insert (or ignore) this relay
|
|
||||||
let dbrelay = DbRelay::new(relay.clone()).map_err(|e| format!("{}", e))?;
|
|
||||||
DbRelay::insert(dbrelay)
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("{}", e))?;
|
|
||||||
|
|
||||||
// Insert (or ignore) this person's relay
|
|
||||||
DbPersonRelay::insert(DbPersonRelay {
|
|
||||||
person: pubkey,
|
|
||||||
relay,
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("{}", e))?;
|
|
||||||
|
|
||||||
// Tell the overlord to update the minion to watch for their events
|
|
||||||
// possibly starting a new minion if necessary.
|
|
||||||
// FIXME TODO
|
|
||||||
|
|
||||||
// Reply to javascript with the person which will be set in the store
|
|
||||||
Ok(person)
|
|
||||||
}
|
|
||||||
|
@ -11,6 +11,7 @@ mod error;
|
|||||||
mod feed;
|
mod feed;
|
||||||
mod globals;
|
mod globals;
|
||||||
mod overlord;
|
mod overlord;
|
||||||
|
mod people;
|
||||||
mod process;
|
mod process;
|
||||||
mod relationship;
|
mod relationship;
|
||||||
mod settings;
|
mod settings;
|
||||||
|
@ -30,7 +30,6 @@ pub struct Minion {
|
|||||||
stream: Option<SplitStream<WebSocketStream<MaybeTlsStream<TcpStream>>>>,
|
stream: Option<SplitStream<WebSocketStream<MaybeTlsStream<TcpStream>>>>,
|
||||||
sink: Option<SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, WsMessage>>,
|
sink: Option<SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, WsMessage>>,
|
||||||
subscriptions: Subscriptions,
|
subscriptions: Subscriptions,
|
||||||
#[allow(dead_code)]
|
|
||||||
next_events_subscription_id: u32,
|
next_events_subscription_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +355,6 @@ impl Minion {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
async fn get_events(&mut self, ids: Vec<IdHex>) -> Result<(), Error> {
|
async fn get_events(&mut self, ids: Vec<IdHex>) -> Result<(), Error> {
|
||||||
if ids.is_empty() {
|
if ids.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -388,9 +386,10 @@ impl Minion {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
async fn follow_event_reactions(&mut self, _ids: Vec<IdHex>) -> Result<(), Error> {
|
async fn follow_event_reactions(&mut self, _ids: Vec<IdHex>) -> Result<(), Error> {
|
||||||
// Create or extend the "reactions" subscription
|
// Create or extend the "reactions" subscription
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,11 @@ impl Subscriptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub fn get_by_id(&self, id: &str) -> Option<Subscription> {
|
pub fn get_by_id(&self, id: &str) -> Option<Subscription> {
|
||||||
self.by_id.get(id).cloned()
|
self.by_id.get(id).cloned()
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn get_handle_by_id(&self, id: &str) -> Option<String> {
|
pub fn get_handle_by_id(&self, id: &str) -> Option<String> {
|
||||||
for (handle, xid) in self.handle_to_id.iter() {
|
for (handle, xid) in self.handle_to_id.iter() {
|
||||||
@ -67,10 +68,11 @@ impl Subscriptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub fn remove_by_id(&mut self, id: &str) {
|
pub fn remove_by_id(&mut self, id: &str) {
|
||||||
self.by_id.remove(id);
|
self.by_id.remove(id);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -101,10 +103,11 @@ impl Subscription {
|
|||||||
self.eose = true;
|
self.eose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/*
|
||||||
pub fn eose(&self) -> bool {
|
pub fn eose(&self) -> bool {
|
||||||
self.eose
|
self.eose
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn req_message(&self) -> ClientMessage {
|
pub fn req_message(&self) -> ClientMessage {
|
||||||
ClientMessage::Req(SubscriptionId(self.get_id()), self.filters.clone())
|
ClientMessage::Req(SubscriptionId(self.get_id()), self.filters.clone())
|
||||||
|
@ -5,6 +5,7 @@ use crate::comms::BusMessage;
|
|||||||
use crate::db::{DbEvent, DbPerson, DbPersonRelay, DbRelay};
|
use crate::db::{DbEvent, DbPerson, DbPersonRelay, DbRelay};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::globals::{Globals, GLOBALS};
|
use crate::globals::{Globals, GLOBALS};
|
||||||
|
use crate::people::People;
|
||||||
use minion::Minion;
|
use minion::Minion;
|
||||||
use nostr_types::{
|
use nostr_types::{
|
||||||
Event, EventKind, Id, Nip05, PreEvent, PrivateKey, PublicKey, PublicKeyHex, Tag, Unixtime, Url,
|
Event, EventKind, Id, Nip05, PreEvent, PrivateKey, PublicKey, PublicKeyHex, Tag, Unixtime, Url,
|
||||||
@ -94,7 +95,7 @@ impl Overlord {
|
|||||||
// new people are encountered, not batch-style on startup.
|
// new people are encountered, not batch-style on startup.
|
||||||
// Create a person record for every person seen
|
// Create a person record for every person seen
|
||||||
|
|
||||||
DbPerson::populate_new_people().await?;
|
People::populate_new_people().await?;
|
||||||
|
|
||||||
// FIXME - if this needs doing, it should be done dynamically as
|
// FIXME - if this needs doing, it should be done dynamically as
|
||||||
// new people are encountered, not batch-style on startup.
|
// new people are encountered, not batch-style on startup.
|
||||||
@ -118,13 +119,7 @@ impl Overlord {
|
|||||||
let _ = GLOBALS.to_syncer.send("test".to_owned());
|
let _ = GLOBALS.to_syncer.send("test".to_owned());
|
||||||
|
|
||||||
// Load people from the database
|
// Load people from the database
|
||||||
{
|
GLOBALS.people.write().await.load_all_followed().await?;
|
||||||
let mut dbpeople = DbPerson::fetch(None).await?;
|
|
||||||
for dbperson in dbpeople.drain(..) {
|
|
||||||
let pubkey = PublicKey::try_from(dbperson.pubkey.clone())?;
|
|
||||||
GLOBALS.people.write().await.insert(pubkey, dbperson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load latest metadata per person and update their metadata
|
// Load latest metadata per person and update their metadata
|
||||||
{
|
{
|
||||||
@ -172,7 +167,16 @@ impl Overlord {
|
|||||||
|
|
||||||
// Pick Relays and start Minions
|
// Pick Relays and start Minions
|
||||||
{
|
{
|
||||||
let pubkeys: Vec<PublicKeyHex> = crate::globals::followed_pubkeys().await;
|
let pubkeys: Vec<PublicKeyHex> = GLOBALS
|
||||||
|
.people
|
||||||
|
.read()
|
||||||
|
.await
|
||||||
|
.get_followed_pubkeys()
|
||||||
|
.await
|
||||||
|
.iter()
|
||||||
|
.map(|p| PublicKeyHex::from(*p))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let (num_relays_per_person, max_relays) = {
|
let (num_relays_per_person, max_relays) = {
|
||||||
let settings = GLOBALS.settings.read().await;
|
let settings = GLOBALS.settings.read().await;
|
||||||
(settings.num_relays_per_person, settings.max_relays)
|
(settings.num_relays_per_person, settings.max_relays)
|
||||||
|
215
src/people/mod.rs
Normal file
215
src/people/mod.rs
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
use crate::db::DbPerson;
|
||||||
|
use crate::error::Error;
|
||||||
|
use crate::globals::GLOBALS;
|
||||||
|
use nostr_types::{Metadata, PublicKey, PublicKeyHex, Unixtime};
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use tokio::task;
|
||||||
|
|
||||||
|
pub struct People {
|
||||||
|
people: HashMap<PublicKey, DbPerson>,
|
||||||
|
deferred_load: HashSet<PublicKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl People {
|
||||||
|
pub fn new() -> People {
|
||||||
|
People {
|
||||||
|
people: HashMap::new(),
|
||||||
|
deferred_load: HashSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_followed_pubkeys(&self) -> Vec<PublicKey> {
|
||||||
|
let mut output: Vec<PublicKey> = Vec::new();
|
||||||
|
for (_, person) in self.people.iter() {
|
||||||
|
if let Ok(pubkey) = PublicKey::try_from_hex_string(&person.pubkey.0) {
|
||||||
|
output.push(pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_if_missing(&mut self, pubkey: PublicKey) -> Result<(), Error> {
|
||||||
|
if self.people.contains_key(&pubkey) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try loading from the database
|
||||||
|
let maybe_dbperson = DbPerson::fetch_one(pubkey.into()).await?;
|
||||||
|
if let Some(dbperson) = maybe_dbperson {
|
||||||
|
// Insert into the map
|
||||||
|
self.people.insert(pubkey, dbperson);
|
||||||
|
} else {
|
||||||
|
// Create new
|
||||||
|
let dbperson = DbPerson {
|
||||||
|
pubkey: pubkey.into(),
|
||||||
|
name: None,
|
||||||
|
about: None,
|
||||||
|
picture: None,
|
||||||
|
dns_id: None,
|
||||||
|
dns_id_valid: 0,
|
||||||
|
dns_id_last_checked: None,
|
||||||
|
metadata_at: None,
|
||||||
|
followed: 0,
|
||||||
|
};
|
||||||
|
// Insert into the map
|
||||||
|
self.people.insert(pubkey, dbperson.clone());
|
||||||
|
// Insert into the database
|
||||||
|
DbPerson::insert(dbperson).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_metadata(
|
||||||
|
&mut self,
|
||||||
|
pubkey: PublicKey,
|
||||||
|
metadata: Metadata,
|
||||||
|
asof: Unixtime,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// Sync in from database first
|
||||||
|
self.create_if_missing(pubkey).await?;
|
||||||
|
|
||||||
|
// Update the map
|
||||||
|
let person = self.people.get_mut(&pubkey).unwrap();
|
||||||
|
if let Some(metadata_at) = person.metadata_at {
|
||||||
|
if asof.0 <= metadata_at {
|
||||||
|
// Old metadata. Ignore it
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
person.name = metadata.name;
|
||||||
|
person.about = metadata.about;
|
||||||
|
person.picture = metadata.picture;
|
||||||
|
if person.dns_id != metadata.nip05 {
|
||||||
|
person.dns_id = metadata.nip05;
|
||||||
|
person.dns_id_valid = 0; // changed, so reset to invalid
|
||||||
|
person.dns_id_last_checked = None; // we haven't checked this one yet
|
||||||
|
}
|
||||||
|
person.metadata_at = Some(asof.0);
|
||||||
|
|
||||||
|
// Update the database
|
||||||
|
let person = person.clone();
|
||||||
|
let pubkeyhex: PublicKeyHex = person.pubkey.clone();
|
||||||
|
task::spawn_blocking(move || {
|
||||||
|
let maybe_db = GLOBALS.db.blocking_lock();
|
||||||
|
let db = maybe_db.as_ref().unwrap();
|
||||||
|
|
||||||
|
let mut stmt = db.prepare(
|
||||||
|
"UPDATE person SET name=?, about=?, picture=?, dns_id=?, metadata_at=? WHERE pubkey=?"
|
||||||
|
)?;
|
||||||
|
stmt.execute((
|
||||||
|
&person.name,
|
||||||
|
&person.about,
|
||||||
|
&person.picture,
|
||||||
|
&person.dns_id,
|
||||||
|
&person.metadata_at,
|
||||||
|
&pubkeyhex.0,
|
||||||
|
))?;
|
||||||
|
Ok::<(), Error>(())
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn load_all_followed(&mut self) -> Result<(), Error> {
|
||||||
|
if !self.people.is_empty() {
|
||||||
|
return Err(Error::Internal(
|
||||||
|
"load_all_followed should only be called before people is otherwise used."
|
||||||
|
.to_owned(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let sql =
|
||||||
|
"SELECT pubkey, name, about, picture, dns_id, dns_id_valid, dns_id_last_checked, \
|
||||||
|
metadata_at, followed FROM person WHERE followed=1"
|
||||||
|
.to_owned();
|
||||||
|
|
||||||
|
let output: Result<Vec<DbPerson>, Error> = task::spawn_blocking(move || {
|
||||||
|
let maybe_db = GLOBALS.db.blocking_lock();
|
||||||
|
let db = maybe_db.as_ref().unwrap();
|
||||||
|
|
||||||
|
let mut stmt = db.prepare(&sql)?;
|
||||||
|
let rows = stmt.query_map([], |row| {
|
||||||
|
Ok(DbPerson {
|
||||||
|
pubkey: PublicKeyHex(row.get(0)?),
|
||||||
|
name: row.get(1)?,
|
||||||
|
about: row.get(2)?,
|
||||||
|
picture: row.get(3)?,
|
||||||
|
dns_id: row.get(4)?,
|
||||||
|
dns_id_valid: row.get(5)?,
|
||||||
|
dns_id_last_checked: row.get(6)?,
|
||||||
|
metadata_at: row.get(7)?,
|
||||||
|
followed: row.get(8)?,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
let mut output: Vec<DbPerson> = Vec::new();
|
||||||
|
for row in rows {
|
||||||
|
output.push(row?);
|
||||||
|
}
|
||||||
|
Ok(output)
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
for person in output? {
|
||||||
|
if let Ok(pubkey) = PublicKey::try_from_hex_string(&person.pubkey.0) {
|
||||||
|
self.people.insert(pubkey, person);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&mut self, pubkey: PublicKey) -> Option<DbPerson> {
|
||||||
|
if self.people.contains_key(&pubkey) {
|
||||||
|
self.people.get(&pubkey).cloned()
|
||||||
|
} else {
|
||||||
|
// Not there. Maybe it's in the database. Defer and let syncer
|
||||||
|
// try to load
|
||||||
|
self.deferred_load.insert(pubkey);
|
||||||
|
let _ = GLOBALS.to_syncer.send("sync_people".to_owned());
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_all(&mut self) -> Vec<DbPerson> {
|
||||||
|
let mut v: Vec<DbPerson> = self.people.values().map(|p| p.to_owned()).collect();
|
||||||
|
v.sort_by(|a, b| {
|
||||||
|
let c = a.name.cmp(&b.name);
|
||||||
|
if c == Ordering::Equal {
|
||||||
|
a.pubkey.cmp(&b.pubkey)
|
||||||
|
} else {
|
||||||
|
c
|
||||||
|
}
|
||||||
|
});
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn sync(&mut self) -> Result<(), Error> {
|
||||||
|
for pubkey in self.deferred_load.iter() {
|
||||||
|
if !self.people.contains_key(pubkey) {
|
||||||
|
if let Some(person) = DbPerson::fetch_one((*pubkey).into()).await? {
|
||||||
|
let _ = self.people.insert(*pubkey, person);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.deferred_load.clear();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is a 'just in case' the main code isn't keeping them in sync.
|
||||||
|
pub async fn populate_new_people() -> Result<(), Error> {
|
||||||
|
let sql = "INSERT or IGNORE INTO person (pubkey) SELECT DISTINCT pubkey FROM EVENT";
|
||||||
|
|
||||||
|
task::spawn_blocking(move || {
|
||||||
|
let maybe_db = GLOBALS.db.blocking_lock();
|
||||||
|
let db = maybe_db.as_ref().unwrap();
|
||||||
|
db.execute(sql, [])?;
|
||||||
|
Ok::<(), Error>(())
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
use crate::db::{
|
use crate::db::{
|
||||||
DbEvent, DbEventHashtag, DbEventRelationship, DbEventSeen, DbEventTag, DbPerson, DbPersonRelay,
|
DbEvent, DbEventHashtag, DbEventRelationship, DbEventSeen, DbEventTag, DbPersonRelay, DbRelay,
|
||||||
DbRelay,
|
|
||||||
};
|
};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::globals::{Globals, GLOBALS};
|
use crate::globals::{Globals, GLOBALS};
|
||||||
@ -44,28 +43,12 @@ pub async fn process_new_event(
|
|||||||
DbEventSeen::replace(db_event_seen).await?;
|
DbEventSeen::replace(db_event_seen).await?;
|
||||||
|
|
||||||
// Create the person if missing in the database
|
// Create the person if missing in the database
|
||||||
DbPerson::populate_new_people().await?;
|
GLOBALS
|
||||||
|
|
||||||
// Create the person if missing in GLOBALS.people
|
|
||||||
// FIXME - if the database has better data we should get it.
|
|
||||||
// we should fix that by making GLOBALS.people an
|
|
||||||
// object that persists on it's backend.
|
|
||||||
let _ = GLOBALS
|
|
||||||
.people
|
.people
|
||||||
.write()
|
.write()
|
||||||
.await
|
.await
|
||||||
.entry(event.pubkey)
|
.create_if_missing(event.pubkey)
|
||||||
.or_insert_with(|| DbPerson {
|
.await?;
|
||||||
pubkey: event.pubkey.into(),
|
|
||||||
name: None,
|
|
||||||
about: None,
|
|
||||||
picture: None,
|
|
||||||
dns_id: None,
|
|
||||||
dns_id_valid: 0,
|
|
||||||
dns_id_last_checked: None,
|
|
||||||
metadata_at: None,
|
|
||||||
followed: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update person_relay.last_fetched
|
// Update person_relay.last_fetched
|
||||||
DbPersonRelay::upsert_last_fetched(
|
DbPersonRelay::upsert_last_fetched(
|
||||||
@ -239,50 +222,15 @@ pub async fn process_new_event(
|
|||||||
// If metadata, update person
|
// If metadata, update person
|
||||||
if event.kind == EventKind::Metadata {
|
if event.kind == EventKind::Metadata {
|
||||||
let metadata: Metadata = serde_json::from_str(&event.content)?;
|
let metadata: Metadata = serde_json::from_str(&event.content)?;
|
||||||
let metadata2 = metadata.clone();
|
|
||||||
|
|
||||||
if from_relay {
|
GLOBALS
|
||||||
DbPerson::update_metadata(event.pubkey.into(), metadata.clone(), event.created_at)
|
.people
|
||||||
|
.write()
|
||||||
|
.await
|
||||||
|
.update_metadata(event.pubkey, metadata, event.created_at)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
let mut people = GLOBALS.people.write().await;
|
|
||||||
people
|
|
||||||
.entry(event.pubkey)
|
|
||||||
.and_modify(|person| {
|
|
||||||
if let Some(metadata_at) = person.metadata_at {
|
|
||||||
if event.created_at.0 <= metadata_at {
|
|
||||||
// Old metadata. Ignore it
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the metadata
|
|
||||||
person.name = metadata.name;
|
|
||||||
person.about = metadata.about;
|
|
||||||
person.picture = metadata.picture;
|
|
||||||
if person.dns_id != metadata.nip05 {
|
|
||||||
person.dns_id = metadata.nip05;
|
|
||||||
person.dns_id_valid = 0; // changed, so reset to invalid
|
|
||||||
person.dns_id_last_checked = None; // we haven't checked this one yet
|
|
||||||
}
|
|
||||||
person.metadata_at = Some(event.created_at.0);
|
|
||||||
})
|
|
||||||
.or_insert_with(|| {
|
|
||||||
let mut person = DbPerson::new(event.pubkey.into());
|
|
||||||
person.name = metadata2.name;
|
|
||||||
person.about = metadata2.about;
|
|
||||||
person.picture = metadata2.picture;
|
|
||||||
person.dns_id = metadata2.nip05;
|
|
||||||
person.dns_id_valid = 0;
|
|
||||||
person.dns_id_last_checked = None; // we haven't checked this one yet
|
|
||||||
person.metadata_at = Some(event.created_at.0);
|
|
||||||
person
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Handle EventKind::RecommendedRelay
|
// FIXME: Handle EventKind::RecommendedRelay
|
||||||
|
|
||||||
// FIXME: Handle EventKind::ContactList
|
// FIXME: Handle EventKind::ContactList
|
||||||
|
@ -14,12 +14,10 @@ impl Default for Signer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Signer {
|
impl Signer {
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn load_encrypted_private_key(&mut self, epk: EncryptedPrivateKey) {
|
pub fn load_encrypted_private_key(&mut self, epk: EncryptedPrivateKey) {
|
||||||
*self = Signer::Encrypted(epk);
|
*self = Signer::Encrypted(epk);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn unlock_encrypted_private_key(&mut self, pass: &str) -> Result<(), Error> {
|
pub fn unlock_encrypted_private_key(&mut self, pass: &str) -> Result<(), Error> {
|
||||||
if let Signer::Encrypted(epk) = self {
|
if let Signer::Encrypted(epk) = self {
|
||||||
*self = Signer::Ready(epk.decrypt(pass)?);
|
*self = Signer::Ready(epk.decrypt(pass)?);
|
||||||
@ -38,17 +36,14 @@ impl Signer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn is_loaded(&self) -> bool {
|
pub fn is_loaded(&self) -> bool {
|
||||||
matches!(self, Signer::Encrypted(_)) || matches!(self, Signer::Ready(_))
|
matches!(self, Signer::Encrypted(_)) || matches!(self, Signer::Ready(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn is_ready(&self) -> bool {
|
pub fn is_ready(&self) -> bool {
|
||||||
matches!(self, Signer::Ready(_))
|
matches!(self, Signer::Ready(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn public_key(&self) -> Option<PublicKey> {
|
pub fn public_key(&self) -> Option<PublicKey> {
|
||||||
if let Signer::Ready(pk) = self {
|
if let Signer::Ready(pk) = self {
|
||||||
Some(pk.public_key())
|
Some(pk.public_key())
|
||||||
@ -57,7 +52,6 @@ impl Signer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn key_security(&self) -> Option<KeySecurity> {
|
pub fn key_security(&self) -> Option<KeySecurity> {
|
||||||
if let Signer::Ready(pk) = self {
|
if let Signer::Ready(pk) = self {
|
||||||
Some(pk.key_security())
|
Some(pk.key_security())
|
||||||
@ -66,7 +60,6 @@ impl Signer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn sign_preevent(&self, preevent: PreEvent, pow: Option<u8>) -> Result<Event, Error> {
|
pub fn sign_preevent(&self, preevent: PreEvent, pow: Option<u8>) -> Result<Event, Error> {
|
||||||
match self {
|
match self {
|
||||||
Signer::Ready(pk) => match pow {
|
Signer::Ready(pk) => match pow {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::globals::GLOBALS;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
pub struct Syncer {
|
pub struct Syncer {
|
||||||
@ -23,6 +24,11 @@ impl Syncer {
|
|||||||
"test" => {
|
"test" => {
|
||||||
tracing::debug!("Syncer received test message.");
|
tracing::debug!("Syncer received test message.");
|
||||||
}
|
}
|
||||||
|
"sync_people" => {
|
||||||
|
if let Err(e) = GLOBALS.people.write().await.sync().await {
|
||||||
|
tracing::error!("Problem syncing people: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
tracing::debug!("Syncer received unknown message: {}", message);
|
tracing::debug!("Syncer received unknown message: {}", message);
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ fn render_post(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let maybe_person = GLOBALS.people.blocking_read().get(&event.pubkey).cloned();
|
let maybe_person = GLOBALS.people.blocking_write().get(event.pubkey);
|
||||||
|
|
||||||
let reactions = Globals::get_reactions_sync(event.id);
|
let reactions = Globals::get_reactions_sync(event.id);
|
||||||
let replies = Globals::get_replies_sync(event.id);
|
let replies = Globals::get_replies_sync(event.id);
|
||||||
@ -339,7 +339,7 @@ fn render_post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_person_view(app: &mut GossipUi, pubkey: PublicKey) {
|
fn set_person_view(app: &mut GossipUi, pubkey: PublicKey) {
|
||||||
if let Some(dbperson) = GLOBALS.people.blocking_read().get(&pubkey).cloned() {
|
if let Some(dbperson) = GLOBALS.people.blocking_write().get(pubkey) {
|
||||||
app.person_view_name = if let Some(name) = &dbperson.name {
|
app.person_view_name = if let Some(name) = &dbperson.name {
|
||||||
Some(name.to_string())
|
Some(name.to_string())
|
||||||
} else {
|
} else {
|
||||||
|
@ -120,10 +120,10 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra
|
|||||||
ui.heading("People Followed");
|
ui.heading("People Followed");
|
||||||
ui.add_space(18.0);
|
ui.add_space(18.0);
|
||||||
|
|
||||||
let people = GLOBALS.people.blocking_read().clone();
|
let people = GLOBALS.people.blocking_write().get_all();
|
||||||
|
|
||||||
ScrollArea::vertical().show(ui, |ui| {
|
ScrollArea::vertical().show(ui, |ui| {
|
||||||
for (_, person) in people.iter() {
|
for person in people.iter() {
|
||||||
if person.followed != 1 {
|
if person.followed != 1 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user