Connect db_activity to notification system
This commit is contained in:
26
modules/harness/activity-ping-once.lua
Normal file
26
modules/harness/activity-ping-once.lua
Normal file
@@ -0,0 +1,26 @@
|
||||
-- Description: Log some dummy activity
|
||||
-- Version: 0.1.0
|
||||
-- License: GPL-3.0
|
||||
|
||||
function run()
|
||||
local uniq = getopt('uniq')
|
||||
local topic = getopt('topic') or 'harness/activity-ping:dummy'
|
||||
|
||||
if getopt('gps') then
|
||||
lat=1.23
|
||||
lon=4.56
|
||||
radius=100
|
||||
end
|
||||
|
||||
db_activity({
|
||||
topic=topic,
|
||||
time=sn0int_time(),
|
||||
uniq=uniq,
|
||||
latitude=lat,
|
||||
longitude=lon,
|
||||
radius=radius,
|
||||
content={
|
||||
msg='ohai',
|
||||
},
|
||||
})
|
||||
end
|
||||
@@ -65,9 +65,7 @@ fn print_summary(module: &Module, sent: usize, errors: usize) {
|
||||
}
|
||||
|
||||
fn send(args: SendArgs, rl: &mut Shell) -> Result<()> {
|
||||
let config = rl.config().notifications.clone();
|
||||
let workspace = rl.workspace().to_string();
|
||||
notify::run_router(rl, args.dry_run, &config, &workspace, &args.topic, &args.notification)?;
|
||||
notify::run_router(rl, &mut term::Term, args.dry_run, &args.topic, &args.notification)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::cmd::run_cmd::Params;
|
||||
use crate::engine::Module;
|
||||
use crate::options;
|
||||
use crate::shell::Shell;
|
||||
use crate::term;
|
||||
use crate::term::SpinLogger;
|
||||
use crate::worker;
|
||||
use serde::de::{self, Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
@@ -111,6 +111,10 @@ impl NotificationConfig {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trigger_notify_event<T: SpinLogger>(rl: &mut Shell, spinner: &mut T, topic: &str, notification: &Notification) -> Result<()> {
|
||||
run_router(rl, spinner, false, topic, notification)
|
||||
}
|
||||
|
||||
fn prepare_arg(notification: &Notification) -> Result<(serde_json::Value, Option<String>, Vec<Blob>)> {
|
||||
let arg = serde_json::to_value(notification)?;
|
||||
Ok((arg, None, vec![]))
|
||||
@@ -141,25 +145,27 @@ pub fn exec(rl: &mut Shell, module: &Module, options: HashMap<String, String>, n
|
||||
Ok(errors)
|
||||
}
|
||||
|
||||
pub fn run_router(rl: &mut Shell, dry_run: bool, configs: &HashMap<String, NotificationConfig>, workspace: &str, topic: &str, notification: &Notification) -> Result<()> {
|
||||
pub fn run_router<T: SpinLogger>(rl: &mut Shell, spinner: &mut T, dry_run: bool, topic: &str, notification: &Notification) -> Result<()> {
|
||||
let configs = rl.config().notifications.clone();
|
||||
|
||||
for (name, config) in configs {
|
||||
if config.matches(workspace, topic) {
|
||||
if config.matches(rl.workspace(), topic) {
|
||||
let module = rl.library().get(&config.script)?.clone();
|
||||
if dry_run {
|
||||
term::info(&format!("Executed {} {:?} (dry-run)", module.canonical(), name));
|
||||
spinner.success(&format!("Executed {} {:?} (dry-run)", module.canonical(), name));
|
||||
} else {
|
||||
let options = options::Opt::collect(&config.options);
|
||||
match exec(rl, &module, options, notification) {
|
||||
Ok(0) => {
|
||||
let msg = format!("Executed {} {:?}", module.canonical(), name);
|
||||
term::info(&msg);
|
||||
spinner.success(&msg);
|
||||
},
|
||||
Ok(errors) => {
|
||||
let msg = format!("Executed {} {:?} ({} errors)", module.canonical(), name, errors);
|
||||
term::error(&msg);
|
||||
spinner.error(&msg);
|
||||
},
|
||||
Err(err) => {
|
||||
term::error(&format!("Fatal {} {:?}: {}", module.canonical(), name, err));
|
||||
spinner.error(&format!("Fatal {} {:?}: {}", module.canonical(), name, err));
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -168,7 +174,6 @@ pub fn run_router(rl: &mut Shell, dry_run: bool, configs: &HashMap<String, Notif
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
38
src/term.rs
38
src/term.rs
@@ -221,6 +221,44 @@ pub fn error(line: &str) {
|
||||
eprintln!("\x1b[1m[\x1b[31m{}\x1b[0;1m]\x1b[0m {}", '-', line);
|
||||
}
|
||||
|
||||
pub struct Term;
|
||||
|
||||
impl SpinLogger for Term {
|
||||
fn log(&mut self, line: &str) {
|
||||
success(line)
|
||||
}
|
||||
|
||||
fn debug(&mut self, line: &str) {
|
||||
debug(line)
|
||||
}
|
||||
|
||||
fn success(&mut self, line: &str) {
|
||||
info(line)
|
||||
}
|
||||
|
||||
fn error(&mut self, line: &str) {
|
||||
error(line)
|
||||
}
|
||||
|
||||
fn warn(&mut self, line: &str) {
|
||||
warn(line)
|
||||
}
|
||||
|
||||
fn warn_once(&mut self, _line: &str) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn status(&mut self, _status: String) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn stacked_status(&mut self, _name: &String, _status: String) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Prompt {
|
||||
pub workspace: String,
|
||||
pub module: Option<Module>,
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::engine::Module;
|
||||
use crate::ipc;
|
||||
use crate::ipc::parent::IpcParent;
|
||||
use crate::models::*;
|
||||
use crate::notify::{self, Notification};
|
||||
use serde_json;
|
||||
use crate::ratelimits::{Ratelimiter, RatelimitResponse};
|
||||
use crate::shell::Shell;
|
||||
@@ -231,32 +232,52 @@ impl DatabaseEvent {
|
||||
tx.send(result).expect("Failed to send db result to channel");
|
||||
}
|
||||
|
||||
pub fn activity<T: SpinLogger>(object: NewActivity, tx: DbSender, spinner: &mut T, db: &Database, verbose: u64) {
|
||||
fn spinner_log_new_activity<T: SpinLogger>(object: &NewActivity, spinner: &mut T, verbose: u64) {
|
||||
let mut log = format!("{:?} ", object.topic);
|
||||
if let Some(uniq) = &object.uniq {
|
||||
log.push_str(&format!("({:?}) ", uniq));
|
||||
}
|
||||
log.push_str(&format!("@ {}", object.time));
|
||||
|
||||
if let (Some(ref lat), Some(ref lon)) = (object.latitude, object.longitude) {
|
||||
log.push_str(&format!(" ({}, {}", lat, lon));
|
||||
if let Some(radius) = &object.radius {
|
||||
log.push_str(&format!(" | {}m", radius));
|
||||
}
|
||||
log.push_str(")");
|
||||
}
|
||||
|
||||
if verbose > 0 {
|
||||
log.push_str(&format!(": {}", object.content));
|
||||
}
|
||||
|
||||
spinner.log(&log);
|
||||
}
|
||||
|
||||
pub fn activity<T: SpinLogger>(rl: &mut Shell, object: NewActivity, tx: DbSender, spinner: &mut T, verbose: u64) {
|
||||
let db = rl.db();
|
||||
let result = db.insert_activity(object.clone());
|
||||
debug!("{:?} => {:?}", object, result);
|
||||
|
||||
let result = match result {
|
||||
Ok(true) => {
|
||||
let mut log = format!("{:?} ", object.topic);
|
||||
Self::spinner_log_new_activity(&object, spinner, verbose);
|
||||
// TODO: we don't want to copy the match arms everywhere
|
||||
let topic = format!("activity:{}", object.topic);
|
||||
let mut subject = format!("New activity: {:?}", object.topic);
|
||||
if let Some(uniq) = &object.uniq {
|
||||
log.push_str(&format!("({:?}) ", uniq));
|
||||
subject += &format!(" ({:?})", uniq);
|
||||
}
|
||||
log.push_str(&format!("@ {}", object.time));
|
||||
|
||||
if let (Some(ref lat), Some(ref lon)) = (object.latitude, object.longitude) {
|
||||
log.push_str(&format!(" ({}, {}", lat, lon));
|
||||
if let Some(radius) = &object.radius {
|
||||
log.push_str(&format!(" | {}m", radius));
|
||||
}
|
||||
log.push_str(")");
|
||||
if let Err(err) = notify::trigger_notify_event(rl, spinner, &topic, &Notification {
|
||||
subject,
|
||||
body: None,
|
||||
}) {
|
||||
let err = err.to_string();
|
||||
spinner.error(&format!("Failed to send notifications: {}", err));
|
||||
Err(err)
|
||||
} else {
|
||||
Ok(DatabaseResponse::Inserted(0))
|
||||
}
|
||||
|
||||
if verbose > 0 {
|
||||
log.push_str(&format!(": {}", object.content));
|
||||
}
|
||||
|
||||
spinner.log(&log);
|
||||
Ok(DatabaseResponse::Inserted(0))
|
||||
},
|
||||
Ok(false) => Ok(DatabaseResponse::NoChange(0)),
|
||||
Err(err) => {
|
||||
@@ -269,11 +290,12 @@ impl DatabaseEvent {
|
||||
tx.send(result).expect("Failed to send db result to channel");
|
||||
}
|
||||
|
||||
pub fn apply<T: SpinLogger>(self, tx: DbSender, spinner: &mut T, db: &Database, verbose: u64) {
|
||||
pub fn apply<T: SpinLogger>(self, rl: &mut Shell, tx: DbSender, spinner: &mut T, verbose: u64) {
|
||||
let db = rl.db();
|
||||
match self {
|
||||
DatabaseEvent::Insert(object) => Self::insert(object, None, tx, spinner, db, verbose),
|
||||
DatabaseEvent::InsertTtl((object, ttl)) => Self::insert(object, Some(ttl), tx, spinner, db, verbose),
|
||||
DatabaseEvent::Activity(object) => Self::activity(object, tx, spinner, db, verbose),
|
||||
DatabaseEvent::Activity(object) => Self::activity(rl, object, tx, spinner, verbose),
|
||||
DatabaseEvent::Select((family, value)) => {
|
||||
let result = match db.get_opt(&family, &value) {
|
||||
Ok(Some(id)) => Ok(DatabaseResponse::Found(id)),
|
||||
@@ -443,7 +465,7 @@ pub fn spawn(rl: &mut Shell, module: &Module, args: Vec<(serde_json::Value, Opti
|
||||
stack.add(name, label);
|
||||
},
|
||||
Event2::Log(log) => log.apply(&mut stack.prefixed(name)),
|
||||
Event2::Database((db, tx)) => db.apply(tx, &mut stack.prefixed(name), rl.db(), verbose),
|
||||
Event2::Database((db, tx)) => db.apply(rl, tx, &mut stack.prefixed(name), verbose),
|
||||
Event2::Ratelimit((req, tx)) => ratelimit.pass(tx, &req.key, req.passes, req.time),
|
||||
Event2::Blob((blob, tx)) => rl.store_blob(tx, &blob),
|
||||
Event2::Exit(event) => {
|
||||
|
||||
Reference in New Issue
Block a user