mirror of
https://github.com/BreizhHardware/ntfy_alerts.git
synced 2026-01-18 16:37:28 +01:00
refactor(database): add version tracking functions and update notification logic
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
use log::info;
|
use log::info;
|
||||||
use rusqlite::{Connection, Result as SqliteResult, OpenFlags};
|
pub(crate) use rusqlite::{Connection, Result as SqliteResult, OpenFlags};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
@@ -78,4 +78,26 @@ pub fn get_docker_watched_repos(conn: &Connection) -> SqliteResult<Vec<String>>
|
|||||||
repos.push(repo?);
|
repos.push(repo?);
|
||||||
}
|
}
|
||||||
Ok(repos)
|
Ok(repos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_new_version(conn: &Connection, repo: &str, version: &str) -> SqliteResult<bool> {
|
||||||
|
let mut stmt = conn.prepare("SELECT version FROM versions WHERE repo = ?")?;
|
||||||
|
let result = stmt.query_map([repo], |row| row.get::<_, String>(0))?;
|
||||||
|
|
||||||
|
for stored_version in result {
|
||||||
|
if let Ok(v) = stored_version {
|
||||||
|
return Ok(v != version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_version(conn: &Connection, repo: &str, version: &str, changelog: Option<&str>) -> SqliteResult<()> {
|
||||||
|
conn.execute(
|
||||||
|
"REPLACE INTO versions (repo, version, changelog) VALUES (?, ?, ?)",
|
||||||
|
[repo, version, changelog.unwrap_or("")],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let config = config::Config::from_env();
|
let config = config::Config::from_env();
|
||||||
let (_conn_versions, conn_repos) = database::init_databases()?;
|
let (conn_versions, conn_repos) = database::init_databases()?;
|
||||||
|
|
||||||
start_api();
|
start_api();
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let github_releases = github::get_latest_releases(&github_repos, &client, config.github_headers()).await;
|
let github_releases = github::get_latest_releases(&github_repos, &client, config.github_headers()).await;
|
||||||
let docker_releases = docker::get_latest_docker_releases(&docker_repos, &client, config.docker_headers()).await;
|
let docker_releases = docker::get_latest_docker_releases(&docker_repos, &client, config.docker_headers()).await;
|
||||||
|
|
||||||
notifications::send_notifications(github_releases, docker_releases, &config).await;
|
notifications::send_notifications(github_releases, docker_releases, &config, &conn_versions).await;
|
||||||
|
|
||||||
tokio::time::sleep(Duration::from_secs_f64(config.timeout)).await;
|
tokio::time::sleep(Duration::from_secs_f64(config.timeout)).await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,4 +33,10 @@ pub struct DockerReleaseInfo {
|
|||||||
pub digest: String,
|
pub digest: String,
|
||||||
pub html_url: String,
|
pub html_url: String,
|
||||||
pub published_at: String,
|
pub published_at: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NotifiedRelease {
|
||||||
|
pub repo: String,
|
||||||
|
pub tag_name: String,
|
||||||
|
pub notified_at: chrono::DateTime<chrono::Utc>,
|
||||||
}
|
}
|
||||||
@@ -8,85 +8,95 @@ pub mod docker;
|
|||||||
use tokio::task;
|
use tokio::task;
|
||||||
use crate::models::{GithubReleaseInfo, DockerReleaseInfo};
|
use crate::models::{GithubReleaseInfo, DockerReleaseInfo};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
use crate::database::{Connection, is_new_version, update_version};
|
||||||
|
use rusqlite::Result as SqliteResult;
|
||||||
|
|
||||||
pub async fn send_notifications(
|
pub async fn send_notifications(
|
||||||
github_releases: Vec<GithubReleaseInfo>,
|
github_releases: Vec<GithubReleaseInfo>,
|
||||||
docker_releases: Vec<DockerReleaseInfo>,
|
docker_releases: Vec<DockerReleaseInfo>,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) {
|
db_conn: &Connection,
|
||||||
|
) -> SqliteResult<()> {
|
||||||
let mut tasks = Vec::new();
|
let mut tasks = Vec::new();
|
||||||
|
|
||||||
// Create tasks for GitHub notifications
|
// Create tasks for GitHub notifications
|
||||||
for release in &github_releases {
|
for release in &github_releases {
|
||||||
if let Some(url) = &config.ntfy_url {
|
if is_new_version(db_conn, &release.repo, &release.tag_name)? {
|
||||||
let release = release.clone();
|
if let Some(url) = &config.ntfy_url {
|
||||||
let auth = config.auth.clone();
|
let release = release.clone();
|
||||||
let url = url.clone();
|
let auth = config.auth.clone();
|
||||||
tasks.push(task::spawn(async move {
|
let url = url.clone();
|
||||||
github::send_to_ntfy(release, &auth, &url).await;
|
tasks.push(task::spawn(async move {
|
||||||
}));
|
github::send_to_ntfy(release, &auth, &url).await;
|
||||||
}
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
if let (Some(gotify_url), Some(gotify_token)) = (&config.gotify_url, &config.gotify_token) {
|
if let (Some(gotify_url), Some(gotify_token)) = (&config.gotify_url, &config.gotify_token) {
|
||||||
let release = release.clone();
|
let release = release.clone();
|
||||||
let url = gotify_url.clone();
|
let url = gotify_url.clone();
|
||||||
let token = gotify_token.clone();
|
let token = gotify_token.clone();
|
||||||
tasks.push(task::spawn(async move {
|
tasks.push(task::spawn(async move {
|
||||||
github::send_to_gotify(release, &token, &url).await;
|
github::send_to_gotify(release, &token, &url).await;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(discord_url) = &config.discord_webhook_url {
|
if let Some(discord_url) = &config.discord_webhook_url {
|
||||||
let release = release.clone();
|
let release = release.clone();
|
||||||
let url = discord_url.clone();
|
let url = discord_url.clone();
|
||||||
tasks.push(task::spawn(async move {
|
tasks.push(task::spawn(async move {
|
||||||
github::send_to_discord(release, &url).await;
|
github::send_to_discord(release, &url).await;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(slack_url) = &config.slack_webhook_url {
|
if let Some(slack_url) = &config.slack_webhook_url {
|
||||||
let release = release.clone();
|
let release = release.clone();
|
||||||
let url = slack_url.clone();
|
let url = slack_url.clone();
|
||||||
tasks.push(task::spawn(async move {
|
tasks.push(task::spawn(async move {
|
||||||
github::send_to_slack(release, &url).await;
|
github::send_to_slack(release, &url).await;
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
update_version(db_conn, &release.repo, &release.tag_name, Some(release.changelog.as_str()))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create tasks for Docker notifications
|
|
||||||
for release in &docker_releases {
|
for release in &docker_releases {
|
||||||
if let Some(url) = &config.ntfy_url {
|
if is_new_version(db_conn, &release.repo, &release.digest)? {
|
||||||
let release = release.clone();
|
if let Some(url) = &config.ntfy_url {
|
||||||
let auth = config.auth.clone();
|
let release = release.clone();
|
||||||
let url = url.clone();
|
let auth = config.auth.clone();
|
||||||
tasks.push(task::spawn(async move {
|
let url = url.clone();
|
||||||
docker::send_to_ntfy(release, &auth, &url).await;
|
tasks.push(task::spawn(async move {
|
||||||
}));
|
docker::send_to_ntfy(release, &auth, &url).await;
|
||||||
}
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
if let (Some(gotify_url), Some(gotify_token)) = (&config.gotify_url, &config.gotify_token) {
|
if let (Some(gotify_url), Some(gotify_token)) = (&config.gotify_url, &config.gotify_token) {
|
||||||
let release = release.clone();
|
let release = release.clone();
|
||||||
let url = gotify_url.clone();
|
let url = gotify_url.clone();
|
||||||
let token = gotify_token.clone();
|
let token = gotify_token.clone();
|
||||||
tasks.push(task::spawn(async move {
|
tasks.push(task::spawn(async move {
|
||||||
docker::send_to_gotify(release, &token, &url).await;
|
docker::send_to_gotify(release, &token, &url).await;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(discord_url) = &config.discord_webhook_url {
|
if let Some(discord_url) = &config.discord_webhook_url {
|
||||||
let release = release.clone();
|
let release = release.clone();
|
||||||
let url = discord_url.clone();
|
let url = discord_url.clone();
|
||||||
tasks.push(task::spawn(async move {
|
tasks.push(task::spawn(async move {
|
||||||
docker::send_to_discord(release, &url).await;
|
docker::send_to_discord(release, &url).await;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(slack_url) = &config.slack_webhook_url {
|
if let Some(slack_url) = &config.slack_webhook_url {
|
||||||
let release = release.clone();
|
let release = release.clone();
|
||||||
let url = slack_url.clone();
|
let url = slack_url.clone();
|
||||||
tasks.push(task::spawn(async move {
|
tasks.push(task::spawn(async move {
|
||||||
docker::send_to_slack(release, &url).await;
|
docker::send_to_slack(release, &url).await;
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
update_version(db_conn, &release.repo, &release.digest, None)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,4 +104,6 @@ pub async fn send_notifications(
|
|||||||
for task in tasks {
|
for task in tasks {
|
||||||
let _ = task.await;
|
let _ = task.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user