Skip to content

Commit

Permalink
Added settings page and Webhook settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ericpp committed Mar 8, 2024
1 parent b9ae3ee commit c883776
Show file tree
Hide file tree
Showing 12 changed files with 725 additions and 112 deletions.
1 change: 1 addition & 0 deletions dbif/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
chrono = "0.4.19"
rusqlite = "0.26.1"
serde = {version = "1.0", features = ["derive"] }
serde_json = "1.0"
201 changes: 200 additions & 1 deletion dbif/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::fmt;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::os::unix::fs::PermissionsExt;
use chrono::DateTime;

#[derive(Serialize, Deserialize, Debug)]
pub struct NodeInfoRecord {
Expand Down Expand Up @@ -58,6 +59,26 @@ pub struct PaymentRecord {
pub reply_to_idx: Option<u64>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct WebhookRecord {
pub index: u64,
pub url: String,
pub token: String,
pub enabled: bool,
pub request_successful: Option<bool>,
pub request_timestamp: Option<i64>,
pub request_datetime: Option<String>,
}

impl WebhookRecord {
pub fn get_request_timestamp_string(&self) -> Option<String> {
match self.request_timestamp {
Some(timestamp) => Some(DateTime::from_timestamp(timestamp, 0).unwrap().to_rfc3339()),
None => None,
}
}
}

#[derive(Debug)]
struct HydraError(String);
impl fmt::Display for HydraError {
Expand Down Expand Up @@ -250,6 +271,28 @@ pub fn create_database(filepath: &String) -> Result<bool, Box<dyn Error>> {
}
}


//Create the sent boosts table
match conn.execute(
"CREATE TABLE IF NOT EXISTS webhooks (
idx integer primary key autoincrement,
url text,
token text,
enabled integer,
request_successful integer,
request_timestamp integer
)",
[],
) {
Ok(_) => {
println!("Webhooks table is ready.");
}
Err(e) => {
eprintln!("{}", e);
return Err(Box::new(HydraError(format!("Failed to create database webhooks table: [{}].", filepath).into())))
}
}

Ok(true)
}

Expand Down Expand Up @@ -320,7 +363,7 @@ pub fn add_node_info_to_db(filepath: &String, info: NodeInfoRecord) -> Result<bo
}

//Add an invoice to the database
pub fn add_invoice_to_db(filepath: &String, boost: BoostRecord) -> Result<bool, Box<dyn Error>> {
pub fn add_invoice_to_db(filepath: &String, boost: &BoostRecord) -> Result<bool, Box<dyn Error>> {
let conn = connect_to_database(false, filepath)?;

match conn.execute("INSERT INTO boosts (idx, time, value_msat, value_msat_total, action, sender, app, message, podcast, episode, tlv, remote_podcast, remote_episode, reply_sent) \
Expand Down Expand Up @@ -805,5 +848,161 @@ pub fn add_payment_to_db(filepath: &String, boost: &BoostRecord) -> Result<bool,
mark_boost_as_replied(filepath, reply_to_idx)?;
}

Ok(true)
}

pub fn get_webhooks_from_db(filepath: &String, enabled: Option<bool>) -> Result<Vec<WebhookRecord>, Box<dyn Error>> {
let conn = connect_to_database(false, filepath)?;
let mut webhooks: Vec<WebhookRecord> = Vec::new();

let where_enabled = match enabled {
Some(true) => "WHERE enabled = 1",
Some(false) => "WHERE enabled = 0",
None => "",
};

let sqltxt = format!(
r#"SELECT
idx,
url,
token,
enabled,
request_successful,
request_timestamp
FROM
webhooks
{}"#,
where_enabled,
);

let mut stmt = conn.prepare(sqltxt.as_str())?;
let rows = stmt.query_map([], |row| {
let datetime = match row.get(5).ok() {
Some(ts) => match DateTime::from_timestamp(ts, 0) {
Some(ts) => Some(ts.to_rfc3339()),
None => None,
},
None => None,
};

Ok(WebhookRecord {
index: row.get(0)?,
url: row.get(1)?,
token: row.get(2)?,
enabled: row.get(3)?,
request_successful: row.get(4).ok(),
request_timestamp: row.get(5).ok(),
request_datetime: datetime,
})
}).unwrap();

for row in rows {
webhooks.push(row.unwrap());
}

Ok(webhooks)
}

pub fn load_webhook_from_db(filepath: &String, index: u64) -> Result<WebhookRecord, Box<dyn Error>> {
let conn = connect_to_database(false, filepath)?;

let mut stmt = conn.prepare(
r#"SELECT
idx,
url,
token,
enabled,
request_successful,
request_timestamp
FROM
webhooks
WHERE
idx = :idx
"#
)?;

let webhook = stmt.query_row(&[(":idx", index.to_string().as_str())], |row| {
let timestamp: i64 = row.get(5)?;
let datetime = match DateTime::from_timestamp(timestamp, 0) {
Some(ts) => Some(ts.to_rfc3339()),
None => None
};

Ok(WebhookRecord {
index: row.get(0)?,
url: row.get(1)?,
token: row.get(2)?,
enabled: row.get(3)?,
request_successful: row.get(4).ok(),
request_timestamp: row.get(5).ok(),
request_datetime: datetime,
})
})?;

Ok(webhook)
}

pub fn save_webhook_to_db(filepath: &String, webhook: &WebhookRecord) -> Result<u64, Box<dyn Error>> {
let conn = connect_to_database(false, filepath)?;

let index = if webhook.index > 0 {
Some(webhook.index)
} else {
None
};

let mut stmt = conn.prepare(
r#"INSERT INTO webhooks (
idx,
url,
token,
enabled,
request_successful,
request_timestamp
)
VALUES
(?1, ?2, ?3, ?4, ?5, ?6)
ON CONFLICT(idx) DO UPDATE SET
url = excluded.url,
token = excluded.token,
enabled = excluded.enabled
RETURNING idx
"#,
)?;

let params = params![
index,
webhook.url,
webhook.token,
webhook.enabled,
webhook.request_successful,
webhook.request_timestamp,
];

let idx = stmt.query_row(params, |row| {
let idx: u64 = row.get(0)?;
Ok(idx)
})?;

Ok(idx)
}

pub fn set_webhook_last_request(filepath: &String, index: u64, successful: bool, timestamp: i64) -> Result<bool, Box<dyn Error>> {
let conn = connect_to_database(false, filepath)?;

conn.execute(
r#"UPDATE webhooks SET request_successful = ?2, request_timestamp = ?3 WHERE idx = ?1"#,
params![index, successful, timestamp]
)?;

Ok(true)

}

pub fn delete_webhook_from_db(filepath: &String, index: u64) -> Result<bool, Box<dyn Error>> {
let conn = connect_to_database(false, filepath)?;

conn.execute(r#"DELETE FROM webhooks WHERE idx = ?1"#, params![index])?;

Ok(true)
}

0 comments on commit c883776

Please sign in to comment.