mirror of
https://github.com/scsibug/nostr-rs-relay.git
synced 2024-11-22 17:19:07 -05:00
Merge pull request #8 from scsibug/master
Fork Sync: Update from parent repository
This commit is contained in:
commit
cb00b825db
|
@ -20,6 +20,9 @@ description = "A newly created nostr-rs-relay.\n\nCustomize this with your own i
|
||||||
# ICO format.
|
# ICO format.
|
||||||
#favicon = "favicon.ico"
|
#favicon = "favicon.ico"
|
||||||
|
|
||||||
|
# URL of Relay's icon.
|
||||||
|
#relay_icon = "https://example.test/img.png"
|
||||||
|
|
||||||
[diagnostics]
|
[diagnostics]
|
||||||
# Enable tokio tracing (for use with tokio-console)
|
# Enable tokio tracing (for use with tokio-console)
|
||||||
#tracing = false
|
#tracing = false
|
||||||
|
|
|
@ -112,7 +112,8 @@ seen" policy.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
PRAGMA foreign_keys = ON;
|
PRAGMA foreign_keys = ON;
|
||||||
TODO!
|
|
||||||
|
DELETE FROM event WHERE first_seen < CAST(strftime('%s', date('now', '-30 day')) AS INT);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Delete Profile Events with No Recent Events
|
### Delete Profile Events with No Recent Events
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn main() -> Result<()> {
|
||||||
let _trace_sub = tracing_subscriber::fmt::try_init();
|
let _trace_sub = tracing_subscriber::fmt::try_init();
|
||||||
println!("Nostr-rs-relay Bulk Loader");
|
println!("Nostr-rs-relay Bulk Loader");
|
||||||
// check for a database file, or create one.
|
// check for a database file, or create one.
|
||||||
let settings = config::Settings::new(&None);
|
let settings = config::Settings::new(&None)?;
|
||||||
if !Path::new(&settings.database.data_directory).is_dir() {
|
if !Path::new(&settings.database.data_directory).is_dir() {
|
||||||
info!("Database directory does not exist");
|
info!("Database directory does not exist");
|
||||||
return Err(Error::DatabaseDirError);
|
return Err(Error::DatabaseDirError);
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
//! Configuration file and settings management
|
//! Configuration file and settings management
|
||||||
|
use crate::payment::Processor;
|
||||||
use config::{Config, ConfigError, File};
|
use config::{Config, ConfigError, File};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::warn;
|
|
||||||
|
|
||||||
use crate::payment::Processor;
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -15,6 +13,7 @@ pub struct Info {
|
||||||
pub pubkey: Option<String>,
|
pub pubkey: Option<String>,
|
||||||
pub contact: Option<String>,
|
pub contact: Option<String>,
|
||||||
pub favicon: Option<String>,
|
pub favicon: Option<String>,
|
||||||
|
pub relay_icon: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
@ -192,18 +191,24 @@ pub struct Settings {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
#[must_use]
|
pub fn new(config_file_name: &Option<String>) -> Result<Self, ConfigError> {
|
||||||
pub fn new(config_file_name: &Option<String>) -> Self {
|
|
||||||
let default_settings = Self::default();
|
let default_settings = Self::default();
|
||||||
// attempt to construct settings with file
|
// attempt to construct settings with file
|
||||||
let from_file = Self::new_from_default(&default_settings, config_file_name);
|
let from_file = Self::new_from_default(&default_settings, config_file_name);
|
||||||
match from_file {
|
match from_file {
|
||||||
Ok(f) => f,
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Error reading config file ({:?})", e);
|
// pass up the parse error if the config file was specified,
|
||||||
default_settings
|
// otherwise use the default config (with a warning).
|
||||||
|
if config_file_name.is_some() {
|
||||||
|
Err(e)
|
||||||
|
} else {
|
||||||
|
eprintln!("Error reading config file ({:?})", e);
|
||||||
|
eprintln!("WARNING: Default configuration settings will be used");
|
||||||
|
Ok(default_settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ok => ok,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_from_default(
|
fn new_from_default(
|
||||||
|
@ -268,6 +273,7 @@ impl Default for Settings {
|
||||||
pubkey: None,
|
pubkey: None,
|
||||||
contact: None,
|
contact: None,
|
||||||
favicon: None,
|
favicon: None,
|
||||||
|
relay_icon: None,
|
||||||
},
|
},
|
||||||
diagnostics: Diagnostics { tracing: false },
|
diagnostics: Diagnostics { tracing: false },
|
||||||
database: Database {
|
database: Database {
|
||||||
|
|
|
@ -45,6 +45,8 @@ pub struct RelayInfo {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub contact: Option<String>,
|
pub contact: Option<String>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub icon: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub supported_nips: Option<Vec<i64>>,
|
pub supported_nips: Option<Vec<i64>>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub software: Option<String>,
|
pub software: Option<String>,
|
||||||
|
@ -124,6 +126,7 @@ impl From<Settings> for RelayInfo {
|
||||||
limitation: Some(limitations),
|
limitation: Some(limitations),
|
||||||
payment_url,
|
payment_url,
|
||||||
fees,
|
fees,
|
||||||
|
icon: i.relay_icon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -4,6 +4,9 @@ use console_subscriber::ConsoleLayer;
|
||||||
use nostr_rs_relay::cli::CLIArgs;
|
use nostr_rs_relay::cli::CLIArgs;
|
||||||
use nostr_rs_relay::config;
|
use nostr_rs_relay::config;
|
||||||
use nostr_rs_relay::server::start_server;
|
use nostr_rs_relay::server::start_server;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::process;
|
||||||
use std::sync::mpsc as syncmpsc;
|
use std::sync::mpsc as syncmpsc;
|
||||||
use std::sync::mpsc::{Receiver as MpscReceiver, Sender as MpscSender};
|
use std::sync::mpsc::{Receiver as MpscReceiver, Sender as MpscSender};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
@ -24,11 +27,35 @@ fn main() {
|
||||||
// get config file name from args
|
// get config file name from args
|
||||||
let config_file_arg = args.config;
|
let config_file_arg = args.config;
|
||||||
|
|
||||||
|
// Ensure the config file is readable if it was explicitly set
|
||||||
|
if let Some(config_path) = config_file_arg.as_ref() {
|
||||||
|
let path = Path::new(&config_path);
|
||||||
|
if !path.exists() {
|
||||||
|
eprintln!("Config file not found: {}", &config_path);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
if !path.is_file() {
|
||||||
|
eprintln!("Invalid config file path: {}", &config_path);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
if let Err(err) = fs::metadata(path) {
|
||||||
|
eprintln!("Error while accessing file metadata: {}", err);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
if let Err(err) = fs::File::open(path) {
|
||||||
|
eprintln!("Config file is not readable: {}", err);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut _log_guard: Option<WorkerGuard> = None;
|
let mut _log_guard: Option<WorkerGuard> = None;
|
||||||
|
|
||||||
// configure settings from the config file (defaults to config.toml)
|
// configure settings from the config file (defaults to config.toml)
|
||||||
// replace default settings with those read from the config file
|
// replace default settings with those read from the config file
|
||||||
let mut settings = config::Settings::new(&config_file_arg);
|
let mut settings = config::Settings::new(&config_file_arg).unwrap_or_else(|e| {
|
||||||
|
eprintln!("Error reading config file ({:?})", e);
|
||||||
|
process::exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
// setup tracing
|
// setup tracing
|
||||||
if settings.diagnostics.tracing {
|
if settings.diagnostics.tracing {
|
||||||
|
|
|
@ -904,7 +904,7 @@ fn query_from_filter(f: &ReqFilter) -> Option<QueryBuilder<Postgres>> {
|
||||||
}
|
}
|
||||||
push_and = true;
|
push_and = true;
|
||||||
query
|
query
|
||||||
.push("e.created_at > ")
|
.push("e.created_at >= ")
|
||||||
.push_bind(Utc.timestamp_opt(f.since.unwrap() as i64, 0).unwrap());
|
.push_bind(Utc.timestamp_opt(f.since.unwrap() as i64, 0).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,7 +915,7 @@ fn query_from_filter(f: &ReqFilter) -> Option<QueryBuilder<Postgres>> {
|
||||||
}
|
}
|
||||||
push_and = true;
|
push_and = true;
|
||||||
query
|
query
|
||||||
.push("e.created_at < ")
|
.push("e.created_at <= ")
|
||||||
.push_bind(Utc.timestamp_opt(f.until.unwrap() as i64, 0).unwrap());
|
.push_bind(Utc.timestamp_opt(f.until.unwrap() as i64, 0).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1083,13 +1083,13 @@ fn query_from_filter(f: &ReqFilter) -> (String, Vec<Box<dyn ToSql>>, Option<Stri
|
||||||
kind_clause = String::new();
|
kind_clause = String::new();
|
||||||
};
|
};
|
||||||
if f.since.is_some() {
|
if f.since.is_some() {
|
||||||
since_clause = format!("AND created_at > {}", f.since.unwrap());
|
since_clause = format!("AND created_at >= {}", f.since.unwrap());
|
||||||
} else {
|
} else {
|
||||||
since_clause = String::new();
|
since_clause = String::new();
|
||||||
};
|
};
|
||||||
// Query for timestamp
|
// Query for timestamp
|
||||||
if f.until.is_some() {
|
if f.until.is_some() {
|
||||||
until_clause = format!("AND created_at < {}", f.until.unwrap());
|
until_clause = format!("AND created_at <= {}", f.until.unwrap());
|
||||||
} else {
|
} else {
|
||||||
until_clause = String::new();
|
until_clause = String::new();
|
||||||
};
|
};
|
||||||
|
@ -1107,12 +1107,12 @@ fn query_from_filter(f: &ReqFilter) -> (String, Vec<Box<dyn ToSql>>, Option<Stri
|
||||||
}
|
}
|
||||||
// Query for timestamp
|
// Query for timestamp
|
||||||
if f.since.is_some() {
|
if f.since.is_some() {
|
||||||
let created_clause = format!("created_at > {}", f.since.unwrap());
|
let created_clause = format!("created_at >= {}", f.since.unwrap());
|
||||||
filter_components.push(created_clause);
|
filter_components.push(created_clause);
|
||||||
}
|
}
|
||||||
// Query for timestamp
|
// Query for timestamp
|
||||||
if f.until.is_some() {
|
if f.until.is_some() {
|
||||||
let until_clause = format!("created_at < {}", f.until.unwrap());
|
let until_clause = format!("created_at <= {}", f.until.unwrap());
|
||||||
filter_components.push(until_clause);
|
filter_components.push(until_clause);
|
||||||
}
|
}
|
||||||
// never display hidden events
|
// never display hidden events
|
||||||
|
|
|
@ -319,8 +319,8 @@ impl ReqFilter {
|
||||||
pub fn interested_in_event(&self, event: &Event) -> bool {
|
pub fn interested_in_event(&self, event: &Event) -> bool {
|
||||||
// self.id.as_ref().map(|v| v == &event.id).unwrap_or(true)
|
// self.id.as_ref().map(|v| v == &event.id).unwrap_or(true)
|
||||||
self.ids_match(event)
|
self.ids_match(event)
|
||||||
&& self.since.map_or(true, |t| event.created_at > t)
|
&& self.since.map_or(true, |t| event.created_at >= t)
|
||||||
&& self.until.map_or(true, |t| event.created_at < t)
|
&& self.until.map_or(true, |t| event.created_at <= t)
|
||||||
&& self.kind_match(event.kind)
|
&& self.kind_match(event.kind)
|
||||||
&& (self.authors_match(event) || self.delegated_authors_match(event))
|
&& (self.authors_match(event) || self.delegated_authors_match(event))
|
||||||
&& self.tag_match(event)
|
&& self.tag_match(event)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user