1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use rusqlite::{
    Rows,
    types::{
        Value,
        Type
    },
};
use horrorshow::{
    helper::doctype,
};
use chrono::offset::Local;
use std::io::prelude::*;
use std::fs::OpenOptions;

use tables::{
    SystemInfoData
};

pub fn map(values: &mut Rows) -> Vec<Vec<String>> {
    let mut table: Vec<Vec<String>> = Vec::new();
    let mut row: Vec<String> = Vec::new();
    loop {
        if let Some(v) = values.next() {
            if let Some(res) = v.ok() {
                for i in 0..res.column_count() {
                    let val = Value::data_type(&res.get(i));
                    match val {
                        Type::Real | Type::Integer => {
                            row.push(res.get::<usize, i64>(i).to_string());
                        },
                        Type::Text => {
                            row.push(res.get::<usize, String>(i))
                        },
                        _ => {
                            // Do nothing.
                        }
                    }
                }
                table.push(row);
                row = Vec::new();
            }
        } else {
            break
        }
    }
    table
}

pub fn print_html(columns: Vec<String>, values: &mut Rows, query: &str) {
    let map = map(values);
    let table_name = query.split(' ').collect::<Vec<&str>>();
    let hostname = format!(
        "{}",
        SystemInfoData::get_specific()
        .get(0)
        .unwrap_or(&SystemInfoData::new()).computer_name
    );
    let html_data = format!(
        "{}",
        html! {
            : doctype::HTML;
            html {
                head {
                    title : hostname.clone();
                }
                body {
                    TABLE(frame="hsides", rules="groups", cellpadding="1") {
                        CAPTION {
                            : format!(
                            "Inventory Report of {} - {}",
                            hostname,
                            Local::now()
                            );
                        }
                        COLGROUP(align="center");
                        COLGROUP(align="left");
                        THEAD(valign="top"){
                            TR{
                                TH(colspan="2"){
                                    : table_name.get(3);
                                }
                            }
                        }
                        THEAD(valign="top"){
                            TR {
                                TH {
                                    :"labels";
                                }
                                TH {
                                    :"values";
                                }
                            }
                        }
                        @ for j in 0..map.len() {
                            TBODY {
                                @ for i in 0..columns.len() {
                                    TR {
                                        TD {
                                            : columns[i].clone();
                                        }
                                        TD {
                                            : map[j][i].clone();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        });
    write_file(html_data).unwrap_or_else(|e| println!("html printer failed with: {}",e));
}

fn write_file (data: String) -> std::io::Result<()> {
    let mut file: std::fs::File = OpenOptions::new().append(true).open("inventory.html")?;
    file.write_all(data.as_bytes())?;
    Ok(())
}