Merge branch 'dilger/nip11' into feature/relay-list-widget

This commit is contained in:
Bu5hm4nn 2023-05-18 22:24:19 -06:00
commit f5acc8034c
4 changed files with 47 additions and 6 deletions

View File

@ -244,7 +244,7 @@ fn normalize_urls() -> Result<(), Error> {
Ok(())
}
const UPGRADE_SQL: [&str; 34] = [
const UPGRADE_SQL: [&str; 35] = [
include_str!("sql/schema1.sql"),
include_str!("sql/schema2.sql"),
include_str!("sql/schema3.sql"),
@ -279,4 +279,5 @@ const UPGRADE_SQL: [&str; 34] = [
include_str!("sql/schema32.sql"),
include_str!("sql/schema33.sql"),
include_str!("sql/schema34.sql"),
include_str!("sql/schema35.sql"),
];

View File

@ -1,6 +1,6 @@
use crate::error::Error;
use crate::globals::GLOBALS;
use nostr_types::{Id, RelayUrl};
use nostr_types::{Id, RelayInformationDocument, RelayUrl};
use tokio::task::spawn_blocking;
#[derive(Debug, Clone)]
@ -13,6 +13,8 @@ pub struct DbRelay {
pub rank: u64,
pub hidden: bool,
pub usage_bits: u64,
pub nip11: Option<RelayInformationDocument>,
pub last_attempt_nip11: Option<u64>,
}
impl DbRelay {
@ -35,6 +37,8 @@ impl DbRelay {
rank: 3,
hidden: false,
usage_bits: 0,
nip11: None,
last_attempt_nip11: None,
}
}
@ -86,7 +90,8 @@ impl DbRelay {
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbRelay>, Error> {
let sql = "SELECT url, success_count, failure_count, last_connected_at, \
last_general_eose_at, rank, hidden, usage_bits FROM relay"
last_general_eose_at, rank, hidden, usage_bits, \
nip11, last_attempt_nip11 FROM relay"
.to_owned();
let sql = match criteria {
None => sql,
@ -101,8 +106,12 @@ impl DbRelay {
let mut output: Vec<DbRelay> = Vec::new();
while let Some(row) = rows.next()? {
let s: String = row.get(0)?;
// just skip over invalid relay URLs
if let Ok(url) = RelayUrl::try_from_str(&s) {
let nip11: Option<String> = row.get(8)?;
output.push(DbRelay {
url,
success_count: row.get(1)?,
@ -112,6 +121,11 @@ impl DbRelay {
rank: row.get(5)?,
hidden: row.get(6)?,
usage_bits: row.get(7)?,
nip11: match nip11 {
None => None,
Some(s) => serde_json::from_str(&s)?
},
last_attempt_nip11: row.get(9)?,
});
}
}
@ -134,8 +148,9 @@ impl DbRelay {
pub async fn insert(relay: DbRelay) -> Result<(), Error> {
let sql = "INSERT OR IGNORE INTO relay (url, success_count, failure_count, \
last_connected_at, last_general_eose_at, rank, hidden, usage_bits) \
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)";
last_connected_at, last_general_eose_at, rank, hidden, usage_bits, \
nip11, last_attempt_nip11) \
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)";
spawn_blocking(move || {
let db = GLOBALS.db.blocking_lock();
@ -150,6 +165,11 @@ impl DbRelay {
&relay.rank,
&relay.hidden,
&relay.usage_bits,
match relay.nip11 {
None => None,
Some(n11) => Some(serde_json::to_string(&n11)?),
},
&relay.last_attempt_nip11,
)));
Ok::<(), Error>(())
})
@ -161,7 +181,7 @@ impl DbRelay {
pub async fn update(relay: DbRelay) -> Result<(), Error> {
let sql = "UPDATE relay SET success_count=?, failure_count=?, \
last_connected_at=?, last_general_eose_at=?, \
rank=?, hidden=?, usage_bits=? \
rank=?, hidden=?, usage_bits=?, nip11=?, last_attempt_nip11=? \
WHERE url=?";
spawn_blocking(move || {
@ -176,6 +196,11 @@ impl DbRelay {
&relay.rank,
&relay.hidden,
&relay.usage_bits,
match relay.nip11 {
None => None,
Some(n11) => Some(serde_json::to_string(&n11)?),
},
&relay.last_attempt_nip11,
&relay.url.0,
)));
Ok::<(), Error>(())

2
src/db/sql/schema35.sql Normal file
View File

@ -0,0 +1,2 @@
ALTER TABLE relay ADD COLUMN nip11 TEXT DEFAULT NULL;
ALTER TABLE relay ADD COLUMN last_attempt_nip11 INTEGER DEFAULT NULL;

View File

@ -87,6 +87,8 @@ impl Minion {
// Connect to the relay
let websocket_stream = {
// Parse the URI
let uri: http::Uri = self.url.0.parse::<Uri>()?;
let mut parts: Parts = uri.into_parts();
parts.scheme = match parts.scheme {
@ -98,6 +100,8 @@ impl Minion {
None => Some(Scheme::HTTPS),
};
let uri = http::Uri::from_parts(parts)?;
// Fetch NIP-11 data
let request_nip11_future = reqwest::Client::builder()
.timeout(std::time::Duration::new(30, 0))
.redirect(reqwest::redirect::Policy::none())
@ -109,6 +113,7 @@ impl Minion {
.header("Accept", "application/nostr+json")
.send();
let response = request_nip11_future.await?;
self.dbrelay.last_attempt_nip11 = Some(Unixtime::now().unwrap().0 as u64);
let status = response.status();
match Self::text_with_charset(response, "utf-8").await {
Ok(text) => {
@ -123,6 +128,7 @@ impl Minion {
Ok(nip11) => {
tracing::info!("{}: {}", &self.url, nip11);
self.nip11 = Some(nip11);
self.dbrelay.nip11 = self.nip11.clone();
}
Err(e) => {
tracing::warn!(
@ -140,6 +146,13 @@ impl Minion {
}
}
// Save updated NIP-11 data (even if it failed)
// in memory...
let _ = GLOBALS.all_relays.insert(self.url.clone(), self.dbrelay.clone());
// and in the database...
DbRelay::update(self.dbrelay.clone()).await?;
let key: [u8; 16] = rand::random();
let req = http::request::Request::builder().method("GET");