advotracker: restructure project using crate tree

* advotracker: the framework crate
* crate/advotrackerdb: crate implementing the database backend
* crate/advotrackerd: the backend daemon
* crate/adovtracker: the application (CLI and GUI)

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
2021-03-07 18:38:50 +01:00
parent 1ce1d029e5
commit 4c88167bef
185 changed files with 2542983 additions and 0 deletions

4
crates/advotrackerd/.env Normal file
View File

@@ -0,0 +1,4 @@
TEST_LANG=en
RUST_LOG=advotracker=info
DATABASE_URL=./advotracker.sqlite3
#DATABASE_URL=postgres://username:password@localhost/advotracker

10
crates/advotrackerd/.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
# This file should only ignore things that are generated during a build,
# generated by common IDEs, and optional files controlled by the user that
# affect the build (such as config.toml).
.#*
.DS_Store
**/*.rs.bk
Cargo.lock
**/*~
/target/
/config.toml

View File

@@ -0,0 +1,30 @@
[package]
name = "advotrackerd"
version = "0.1.0"
authors = ["Ralf Zerres <ralf.zerres@networkx.de>"]
description = "Supports lawyers to capture relevant data encountered during an online legal advice\n"
readme = "README.md"
license = "(0BSD OR MIT)"
edition = "2018"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winuser"] }
#diesel = { version = "1.4", features = [ "msql", "postgres", "sqlite" ] }
[dependencies]
advotracker_db = { path = "../advotracker-db" }
clap = { version = "~2.33", features = [ "suggestions", "color" ] }
dotenv = { version = "~0.15.0" }
#env_logger = "~0.7.1"
envy = { version = "~0.4" }
locales = { version = "0.1" }
#log = { version = "~0.4.8" }
serde = { version = "~1.0", features = [ "derive" ] }
serde_json = { version = "~1.0" }
tracing = { version = "0.1" }
tracing-subscriber = { version = "0.2.0-alpha", features = ["tracing-log"] }
viperus = { git = "https://github.com/maurocordioli/viperus", features = ["cache", "watch", "fmt-clap", "fmt-env"] }
#[replace]
#"foo:0.1.0" = { git = 'https://github.com/example/foo' }

View File

@@ -0,0 +1,12 @@
Copyright (C) 2019 by Ralf Zerres <ralf.zerres@networkx.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -0,0 +1,19 @@
Copyright (c) 2019 Ralf Zerres <ralf.zerres@networkx.de>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,6 @@
SPDXVersion: SPDX-2.1
DataLicense: CC0-1.0
PackageName: advotracker
PackageOriginator: Ralf Zerres
PackageHomePage: https://github.com/rzerres/advotracker/
PackageLicenseDeclared: MIT, 0BSD

52
crates/advotrackerd/README.md Executable file
View File

@@ -0,0 +1,52 @@
<!-- AdvoTracker.markdown -->
<!-- version: 1.1 -->
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-generate-toc again -->
<!-- markdown-toc end -->
# AdvoTracker - Backend #
AdvoTracker unterstützt Anwälte bei der Erfassung von Mandatsdaten zu einer Online-Beratung.
Dieses crate implementiert das Backend.
Als Programmiersprache wird *Rust* verwendet. Die Implementierung der
GUI Elemente erfolgt mit der Klassenbibliothek *OrbTk*.
Als Dokumentationsquellen wird auf die offiziellen Projektseiten [Rust Book][^1] und [OrbTk][^2] verwiesen.
# Internationalisierung #
AdvoTracker wurde mit Unterstützung der Mehrsprachenfähigkeit implementiert.
Existieren für aktive Umgebung defnierte Sprache (Umgebungsvariable LOCALE) Übersetzungen,
werden diese in allen Dialogen verwendet. Andernfalls erfolgen alle Ausgaben in englischer Sprache
, die als default-Wert (LANG = C) hinterlegt ist.
## Übersetzungen für neue Sprachen ##
### derzeit: crate locales
* Übersetzungen für weiter Sprachen als JSON Dateien
im Unerordner ./locales/*.json
z.B. für Französisch: advotracker_fr.json
### todo: crate fluent
Die zu verwendende Sprache wird aus der in der Umgebungsvariable des Betriebssystems hinterlegten Sprache
ausgewählt.
---
[Logo-CC_BY]: https://i.creativecommons.org/l/by/4.0/88x31.png "Creative Common Logo"
[License-CC_BY]: https://creativecommons.org/licenses/by/4.0/legalcode "Creative Common License"
This work is licensed under a [Creative Common License 4.0][License-CC_BY]
![Creative Common Logo][Logo-CC_BY]
© 2019 Ralf Zerres, Networkx GmbH
---
Foodnotes
[^1]: RUST Book: https://doc.rust-lang.org/book/
[^2]: OrbTK GUI: https://gitlab.redox-os.org/redox-os/orbtk

View 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"
}
}

View File

@@ -0,0 +1,41 @@
name: advotrackerd
version: "1.0"
author: Networkx GmbH <info@networkx.de>
about: capture relevant data encountered during an online legal advice
after_help: in Zusammenarbeit mit HIEDEMANN Rechtsanwälte
args:
- config:
short: c
long: config
value_name: FILE
help: Sets a custom config file
takes_value: true
- dbdriver:
short: D
long: dbdriver
help: Driver used to connect to database
possible_values:
- mysql
- postgres
- sqlite
takes_value: true
- verbose:
short: v
long: verbose
multiple: true
help: Sets the level of verbosity
subcommands:
- config:
about: configure the program environment
version: "0.1.0"
author: Ralf Zerres <ralf.zerres@networkx.de>
value_name: "FILE"
default_value: advotracker.conf
- test:
about: run testing features
version: "0.1.0"
author: Ralf Zerres <ralf.zerres@networkx.de>
args:
- debug:
short: d
help: print debug information

View File

@@ -0,0 +1,327 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2019 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
// module: db
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
//#[cfg(test)]
use diesel::debug_query;
use diesel::dsl::*;
use diesel::prelude::*;
//use diesel::sql_query;
use diesel::sqlite::Sqlite;
use diesel::sqlite::SqliteConnection;
use dotenv::dotenv;
//use serde_derive;
use serde_json;
use std::env;
use std::error::Error;
// modules
pub mod models;
pub mod schema;
pub mod types;
//use crate::db::models::Users;
use crate::db::models::Harm;
use models::User;
use models::UserRole;
use schema::*;
// functions
pub fn establish_connection() -> SqliteConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
SqliteConnection::establish(&database_url)
.unwrap_or_else(|_| panic!("Error connecting to {}", &database_url))
/*
* WIP: integrate tracing!
trace!(
target: "diesel",
type: "Sqlite3",
status: "connected"
);
*/
}
/*
* base functions
pub fn users_insert_default_values(conn: &SqliteConnection) -> QueryResult<usize> {
//use schema::users::dsl::*;
insert_into(users).default_values().execute(conn)
}
#[test]
fn examine_sql_users_insert_default_values() {
use schema::users::dsl::*;
let query = insert_into(users).default_values();
let sql = "INSERT INTO `users` DEFAULT VALUES -- binds: []";
assert_eq!(sql, debug_query::<Sqlite, _>(&query).to_string());
}
pub fn user_roles_insert_default_values(conn: &SqliteConnection) -> QueryResult<usize> {
use schema::user_roles::dsl::*;
insert_into(user_roles).default_values().execute(conn)
}
#[test]
fn examine_sql_user_roles_insert_default_values() {
use schema::user_roles::dsl::*;
let query = insert_into(user_roles).default_values();
let sql = "INSERT INTO `user_roles` DEFAULT VALUES -- binds: []";
assert_eq!(sql, debug_query::<Sqlite, _>(&query).to_string());
}
pub fn user_harms_insert_default_values(conn: &SqliteConnection) -> QueryResult<usize> {
use schema::harms::dsl::*;
insert_into(harms).default_values().execute(conn)
}
#[test]
fn examine_sql_harms_insert_default_values() {
use schema::harms::dsl::*;
let query = insert_into(harms).default_values();
let sql = "INSERT INTO `harms` DEFAULT VALUES -- binds: []";
assert_eq!(sql, debug_query::<Sqlite, _>(&query).to_string());
}
pub fn users_insert_single_column(conn: &SqliteConnection) -> QueryResult<usize> {
use schema::users::dsl::*;
insert_into(users)
.values(alias.eq("Hiedemann"))
.execute(conn)
}
#[test]
fn examine_sql_users_insert_single_column() {
use schema::users::dsl::*;
let query = insert_into(users).values(alias.eq("Hiedemann"));
let sql = "INSERT INTO `users` (`alias`) VALUES (?) \
-- binds: [\"Hiedemann\"]";
assert_eq!(sql, debug_query::<Sqlite, _>(&query).to_string());
}
pub fn users_insert_multiple_columns(conn: &SqliteConnection) -> QueryResult<usize> {
use schema::users::dsl::*;
insert_into(users)
.values((
first_name.eq("Lothar"),
last_name.eq("Schlömer"),
alias.eq("102"),
))
.execute(conn)
}
#[test]
fn examine_sql_user_insert_multiple_columns() {
use models::Users;
//use crate::db::models::Users;
use crate::db::schema::users::dsl::*;
let query = insert_into(users).values((
first_name.eq("Lothar"),
last_name.eq("Schlömer"),
alias.eq("102"),
));
let sql = "INSERT INTO `users` (`first_name`, `last_name`, `alias`) \
VALUES (?, ?, ?) \
-- binds: [\"Lothar\", \"Schlömer\", \"102\"]";
assert_eq!(sql, debug_query::<Sqlite, _>(&query).to_string());
}
pub fn user_insert_struct_via_json(conn: &SqliteConnection) -> Result<(), Box<dyn Error>> {
use models::insert::NewUser;
use schema::users::dsl::*;
let json = r#"{ "alias": "Daniela", "first_name": "Daniela","last_name": "Knocke" }"#;
let user_struct = serde_json::from_str::<NewUser>(json)?;
insert_into(users).values(&user_struct).execute(conn)?;
Ok(())
}
*/
/*
#[test]
fn examine_sql_user_insert_struct_via_json() {
use models::NewUser;
use schema::users::dsl::*;
let json = r#"{ "last_name": "Knocke", "first_name": "Daniela", "alias": "Sekretariat" }"#;
let user_form = serde_json::from_str::<NewUser>(json).unwrap();
let query = insert_into(users).values(&user_form);
let sql = "INSERT INTO `users` (`last_name`, `first_name`, `alias`) \
VALUES (?, ?, ?) \
-- binds: [\"Knocke\", \"Daniela\", \"Sekretariat\"]";
assert_eq!(sql, debug_query::<Sqlite, _>(&query).to_string());
}
*/
/*
pub fn user_insert_struct_json_option(conn: &SqliteConnection) -> Result<(), Box<dyn Error>> {
use models::NewUser;
use schema::users::dsl::*;
let json = r#"{ "alias": "Networkx", "email_confirmed": true,
"email": "support@networkx.de", "first_name": null, "last_name": null }"#; let user_form =
serde_json::from_str::<NewUser>(json)?;
insert_into(users).values(&user_form).execute(conn)?;
Ok(())
}
*/
/*
#[test]
fn examine_sql_user_insert_struct_json_option() {
use schema::users::dsl::*;
use models::NewUser;
let json = r#"{ "alias": "Networkx", "email_confirmed": true, "email": "support@networkx.de", "first_name": null, "last_name": null }"#;
let user_form = serde_json::from_str::<NewUser>(json).unwrap();
let query = insert_into(users).values(&user_form);
let sql = "INSERT INTO `users` (`alias`, `email`, `email_confirmed`) \
VALUES (?, ?, ?) \
-- binds: [\"Networkx\", \"support@networkx.de\", \"$true\"]";
assert_eq!(sql, debug_query::<Sqlite, _>(&query).to_string());
}
*/
// WIP
/*
#[test]
fn examine_sql_users_insert_get_results() {
use diesel::result::Error;
let conn = establish_connection();
conn.test_transaction::<_, Error, _>(|| {
use diesel::select;
use chrono::NaiveDateTime;
use schema::users::dsl::*;
//use schema::users::*;
let now = select(diesel::dsl::now).get_result::<NaiveDateTime>(&conn)?;
let inserted_users = conn.transaction::<_, Error, _>(|| {
let inserted_count = insert_into(users)
.values(&vec![
(id.eq(1), last_name.eq("Hiedemann"), first_name.eq("Eric")),
(id.eq(2), last_name.eq("Schlömer"), first_name.eq("Lothar")),
//(id.eq(1), first_name.eq("Eric"), last_name.eq("Hiedemann"), alias.eq("Eric.Hiedemann")),
//(id.eq(2), first_name.eq("Lothar"), last_name.eq("Schlömer"), alias.eq("othar.Schlömer")),
])
.execute(&conn)?;
/*
Ok(users
.order(id.desc())
.limit(inserted_count as i64)
.load(&conn)?
.into_iter()
.rev()
.collect::<Vec<_>>())
*/
})?;
/*
let expected_users = vec![
User {
id: 1,
last_name: "Hiedemann".into(),
first_name: "Eric".into(),
alias: "Eric.Hiedemann".into(),
email: None,
email_confirmed: false,
password_hash: None,
initials: None,
date_created: now,
date_updated: now,
},
User {
id: 2,
last_name: "Schlömer".into(),
first_name: "Lothar".into(),
alias: "Lothar.Schlömer".into(),
email: None,
email_confirmed: false,
password_hash: None,
initials: None,
date_created: now,
date_updated: now,
},
];
assert_eq!(expected_users, inserted_users);
*/
Ok(())
});
}
*/
/*
pub fn create_numberharm<'a>(connection: &SqliteConnection, NumberHarm: &'a str) {
let numberHarm = models::NewNumberHarm { NumberHarm };
diesel::insert_into(schema::NumberHarm::table)
.values(&numberHarm)
.execute(connection)
.expect("Error inserting new task");
}
*/
/*
pub fn create_userid<'a>(connection: &SqliteConnection, User: &'a str) {
let user = models::NewUser { User };
diesel::insert_into(schema::User::table)
.values(&user)
.execute(connection)
.expect("Error inserting new task");
}
*/
/*
pub fn create_userclaimid<'a>(connection: &SqliteConnection, UserClaim: &'a str) {
let userClaim = models::NewUserClaim { UserClaim };
diesel::insert_into(schema::UserClaim::table)
.values(&userClaim)
.execute(connection)
.expect("Error inserting new task");
}
pub fn create_userrole<'a>(connection: &SqliteConnection, UserRole: &'a str) {
let userRole = models::NewUserRole { UserRole };
diesel::insert_into(schema::UserRole::table)
.values(&userRole)
.execute(connection)
.expect("Error inserting new task");
}
pub fn create_useruserrole<'a>(connection: &SqliteConnection, UserUserRole: &'a str) {
let userUserRole = models::NewUserUserRole { UserUserRole };
diesel::insert_into(schema::UserUserRole::table)
.values(&userUserRole)
.execute(connection)
.expect("Error inserting new task");
}
*/

View File

@@ -0,0 +1,43 @@
/*
* advotracker - Hotline tackingtool for Advocats
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: 0BSD, MIT
*/
#![warn(missing_docs, rust_2018_idioms, rust_2018_compatibility)]
//! advotrackerd: crate documentation
// This function adds two integers (given as arguments) and returns the sum.
//
// # Examples
//
// ```
// assert_eq!(8, advotrackerd::internal_adder(4, 4));
// ```
fn internal_adder(a: i32, b: i32) -> i32 {
a + b
}
/// This function adds two to its argument.
///
/// # Examples
///
/// ```
/// assert_eq!(4, advotrackerd::add_two(2));
/// ```
pub fn add_two(a: i32) -> i32 {
internal_adder(a, 2)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn internal_test() {
assert_eq!(8, internal_adder(4, 4));
}
}

View File

@@ -0,0 +1,213 @@
/* 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)]
/// advotrackerd: the main binary
//use log::info; //substituted with tracing
use dotenv::dotenv;
use locales::t;
use serde::Deserialize;
//use std::{env, process};
use std::env;
//use tracing::{debug, info, instrument, span, Level};
//use tracing::{debug, info, instrument, Level, Metadata, span::{Id, Attributes, Record}, trace};
//use tracing::{debug, instrument, span::*, trace, Level};
use tracing::{debug, trace, Level};
//use diesel::prelude::*;
//use diesel::sqlite::SqliteConnection;
mod parse_args;
#[derive(Deserialize, Debug)]
struct Environment {
test_lang: String,
}
/*
pub struct AdvoTrackerSubscriber;
impl tracing::Subscriber for AdvoTrackerSubscriber{
fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
fn record(&self, _: &Id, _: &Record) {}
fn event(&self, _: &tracing::Event) {}
fn record_follows_from(&self, _: &Id, _: &Id) {}
fn enabled(&self, _: &Metadata) -> bool { false }
fn enter(&self, _: &Id) {}
fn exit(&self, _: &Id) {}
}
impl AdvoTrackerSubscriber {
fn new() -> Self { AdvoTrackerSubscriber }
}
#[instrument]
fn run_subcommand(matches: &ArgMatches) -> Result<(), String> {
//info!("inside run_subcommand");
match matches.subcommand() {
("config", Some(cmd)) => run_config(cmd),
("test", Some(cmd)) => run_test(cmd),
_ => Ok(()),
}
}
fn run_config(matches: &ArgMatches) -> Result<(), String> {
//info!("inside run_config");
let _input = matches.value_of("FILE").unwrap();
Ok(())
}
fn run_test(matches: &ArgMatches) -> Result<(), String> {
//info!("inside run_test");
if let Some(matches) = matches.subcommand_matches("test") {
if matches.is_present("debug") {
println!("test: Printing debug info...");
} else {
println!("test: Printing normally...");
}
}
Ok(())
}
*/
/// `advotrackerd` is the daemon that keeps track of legal mandate data
/// that are backed up in a database.
fn main() -> Result<(), Box<dyn std::error::Error>> {
use parse_args::parse_args;
use tracing_subscriber::fmt;
use viperus::Viperus;
//let advotracker_subscriber = AdvoTrackerSubscriber::new();
//tracing::subscriber::set_global_default(advotracker_subscriber)
// .expect("setting tracing default failed");
// 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, "advotracker_main");
let _enter = span.enter();
let subscriber = fmt::Subscriber::builder()
.with_env_filter("advotracker=trace")
.finish();
// initialize logger
// TODO: exchange with tracing!
//env_logger::init();
//info!("Commencing the proxy!");
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: "advotracker", message = ?res, state = ?state);
//debug!(message = ?res, state = ?state);
trace!(target: "advotracker", 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: "advotracker", "{}", e); }
}
res = t!("parse.environment", lang);
trace!(target: "advotracker", environment = "envy", lang = ?lang);
state = t!("state.finished", lang);
trace!(target: "advotracker", message = ?res, state = ?state);
//debug!(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: "advotracker", process = ?res, state = ?state);
//info!(target: "advotracker", "{}", res);
//debug!(message = ?res, state = ?state);
//info!(target: "advotracker", "parsing commandline args");
let _ = parse_args(&mut v);
state = t!("state.finished", lang);
trace!(target: "advotracker", process = ?res, state = ?state);
//trace!(target: "Viperus", "Config results: {:?}", v);
/*
if verbose > 1 {
for (key, value) in env::vars() {
println!("{}={}", key, value);
}
}
*/
//state = t!("state.finished", lang);
//trace!(target: "advotracker", process = ?res, state = ?state);
//debug!(message = ?res, state = ?state);
/*
// handle subcommands
if let Err(e) = run_subcommand(&matches) {
println!("Subcommand error: {}", e);
process::exit(1);
}
*/
// Starting the program logic
res = t!("main.started", lang);
state = t!("state.started", lang);
//info!(target: "advotracker", "{}", res);
trace!(target: "advotracker", process = ?res, state = ?state);
//use advotracker_backend::*;
//use advotracker_backend::schema::users::dsl::*;
/*
let connection = establish_connection();
trace!(
target: "advotracker",
process = "Sqlite3",
status = "connected",
);
*/
/*
//User::table.load(&connection);
//user::belonging_to(users).load(&connection);
use advotracker_backend::models::*;
let results = users
//.filter(published.eq(true))
.limit(5)
.load::<User>(&connection)
.expect("Error loading users");
println!("Displaying {} users", results.len());
for user in results {
println!("{}", user.user_id);
println!("----------\n");
println!("{}", user.first_name);
println!("{}", user.last_name);
println!("{}", user.alias);
println!("{}", user.email);
}
*/
state = t!("state.finished", lang);
res = t!("main.finished", lang);
//info!(target: "advotracker", "{}", res);
trace!(target: "advotracker", process = ?res, state = ?state);
});
Ok(())
}

View File

@@ -0,0 +1,145 @@
/* advotracker infrastructure.
*
* Copyright 2020 Ralf Zerres <ralf.zerres@networkx.de>
* SPDX-License-Identifier: (0BSD or MIT)
*/
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 tracing::{trace, Level};
use std::env;
if cfg!(feature = "yaml") {
trace!(target:"feature", "Clap feature 'yaml' enabled.");
println!("Using feature yaml.");
}
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("advotrackerd.yml"));
v.add_default("db_driver", String::from("sqlite"));
v.add_default("verbose", 0);
//if cfg!(feature = "fmt-clap") {
println!("With fmt-clap...");
// 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("advotrackerd")
.name(crate_name!())
.version(crate_version!())
.author(crate_authors!())
.about(crate_description!())
.after_help("in Zusammenarbeit mit Hiedemann Rechtsanwälte <info@hiedemann.de>")
.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("Sets a custom config file")
.takes_value(true),
)
.arg(
Arg::with_name("dbdriver")
.short("d")
.long("dbdriver")
.value_name("DatabaseDriver")
.help("Driver used to connect to database")
.possible_values(&["mysql", "postgres", "sqlite"])
.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 ("ADVOTRACKERD_")
//if cfg!(feature = "fmt-clap") {
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"))
);
//v.load_file(".env", v.Format::ENV).unwrap();
// 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);
}
//if cfg!(feature = "fmt-clap") {
// 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("dbdriver", "db_driver");
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!(
"db_driver: {:?}",
v.get::<String>("db_driver").unwrap_or_default()
);
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(())
}

View File

@@ -0,0 +1,7 @@
//use advotracker;
#[test]
fn integration_add_two() {
assert_eq!(4, advotracker_backend::add_two(2));
}