frontend: example: csv-import helper
* cli to import a given csv configured text file Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
58
frontend/examples/csv-import/csv_import.rs
Normal file
58
frontend/examples/csv-import/csv_import.rs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/// Commandline program testing csv imports
|
||||||
|
use log::{info, trace, warn};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
io,
|
||||||
|
process,
|
||||||
|
thread,
|
||||||
|
time::{Duration, Instant}};
|
||||||
|
|
||||||
|
mod parse_args;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Environment {
|
||||||
|
test_lang: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct CsvImportRecord {
|
||||||
|
// dion => Allianz Dion: 1
|
||||||
|
// policy_code => Policy Typ: "AS"
|
||||||
|
// policy_number => Versicherungsscheinnummer: "1515735810"
|
||||||
|
pub dion: String,
|
||||||
|
pub policy_code: String,
|
||||||
|
pub policy_number: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
use parse_args::parse_args;
|
||||||
|
|
||||||
|
use std::net::ToSocketAddrs;
|
||||||
|
use std::process;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use viperus::Viperus;
|
||||||
|
|
||||||
|
// initialize logger
|
||||||
|
env_logger::init();
|
||||||
|
info!("Commencing the proxy!");
|
||||||
|
|
||||||
|
// initialize viperus structure
|
||||||
|
let mut v = Viperus::new();
|
||||||
|
|
||||||
|
// parse commandline arguments
|
||||||
|
info!(target: "csv_import", "parsing commandline args");
|
||||||
|
parse_args(&mut v)?;
|
||||||
|
trace!(target: "Viperus", "Config results: {:?}", v);
|
||||||
|
|
||||||
|
// create a new NextCloudTalk client
|
||||||
|
let config = matches.value_of("config").unwrap_or("advotracker.conf");
|
||||||
|
let csv_import = matches.value_of("import").unwrap_or("allianz.txt");
|
||||||
|
//let username = matches.value_of("username").unwrap_or("nctalkbot");
|
||||||
|
//let password = matches.value_of("password").unwrap_or("botpassword");
|
||||||
|
let verbose = matches.occurrences_of("verbose");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
94
frontend/examples/csv-import/csv_import_bak.rs
Normal file
94
frontend/examples/csv-import/csv_import_bak.rs
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/* advotracker infrastructure.
|
||||||
|
*
|
||||||
|
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
|
||||||
|
* SPDX-License-Identifier: (0BSD or MIT)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Rust nightly supports procedural macros!
|
||||||
|
//#![feature(proc_macro)]
|
||||||
|
//#![deny(rust_2018_idioms)]
|
||||||
|
|
||||||
|
use dotenv::dotenv;
|
||||||
|
use locales::t;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io;
|
||||||
|
use std::process;
|
||||||
|
|
||||||
|
use tracing::{debug, trace, Level};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct Environment {
|
||||||
|
test_lang: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct CsvImportRecord {
|
||||||
|
// dion => Allianz Dion: 1
|
||||||
|
// policy_code => Policy Typ: "AS"
|
||||||
|
// policy_number => Versicherungsscheinnummer: "1515735810"
|
||||||
|
pub dion: String,
|
||||||
|
pub policy_code: String,
|
||||||
|
pub policy_number: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
// the YAML file is found relative to the current file
|
||||||
|
//use clap_v3::{load_yaml, App};
|
||||||
|
use clap::{load_yaml, App};
|
||||||
|
|
||||||
|
let yaml = load_yaml!("cli.yml");
|
||||||
|
//let matches = App::from_yaml(yaml).get_matches();
|
||||||
|
let matches = App::from_yaml(yaml)
|
||||||
|
.name(clap::crate_name!())
|
||||||
|
.version(clap::crate_version!())
|
||||||
|
.author(clap::crate_authors!())
|
||||||
|
.about(clap::crate_description!())
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
// Gets the option value if supplied by user, otherwise set defaults
|
||||||
|
let config = matches.value_of("config").unwrap_or("advotracker.conf");
|
||||||
|
let csv_import = matches.value_of("import").unwrap_or("allianz.txt");
|
||||||
|
//let username = matches.value_of("username").unwrap_or("nctalkbot");
|
||||||
|
//let password = matches.value_of("password").unwrap_or("botpassword");
|
||||||
|
let verbose = matches.occurrences_of("verbose");
|
||||||
|
|
||||||
|
if verbose > 0 {
|
||||||
|
println!("{}: runtime parameters", clap::crate_name!());
|
||||||
|
println!("config_file: '{}'", config);
|
||||||
|
println!("csv_import: '{}'", csv_import);
|
||||||
|
println!("verbosity level: {}", matches.occurrences_of("verbose"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if verbose > 1 {
|
||||||
|
println!("\nEnvironment:");
|
||||||
|
for (key, value) in env::vars() {
|
||||||
|
println!("{}={}", key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// import from csv format (Standard in)
|
||||||
|
fn import() -> Result<(), Box<dyn Error>> {
|
||||||
|
// Build the CSV reader and iterate over each record.
|
||||||
|
let mut csv_reader = csv::Reader::from_reader(io::stdin());
|
||||||
|
for result in csv_reader.deserialize() {
|
||||||
|
// The iterator yields Result<StringRecord, Error>, so we check the
|
||||||
|
// error here.
|
||||||
|
let record: CsvImportRecord = result?;
|
||||||
|
println!("{:?}", record);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if let Err(err) = import() {
|
||||||
|
println!("error running CSV-Import: {}", err);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
78
frontend/examples/csv-import/locales/main.json
Normal file
78
frontend/examples/csv-import/locales/main.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"err.lang.not_found": {
|
||||||
|
"de_DE.UTF-8": "Konnte Sprachkode nicht auslesen",
|
||||||
|
"de": "Konnte Sprachkode nicht auslesen",
|
||||||
|
"en": "Couldn't read LANG"
|
||||||
|
},
|
||||||
|
"err.user.not_found": {
|
||||||
|
"fr": "Utilisateur introuvable: $email, $id",
|
||||||
|
"de-DE.UTF-8": "Anwender nicht gefunden: $email, $id",
|
||||||
|
"de": "Anwender nicht gefunden: $email, $id",
|
||||||
|
"en": "User not found: $email, $id"
|
||||||
|
},
|
||||||
|
"main.started": {
|
||||||
|
"de_DE.UTF-8": "Programmlogik starten",
|
||||||
|
"de": "Programmlogik starten",
|
||||||
|
"en": "Program logic started"
|
||||||
|
},
|
||||||
|
"main.finished": {
|
||||||
|
"de_DE.UTF-8": "Programmlogik beendet",
|
||||||
|
"de": "Programmlogik beendet",
|
||||||
|
"en": "Program logic finished"
|
||||||
|
},
|
||||||
|
"parse.arguments": {
|
||||||
|
"de_DE.UTF-8": "Programmargumente prüfen",
|
||||||
|
"de": "Programmargumente prüfen",
|
||||||
|
"en": "Parsing arguments"
|
||||||
|
},
|
||||||
|
"parse.environment": {
|
||||||
|
"de_DE.UTF-8": "Umgebungsvariablen prüfen",
|
||||||
|
"de": "Umgebungsvariablen prüfen",
|
||||||
|
"en": "Parsing environment"
|
||||||
|
},
|
||||||
|
"parse.results": {
|
||||||
|
"de_DE.UTF-8": "Ergebnisse der Konfigurations-Parameterprüfung",
|
||||||
|
"de": "Ergebnisse der Konfigurationsparameterprüfung",
|
||||||
|
"en": "Config parsing results"
|
||||||
|
},
|
||||||
|
"config.name": {
|
||||||
|
"de_DE.UTF-8": "Konfigurationswert für",
|
||||||
|
"de": "Konfigurationswert für",
|
||||||
|
"en": "Config Value for"
|
||||||
|
},
|
||||||
|
"config.name.lang": {
|
||||||
|
"de_DE.UTF-8": "Sprach-Code",
|
||||||
|
"de": "Sprach-Code",
|
||||||
|
"en": "Language code"
|
||||||
|
},
|
||||||
|
"config.name.verbositylevel": {
|
||||||
|
"de_DE.UTF-8": "Ausgabe-Ebene",
|
||||||
|
"de": "Ausgabe-Ebene",
|
||||||
|
"en": "verbosity level"
|
||||||
|
},
|
||||||
|
"config.name.environment": {
|
||||||
|
"de_DE.UTF-8": "Umgebungsvariablen",
|
||||||
|
"de": "Umgebungsvariablen",
|
||||||
|
"en": "environment"
|
||||||
|
},
|
||||||
|
"config.name.configfile": {
|
||||||
|
"de_DE.UTF-8": "Konfigurations-Datei",
|
||||||
|
"de": "Konfigurations-Datei",
|
||||||
|
"en": "config file"
|
||||||
|
},
|
||||||
|
"config.name.dbdriver": {
|
||||||
|
"de_DE.UTF-8": "Datenbank-Treiber",
|
||||||
|
"de": "Datenbank-Treiber",
|
||||||
|
"en": "database driver"
|
||||||
|
},
|
||||||
|
"state.started": {
|
||||||
|
"de_DE.UTF-8": "gestartet",
|
||||||
|
"de": "gestartet",
|
||||||
|
"en": "started"
|
||||||
|
},
|
||||||
|
"state.finished": {
|
||||||
|
"de_DE.UTF-8": "beendet",
|
||||||
|
"de": "beended",
|
||||||
|
"en": "finished"
|
||||||
|
}
|
||||||
|
}
|
||||||
114
frontend/examples/csv-import/main.rs
Normal file
114
frontend/examples/csv-import/main.rs
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/// Commandline program testing csv imports
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::env;
|
||||||
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
io,
|
||||||
|
// process,
|
||||||
|
// thread,
|
||||||
|
// time::{Duration, Instant}
|
||||||
|
};
|
||||||
|
use tracing::{debug, trace, Level};
|
||||||
|
|
||||||
|
mod parse_args;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Environment {
|
||||||
|
test_lang: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct CsvImportRecord {
|
||||||
|
// dion => Allianz Dion: 1
|
||||||
|
// policy_code => Policy Typ: "AS"
|
||||||
|
// policy_number => Versicherungsscheinnummer: "1515735810"
|
||||||
|
pub dion: String,
|
||||||
|
pub policy_code: String,
|
||||||
|
pub policy_number: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// import from csv format (Standard in)
|
||||||
|
fn import() -> Result<(), Box<dyn Error>> {
|
||||||
|
// Build the CSV reader and iterate over each record.
|
||||||
|
let mut csv_reader = csv::Reader::from_reader(io::stdin());
|
||||||
|
for result in csv_reader.deserialize() {
|
||||||
|
// The iterator yields Result<StringRecord, Error>, so we check the
|
||||||
|
// error here.
|
||||||
|
let record: CsvImportRecord = result?;
|
||||||
|
println!("{:?}", record);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
use dotenv::dotenv;
|
||||||
|
use parse_args::parse_args;
|
||||||
|
use locales::t;
|
||||||
|
//use std::process;
|
||||||
|
//use std::sync::Arc;
|
||||||
|
use tracing_subscriber::fmt;
|
||||||
|
use viperus::Viperus;
|
||||||
|
|
||||||
|
// initialize the tracing subsystem
|
||||||
|
// a drop in replacement for classical logging
|
||||||
|
// reference: https://tokio.rs/blog/2019-08-tracing/
|
||||||
|
let span = tracing::span!(Level::TRACE, "csv-import");
|
||||||
|
let _enter = span.enter();
|
||||||
|
let subscriber = fmt::Subscriber::builder()
|
||||||
|
.with_env_filter("csv-import=trace")
|
||||||
|
.finish();
|
||||||
|
|
||||||
|
// initialize logger
|
||||||
|
//env_logger::init();
|
||||||
|
//info!("Commencing the import Test-Run!");
|
||||||
|
|
||||||
|
tracing::subscriber::with_default(subscriber, || {
|
||||||
|
// get system environment
|
||||||
|
let mut lang = env::var("LANG").unwrap_or("en".to_string());
|
||||||
|
let mut res = t!("parse.environment", lang);
|
||||||
|
let mut state = t!("state.started", lang);
|
||||||
|
trace!(target: "csv-import", message = ?res, state = ?state);
|
||||||
|
//debug!(message = ?res, state = ?state);
|
||||||
|
trace!(target: "csv-import", environment = "system", lang = ?lang);
|
||||||
|
|
||||||
|
// get testing environment (.env)
|
||||||
|
dotenv().ok();
|
||||||
|
match envy::from_env::<Environment>() {
|
||||||
|
Ok(environment) => {
|
||||||
|
if environment.test_lang != lang { lang = environment.test_lang; }
|
||||||
|
},
|
||||||
|
Err(e) => { debug!(target: "csv-import", "{}", e); }
|
||||||
|
}
|
||||||
|
res = t!("parse.environment", lang);
|
||||||
|
trace!(target: "csv-import", environment = "envy", lang = ?lang);
|
||||||
|
state = t!("state.finished", lang);
|
||||||
|
trace!(target: "csv-import", message = ?res, state = ?state);
|
||||||
|
|
||||||
|
// initialize viperus structure
|
||||||
|
let mut v = Viperus::new();
|
||||||
|
|
||||||
|
// parse commandline arguments
|
||||||
|
res = t!("parse.arguments", lang);
|
||||||
|
state = t!("state.started", lang);
|
||||||
|
trace!(target: "csv-import", process = ?res, state = ?state);
|
||||||
|
|
||||||
|
let _ = parse_args(&mut v);
|
||||||
|
state = t!("state.finished", lang);
|
||||||
|
trace!(target: "csv-import", process = ?res, state = ?state);
|
||||||
|
//trace!(target: "Viperus", "Config results: {:?}", v);
|
||||||
|
|
||||||
|
// Starting the program logic
|
||||||
|
res = t!("main.started", lang);
|
||||||
|
state = t!("state.started", lang);
|
||||||
|
trace!(target: "csv-import", process = ?res, state = ?state);
|
||||||
|
|
||||||
|
// import the given import file
|
||||||
|
let csv_file = v.get::<String>("import_file").unwrap();
|
||||||
|
|
||||||
|
state = t!("state.finished", lang);
|
||||||
|
res = t!("main.finished", lang);
|
||||||
|
trace!(target: "csv-import", process = ?res, state = ?state);
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
151
frontend/examples/csv-import/parse_args.rs
Normal file
151
frontend/examples/csv-import/parse_args.rs
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
use viperus::Viperus;
|
||||||
|
|
||||||
|
/// The given Viperus structure will be muted according to the
|
||||||
|
/// processed default, environment and commandline arguments
|
||||||
|
pub fn parse_args(v: &mut Viperus) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
//use log::{debug, info, trace, warn};
|
||||||
|
use log::trace;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
if cfg!(feature = "fmt-clap") {
|
||||||
|
trace!(target: "Viperus", "Viperus feature 'fmt-clap' enabled.");
|
||||||
|
println!("Using feature fmt-clap");
|
||||||
|
}
|
||||||
|
|
||||||
|
// preset default key/value pairs (lowest priority)
|
||||||
|
v.add_default("config_file", String::from("csv_import.ron"));
|
||||||
|
v.add_default("import_file", String::from("allianz.txt"));
|
||||||
|
//v.add_default("username", String::from("nctalkbot"));
|
||||||
|
//v.add_default("password", String::from("botpassword"));
|
||||||
|
v.add_default("verbose", 0);
|
||||||
|
|
||||||
|
// parse CLI commandline arguments with clap
|
||||||
|
use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg};
|
||||||
|
|
||||||
|
// CLI arguments are defined inline
|
||||||
|
let matches = App::new("nctalkproxyd")
|
||||||
|
.name(crate_name!())
|
||||||
|
.version(crate_version!())
|
||||||
|
.author(crate_authors!())
|
||||||
|
.about(crate_description!())
|
||||||
|
.after_help("Test: Versicherungsnummern-Import Allianz DirectCall")
|
||||||
|
.template(
|
||||||
|
"\
|
||||||
|
{bin} v{version}
|
||||||
|
{about}
|
||||||
|
|
||||||
|
{all-args}
|
||||||
|
|
||||||
|
(C) 2020 {author}
|
||||||
|
{after-help}",
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("configFile")
|
||||||
|
.short("c")
|
||||||
|
.long("configFile")
|
||||||
|
.value_name("FILE")
|
||||||
|
.help("Select a config file")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("importFile")
|
||||||
|
.short("i")
|
||||||
|
.long("importFile")
|
||||||
|
//.value_name("FILE")
|
||||||
|
.help("Select source file for the csv-import")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
// .arg(
|
||||||
|
// Arg::with_name("username")
|
||||||
|
// .short("u")
|
||||||
|
// .long("username")
|
||||||
|
// .help("Sets username")
|
||||||
|
// .takes_value(true),
|
||||||
|
// )
|
||||||
|
// .arg(
|
||||||
|
// Arg::with_name("password")
|
||||||
|
// .short("P")
|
||||||
|
// .long("password")
|
||||||
|
// .help("Sets password")
|
||||||
|
// .takes_value(true),
|
||||||
|
// )
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("verbose")
|
||||||
|
.short("v")
|
||||||
|
.long("verbose")
|
||||||
|
.help("Sets verbosity level")
|
||||||
|
.multiple(true),
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
if matches.occurrences_of("verbose") > 0 {
|
||||||
|
// clap is using i64, viperus i32
|
||||||
|
let n = matches.occurrences_of("verbose") as i32;
|
||||||
|
v.add("verbose", n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// preset the prefix for relevant environment variables ("ADVOTRACKER_")
|
||||||
|
let mut env_prefix: String = crate_name!().to_uppercase();
|
||||||
|
env_prefix.push_str("_");
|
||||||
|
v.set_env_prefix(&env_prefix);
|
||||||
|
|
||||||
|
// respect dotenv environment (e.g for testing)
|
||||||
|
// -> overwrites the preset default values
|
||||||
|
println!(
|
||||||
|
"RUST_LOG={}",
|
||||||
|
dotenv::var("RUST_LOG").unwrap_or_else(|_| String::from("None"))
|
||||||
|
);
|
||||||
|
|
||||||
|
// enable caching and automatic update of environment values
|
||||||
|
if cfg!(feature = "fmt-cache") {
|
||||||
|
v.cache(true);
|
||||||
|
}
|
||||||
|
if cfg!(feature = "fmt-env") {
|
||||||
|
v.automatic_env(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load user selected call arguments
|
||||||
|
// -> overwrites values given via environment variables
|
||||||
|
v.load_clap(matches)?;
|
||||||
|
|
||||||
|
// bond the clap names to camel_case rust variable names
|
||||||
|
v.bond_clap("configFile", "config_file");
|
||||||
|
v.bond_clap("importFile", "import_file");
|
||||||
|
//v.bond_clap("username", "username");
|
||||||
|
//v.bond_clap("password", "password");
|
||||||
|
v.bond_clap("verbose", "verbose");
|
||||||
|
|
||||||
|
trace!("verbose {:?}", v.get::<i32>("verbose").unwrap());
|
||||||
|
if v.get::<i32>("verbose").unwrap() > 0 {
|
||||||
|
println!(
|
||||||
|
"config_file: {:?}",
|
||||||
|
v.get::<String>("config_file").unwrap_or_default()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"import_file: {:?}",
|
||||||
|
v.get::<String>("import_file").unwrap_or_default()
|
||||||
|
);
|
||||||
|
// println!(
|
||||||
|
// "username: {:?}",
|
||||||
|
// v.get::<String>("username").unwrap_or_default()
|
||||||
|
// );
|
||||||
|
// println!(
|
||||||
|
// "password: {:?}",
|
||||||
|
// v.get::<String>("password").unwrap_or_default()
|
||||||
|
// ); // only for testing now
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"verbosity level: {:?}",
|
||||||
|
v.get::<i32>("verbose").unwrap_or_default()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.get::<i32>("verbose").unwrap() > 1 {
|
||||||
|
println!("\nEnvironment:");
|
||||||
|
for (key, value) in env::vars() {
|
||||||
|
println!("{}={}", key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user