From eca90a051b4daebe12a8421c6c4f57d5b5b9fbbd Mon Sep 17 00:00:00 2001 From: Till Höppner Date: Wed, 9 Mar 2016 16:59:15 +0100 Subject: Allow ARM failure --- cli/Cargo.toml | 7 ++++ cli/build.rs | 15 +++++++ cli/src/lib.rs | 120 ++++++++++++++++++++++--------------------------------- cli/src/stats.rs | 73 +++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 73 deletions(-) create mode 100644 cli/build.rs create mode 100644 cli/src/stats.rs (limited to 'cli') diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 8e66b7e..e958ef5 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -6,6 +6,7 @@ homepage = "https://github.com/tilpner/ilc" license = "Apache-2.0" repository = "https://github.com/tilpner/ilc" authors = ["Till Höppner "] +build = "build.rs" [features] default = ["ilc-format-weechat", "ilc-format-energymech"] @@ -14,9 +15,15 @@ default = ["ilc-format-weechat", "ilc-format-energymech"] log = "0.3.5" clap = "2.1.2" chrono = "0.2.19" +serde = "~0.7" +serde_json = "~0.7" env_logger = "0.3.2" glob = "0.2.10" ilc-base = "~0.2" ilc-ops = "~0.1" ilc-format-weechat = { optional = true, version = "~0.2" } ilc-format-energymech = { optional = true, version = "~0.2" } +includedir = "~0.2" + +[build-dependencies] +includedir_codegen = "~0.2" diff --git a/cli/build.rs b/cli/build.rs new file mode 100644 index 0000000..e83c21a --- /dev/null +++ b/cli/build.rs @@ -0,0 +1,15 @@ +extern crate includedir_codegen; + +use std::env; + +use includedir_codegen::Compression; + +fn main() { + let mut cg = includedir_codegen::start("FILES"); + if env::var("PASSTHROUGH").is_ok() { + cg.passthrough(); + } + cg.dir("../templates", Compression::Gzip) + .build("data.rs") + .unwrap(); +} diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 9469cfb..ba7f792 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -1,17 +1,3 @@ -// Copyright 2015 Till Höppner -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - extern crate ilc_base; extern crate ilc_ops; extern crate ilc_format_weechat; @@ -22,10 +8,11 @@ extern crate clap; #[macro_use] extern crate log; extern crate env_logger; +extern crate serde; +extern crate serde_json; extern crate glob; use ilc_base::{Context, Decode, Encode}; -use ilc_ops::*; use ilc_format_weechat::Weechat; use ilc_format_energymech::Energymech; @@ -40,19 +27,26 @@ use std::fs::File; use std::path::{Path, PathBuf}; use std::ffi::OsStr; use std::io::{self, BufRead, BufReader, BufWriter, Write}; -use std::{process, usize}; +use std::process; use std::error::Error; mod chain; +mod stats; + +pub struct Cli { + pub version: String, + pub master_hash: String, +} -pub fn main() { +pub fn main(cli: Cli) { env_logger::init().unwrap(); if option_env!("FUSE").is_some() { info!("Compiled with FUSEs") } + let version = format!("{} ({})", cli.version, cli.master_hash); let args = App::new("ilc") - .version(crate_version!()) + .version(&version[..]) .setting(AppSettings::GlobalVersion) .setting(AppSettings::VersionlessSubcommands) .setting(AppSettings::ArgRequiredElseHelp) @@ -115,12 +109,12 @@ pub fn main() { .about("Parse the input, checking the format")) .subcommand(SubCommand::with_name("convert") .about("Convert from a source to a target format")) - .subcommand(SubCommand::with_name("freq") + .subcommand(SubCommand::with_name("stats") .about("Analyse the activity of users by certain metrics") - .arg(Arg::with_name("count") + /*.arg(Arg::with_name("count") .help("The number of items to be displayed") .takes_value(true) - .long("count"))) + .long("count"))*/) .subcommand(SubCommand::with_name("seen") .about("Print the last line a nick was active") .arg(Arg::with_name("nick") @@ -139,68 +133,61 @@ pub fn main() { let res = match args.subcommand() { ("parse", Some(args)) => { let e = Environment(&args); - parse::parse(&e.context(), &mut e.input(), &mut *e.decoder()) + ilc_ops::parse::parse(&e.context(), &mut e.input(), &mut *e.decoder()) } ("convert", Some(args)) => { let e = Environment(&args); - convert::convert(&e.context(), - &mut e.input(), - &mut *e.decoder(), - &mut *e.output(), - &*e.encoder()) + ilc_ops::convert::convert(&e.context(), + &mut e.input(), + &mut *e.decoder(), + &mut *e.output(), + &*e.encoder()) } - ("freq", Some(args)) => { + ("stats", Some(args)) => { let e = Environment(&args); - let count = value_t!(args, "count", usize).unwrap_or(usize::MAX); - freq::freq(count, - &e.context(), - &mut e.input(), - &mut *e.decoder(), - &mut e.output()) + let stats = ilc_ops::stats::stats(&e.context(), &mut e.input(), &mut *e.decoder()) + .unwrap_or_else(|e| error(Box::new(e))); + + stats::output_as_json(&args, &cli, stats) } ("seen", Some(args)) => { let e = Environment(&args); let nick = args.value_of("nick").expect("Required argument not present"); - seen::seen(nick, - &e.context(), - &mut e.input(), - &mut *e.decoder(), - &mut *e.output(), - &Weechat) + ilc_ops::seen::seen(nick, + &e.context(), + &mut e.input(), + &mut *e.decoder(), + &mut *e.output(), + &Weechat) } ("sort", Some(args)) => { let e = Environment(&args); - sort::sort(&e.context(), - &mut e.input(), - &mut *e.decoder(), - &mut *e.output(), - &*e.encoder()) + ilc_ops::sort::sort(&e.context(), + &mut e.input(), + &mut *e.decoder(), + &mut *e.output(), + &*e.encoder()) } ("dedup", Some(args)) => { let e = Environment(&args); - dedup::dedup(&e.context(), - &mut e.input(), - &mut *e.decoder(), - &mut *e.output(), - &*e.encoder()) + ilc_ops::dedup::dedup(&e.context(), + &mut e.input(), + &mut *e.decoder(), + &mut *e.output(), + &*e.encoder()) } ("merge", Some(args)) => { let e = Environment(&args); let mut inputs = e.inputs(); - // let mut decoders = e.decoders(); - let borrowed_inputs = inputs.iter_mut() .map(|a| a as &mut BufRead) .collect(); - // let borrowed_decoders = decoders.iter_mut() - // .map(|a| &mut **a as &mut Decode) - // .collect(); - merge::merge(&e.context(), - borrowed_inputs, - &mut *e.decoder(), - &mut *e.output(), - &*e.encoder()) + ilc_ops::merge::merge(&e.context(), + borrowed_inputs, + &mut *e.decoder(), + &mut *e.output(), + &*e.encoder()) } (sc, _) if !sc.is_empty() => panic!("Unimplemented subcommand `{}`, this is a bug", sc), _ => die("No command specified"), @@ -302,19 +289,6 @@ impl<'a> Environment<'a> { force_decoder(self.0.value_of("format").or(self.0.value_of("input_format"))) } - /* pub fn decoders(&self) -> Vec> { - * self.0 - * .value_of("format") - * .into_iter() - * .chain(self.0 - * .values_of("input_formats") - * .map(|i| Box::new(i) as Box>) - * .unwrap_or(Box::new(iter::empty()) as Box>)) - * .map(Option::Some) - * .map(force_decoder) - * .collect() - * } */ - pub fn encoder(&self) -> Box { force_encoder(self.0.value_of("format").or(self.0.value_of("output_format"))) } diff --git a/cli/src/stats.rs b/cli/src/stats.rs new file mode 100644 index 0000000..390a200 --- /dev/null +++ b/cli/src/stats.rs @@ -0,0 +1,73 @@ +use clap::ArgMatches; + +use chrono::Local; + +use serde_json; +use serde::ser::{MapVisitor, Serialize, Serializer}; + +use ilc_base; +use ilc_ops::stats::Stats; +use Environment; +use Cli; +use error; + +struct StatFormat { + version: String, + master_hash: String, + time: String, + stats: Stats, +} + +impl Serialize for StatFormat { + fn serialize(&self, s: &mut S) -> Result<(), S::Error> + where S: Serializer + { + struct Visitor<'a>(&'a StatFormat); + impl<'a> MapVisitor for Visitor<'a> { + fn visit(&mut self, s: &mut S) -> Result, S::Error> + where S: Serializer + { + try!(s.serialize_struct_elt("version", &self.0.version)); + try!(s.serialize_struct_elt("master_hash", &self.0.master_hash)); + try!(s.serialize_struct_elt("time", &self.0.time)); + try!(s.serialize_struct_elt("stats", &self.0.stats)); + Ok(None) + } + + fn len(&self) -> Option { + Some(4) + } + } + s.serialize_struct("StatFormat", Visitor(self)) + } +} + + +pub fn output_as_json(args: &ArgMatches, cli: &Cli, stats: Stats) -> ilc_base::Result<()> { + let e = Environment(args); + // let count = value_t!(args, "count", usize).unwrap_or(usize::MAX); + // let mut stats: Vec<(String, Person)> = stats.into_iter().collect(); + // stats.sort_by(|&(_, ref a), &(_, ref b)| b.words.cmp(&a.words)); + + // for &(ref name, ref stat) in stats.iter().take(count) { + + let format = StatFormat { + version: cli.version.clone(), + master_hash: cli.master_hash.clone(), + time: Local::now().to_rfc2822(), + stats: stats, + }; + + serde_json::to_writer_pretty(&mut e.output(), &format).unwrap_or_else(|e| error(Box::new(e))); + /* write!(&mut *e.output(), + * "{}:\n\tTotal lines: {}\n\tLines without alphabetic characters: {}\n\tTotal \ + * words: {}\n\tWords per line: {}\n", + * name, + * stat.lines, + * stat.lines - stat.alpha_lines, + * stat.words, + * stat.words as f32 / stat.lines as f32) + * .unwrap_or_else(|e| error(Box::new(e))); */ + // } + Ok(()) +} -- cgit v1.2.3