use clap::{App, Arg};
use colored::*;
use hambands::band::types::{Band, Hertz};
use hambands::search::get_band_by_name;
use pad::{Alignment, PadStr};
use rbn_lib::RbnClient;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
fn main() {
let matches = App::new("Reverse Beacon Network Client")
.version("0.1.2")
.author("Evan Pratten <ewpratten@gmail.com>")
.arg(
Arg::with_name("callsign")
.short("c")
.long("callsign")
.takes_value(true)
.help("Your callsign (used to authenticate with RBN)")
.required(true),
)
.arg(
Arg::with_name("filtercall")
.short("f")
.long("filtercall")
.takes_value(true)
.help("Callsign to filter by")
.required(false),
)
.arg(
Arg::with_name("band")
.short("b")
.long("band")
.takes_value(true)
.help("Band name to filter by. This can be used multiple times to filter multiple bands")
.required(false)
.multiple(true),
)
.get_matches();
let callsign = matches.value_of("callsign").unwrap().to_uppercase();
println!("Welcome {}!", callsign.italic().bright_blue());
let has_filtercall = matches.is_present("filtercall");
let mut filtercall = "".to_string();
if has_filtercall {
filtercall = matches.value_of("filtercall").unwrap().to_uppercase();
println!(
"Filtering by callsign: {}",
filtercall.italic().bright_blue()
);
}
let has_band_filter = matches.is_present("band");
let mut band_filter: Vec<&Band> = Vec::new();
if has_band_filter {
for band_name in matches.values_of("band").unwrap().collect::<Vec<_>>() {
let band = get_band_by_name(band_name);
if band.is_ok() {
let band = band.unwrap();
band_filter.push(band);
println!("Adding band filter for: {}", band.name.white().italic());
}
}
}
let running = Arc::new(AtomicBool::new(true));
let running_clone = running.clone();
ctrlc::set_handler(move || {
running_clone.store(false, Ordering::SeqCst);
})
.expect("Error setting Ctrl-C handler");
println!("{}", "Press CTRL+C to stop".bright_black());
let mut rbn = RbnClient::new_default_addr(callsign);
let _thread = rbn.start(Arc::new(move |data| {
if has_filtercall && (data.spotter != filtercall && data.spotted != filtercall) {
return;
}
let frequency: Hertz = (data.frequency * 1000.0) as Hertz;
if has_band_filter {
let mut valid = false;
for band in band_filter.iter() {
if band.low_frequency <= frequency && frequency <= band.high_frequency {
valid = true;
break;
}
}
if !valid {
return;
}
}
println!(
"{} spotted {} on {} KHz",
&data
.spotter
.pad_to_width_with_alignment(8, Alignment::Right)
.green()
.bold(),
&data
.spotted
.pad_to_width_with_alignment(8, Alignment::Right)
.bright_blue()
.bold(),
&data
.frequency
.to_string()
.pad_to_width_with_alignment(10, Alignment::Right)
.white()
.bold()
)
}));
loop {
if !running.load(Ordering::SeqCst) {
break;
}
}
println!("{}", "\nExiting..".bright_black());
}