Skip to content

Commit a4db062

Browse files
committed
Merging of any number of logs
1 parent 52d4c29 commit a4db062

File tree

16 files changed

+296
-78
lines changed

16 files changed

+296
-78
lines changed

Cargo.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ description = "IRC log converter/collector/cruncher"
44
license = "Apache-2.0"
55
name = "ilc"
66
repository = "https://github.com/tilpner/ilc"
7-
version = "0.2.2"
7+
version = "0.3.0"
88

99
[[bin]]
1010
name = "ilc"
1111
doc = false
1212

1313
[dependencies]
14-
ilc-cli = "0.1.0"
15-
ilc-base = "0.1.0"
16-
ilc-ops = "0.1.0"
17-
ilc-format-weechat = "0.1.0"
18-
ilc-format-energymech = "0.1.0"
14+
ilc-cli = "~0.1"
15+
ilc-base = "~0.2"
16+
ilc-ops = "~0.1"
17+
ilc-format-weechat = "~0.2"
18+
ilc-format-energymech = "~0.2"
19+
20+
[dev-dependencies]
21+
flate2 = "~0.2"
1922

2023
[profile.release]
2124
debug = false

base/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ilc-base"
3-
version = "0.1.2"
3+
version = "0.2.0"
44
description = "IRC log converter/collector/cruncher"
55
homepage = "https://github.com/tilpner/ilc"
66
license = "Apache-2.0"

base/src/context.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,13 @@ pub struct Context {
77
pub override_date: Option<NaiveDate>,
88
pub channel: Option<String>,
99
}
10+
11+
impl Default for Context {
12+
fn default() -> Context {
13+
Context {
14+
timezone: FixedOffset::west(0),
15+
override_date: None,
16+
channel: None,
17+
}
18+
}
19+
}

base/src/dummy.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ use std::io::BufRead;
1818
use event::Event;
1919
use context::Context;
2020

21+
#[derive(Copy, Clone)]
2122
pub struct Dummy;
2223

2324
impl ::Decode for Dummy {
24-
fn decode<'a>(&'a mut self,
25+
fn decode<'a>(&'a self,
2526
_context: &'a Context,
2627
_input: &'a mut BufRead)
2728
-> Box<Iterator<Item = ::Result<Event<'a>>> + 'a> {

base/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub mod dummy;
2626
use std::io::{BufRead, Write};
2727

2828
pub use context::Context;
29-
pub use event::Event;
29+
pub use event::{Event, Time};
3030
pub use error::*;
3131

3232
pub trait Encode {
@@ -37,8 +37,8 @@ pub trait Encode {
3737
-> error::Result<()>;
3838
}
3939

40-
pub trait Decode {
41-
fn decode<'a>(&'a mut self,
40+
pub trait Decode {
41+
fn decode<'a>(&'a self,
4242
context: &'a Context,
4343
input: &'a mut BufRead)
4444
-> Box<Iterator<Item = error::Result<Event<'a>>> + 'a>;

cli/Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ilc-cli"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
description = "IRC log converter/collector/cruncher"
55
homepage = "https://github.com/tilpner/ilc"
66
license = "Apache-2.0"
@@ -16,7 +16,7 @@ clap = "2.1.2"
1616
chrono = "0.2.19"
1717
env_logger = "0.3.2"
1818
glob = "0.2.10"
19-
ilc-base = "0.1.0"
20-
ilc-ops = "0.1.0"
21-
ilc-format-weechat = { optional = true, version = "0.1.0" }
22-
ilc-format-energymech = { optional = true, version = "0.1.0" }
19+
ilc-base = "~0.2"
20+
ilc-ops = "~0.1"
21+
ilc-format-weechat = { optional = true, version = "~0.2" }
22+
ilc-format-energymech = { optional = true, version = "~0.2" }

cli/src/lib.rs

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ mod chain;
4747

4848
pub fn main() {
4949
env_logger::init().unwrap();
50+
if option_env!("FUSE").is_some() {
51+
info!("Compiled with FUSEs")
52+
}
53+
5054
let args = App::new("ilc")
5155
.version(crate_version!())
5256
.setting(AppSettings::GlobalVersion)
@@ -181,21 +185,22 @@ pub fn main() {
181185
&*e.encoder())
182186
}
183187
("merge", Some(args)) => {
184-
// TODO: avoid (de-)serialization to weechat
185188
let e = Environment(&args);
186-
let (ctx, i, d, o, e) = (&e.context(),
187-
&mut e.input(),
188-
&mut *e.decoder(),
189-
&mut *e.output(),
190-
&*e.encoder());
191-
let mut buffer = Vec::new();
192-
match sort::sort(ctx, i, d, &mut buffer, &Weechat) {
193-
Err(e) => error(Box::new(e)),
194-
_ => (),
195-
}
196-
let mut read = io::Cursor::new(&buffer);
197-
dedup::dedup(ctx, &mut read, &mut Weechat, o, e)
198189

190+
let mut inputs = e.inputs();
191+
// let mut decoders = e.decoders();
192+
193+
let borrowed_inputs = inputs.iter_mut()
194+
.map(|a| a as &mut BufRead)
195+
.collect();
196+
// let borrowed_decoders = decoders.iter_mut()
197+
// .map(|a| &mut **a as &mut Decode)
198+
// .collect();
199+
merge::merge(&e.context(),
200+
borrowed_inputs,
201+
&mut *e.decoder(),
202+
&mut *e.output(),
203+
&*e.encoder())
199204
}
200205
(sc, _) if !sc.is_empty() => panic!("Unimplemented subcommand `{}`, this is a bug", sc),
201206
_ => die("No command specified"),
@@ -272,15 +277,44 @@ impl<'a> Environment<'a> {
272277
pub fn context(&self) -> Context {
273278
build_context(self.0)
274279
}
280+
275281
pub fn input(&self) -> Box<BufRead> {
276282
open_files(gather_input(self.0))
277283
}
284+
285+
pub fn inputs(&self) -> Vec<Box<BufRead>> {
286+
gather_input(self.0)
287+
.iter()
288+
.map(|path| {
289+
Box::new(BufReader::new(File::open(path)
290+
.unwrap_or_else(|e| {
291+
error(Box::new(e))
292+
}))) as Box<BufRead>
293+
})
294+
.collect()
295+
}
296+
278297
pub fn output(&self) -> Box<Write> {
279298
open_output(self.0)
280299
}
300+
281301
pub fn decoder(&self) -> Box<Decode> {
282302
force_decoder(self.0.value_of("format").or(self.0.value_of("input_format")))
283303
}
304+
305+
/* pub fn decoders(&self) -> Vec<Box<Decode>> {
306+
* self.0
307+
* .value_of("format")
308+
* .into_iter()
309+
* .chain(self.0
310+
* .values_of("input_formats")
311+
* .map(|i| Box::new(i) as Box<Iterator<Item = _>>)
312+
* .unwrap_or(Box::new(iter::empty()) as Box<Iterator<Item = _>>))
313+
* .map(Option::Some)
314+
* .map(force_decoder)
315+
* .collect()
316+
* } */
317+
284318
pub fn encoder(&self) -> Box<Encode> {
285319
force_encoder(self.0.value_of("format").or(self.0.value_of("output_format")))
286320
}

formats/energymech/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ilc-format-energymech"
3-
version = "0.1.1"
3+
version = "0.2.0"
44
description = "IRC log converter/collector/cruncher"
55
homepage = "https://github.com/tilpner/ilc"
66
license = "Apache-2.0"
@@ -10,4 +10,4 @@ authors = ["Till Höppner <till@hoeppner.ws>"]
1010
[dependencies]
1111
log = "0.3.5"
1212
chrono = "0.2.19"
13-
ilc-base = "0.1.0"
13+
ilc-base = "~0.2"

formats/energymech/src/lib.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use log::LogLevel::Info;
2929

3030
use chrono::*;
3131

32+
#[derive(Copy, Clone)]
3233
pub struct Energymech;
3334

3435
static TIME_FORMAT: &'static str = "%H:%M:%S";
@@ -219,12 +220,15 @@ impl<'a> Iterator for Iter<'a> {
219220
channel: self.context.channel.clone().map(Into::into),
220221
}));
221222
}
223+
if option_env!("FUSE").is_some() {
224+
panic!("Shouldn't reach here, this is a bug!")
225+
}
222226
}
223227
}
224228
}
225229

226230
impl Decode for Energymech {
227-
fn decode<'a>(&'a mut self,
231+
fn decode<'a>(&'a self,
228232
context: &'a Context,
229233
input: &'a mut BufRead)
230234
-> Box<Iterator<Item = ilc_base::Result<Event<'a>>> + 'a> {
@@ -250,6 +254,13 @@ impl Encode for Energymech {
250254
from,
251255
content))
252256
}
257+
&Event { ty: Type::Notice { ref from, ref content }, ref time, .. } => {
258+
try!(writeln!(&mut output,
259+
"[{}] -{}- {}",
260+
time.with_format(&context.timezone, TIME_FORMAT),
261+
from,
262+
content))
263+
}
253264
&Event { ty: Type::Action { ref from, ref content }, ref time, .. } => {
254265
try!(writeln!(&mut output,
255266
"[{}] * {} {}",
@@ -302,7 +313,12 @@ impl Encode for Energymech {
302313
nick.as_ref().expect("Nick not present, but required."),
303314
new_topic))
304315
}
305-
_ => (),
316+
_ => {
317+
if option_env!("FUSE").is_some() {
318+
panic!("Shouldn't reach here, this is a bug!")
319+
}
320+
()
321+
}
306322
}
307323
Ok(())
308324
}

formats/weechat/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ilc-format-weechat"
3-
version = "0.1.1"
3+
version = "0.2.0"
44
description = "IRC log converter/collector/cruncher"
55
homepage = "https://github.com/tilpner/ilc"
66
license = "Apache-2.0"
@@ -10,4 +10,4 @@ authors = ["Till Höppner <till@hoeppner.ws>"]
1010
[dependencies]
1111
log = "0.3.5"
1212
chrono = "0.2.19"
13-
ilc-base = "0.1.0"
13+
ilc-base = "~0.2"

formats/weechat/src/lib.rs

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use ilc_base::format::{rejoin, strip_one};
2626

2727
use log::LogLevel::Info;
2828

29+
#[derive(Copy, Clone)]
2930
pub struct Weechat;
3031

3132
static TIME_DATE_FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";
@@ -76,44 +77,40 @@ impl<'a> Iterator for Iter<'a> {
7677

7778
let len = tokens.len();
7879

79-
if len >= 6 && tokens[5] == "has" {
80-
// 2016-02-25 01:15:05 --> Foo (host@mask.foo) has joined #example
81-
if len >= 8 && tokens[6] == "joined" {
82-
return Some(Ok(Event {
83-
ty: Type::Join {
84-
nick: tokens[3].to_owned().into(),
85-
mask: Some(strip_one(tokens[4]).into()),
86-
},
87-
channel: Some(tokens[7].to_owned().into()),
88-
time: parse_time(&self.context, tokens[0], tokens[1]),
89-
}));
90-
}
91-
// 2016-02-25 01:36:13 <-- Foo (host@mask.foo) has left #channel (Some reason)
92-
else if len >= 9 && tokens[6] == "left" {
93-
return Some(Ok(Event {
94-
ty: Type::Part {
95-
nick: tokens[3].to_owned().into(),
96-
mask: Some(strip_one(&tokens[4]).into()),
97-
reason: Some(strip_one(&rejoin(&tokens[8..], &split_tokens[8..]))
98-
.into()),
99-
},
100-
channel: Some(tokens[7].to_owned().into()),
101-
time: parse_time(&self.context, tokens[0], tokens[1]),
102-
}));
103-
}
104-
// 2016-02-25 01:38:55 <-- Foo (host@mask.foo) has quit (Some reason)
105-
else if len >= 8 && tokens[6] == "quit" {
106-
return Some(Ok(Event {
107-
ty: Type::Quit {
108-
nick: tokens[3].to_owned().into(),
109-
mask: Some(strip_one(tokens[4]).into()),
110-
reason: Some(strip_one(&rejoin(&tokens[7..], &split_tokens[7..]))
111-
.into()),
112-
},
113-
time: parse_time(&self.context, tokens[0], tokens[1]),
114-
channel: self.context.channel.clone().map(Into::into),
115-
}));
116-
}
80+
// 2016-02-25 01:15:05 --> Foo (host@mask.foo) has joined #example
81+
if len >= 8 && tokens[5] == "has" && tokens[6] == "joined" {
82+
return Some(Ok(Event {
83+
ty: Type::Join {
84+
nick: tokens[3].to_owned().into(),
85+
mask: Some(strip_one(tokens[4]).into()),
86+
},
87+
channel: Some(tokens[7].to_owned().into()),
88+
time: parse_time(&self.context, tokens[0], tokens[1]),
89+
}));
90+
}
91+
// 2016-02-25 01:36:13 <-- Foo (host@mask.foo) has left #channel (Some reason)
92+
else if len >= 9 && tokens[5] == "has" && tokens[6] == "left" {
93+
return Some(Ok(Event {
94+
ty: Type::Part {
95+
nick: tokens[3].to_owned().into(),
96+
mask: Some(strip_one(&tokens[4]).into()),
97+
reason: Some(strip_one(&rejoin(&tokens[8..], &split_tokens[8..])).into()),
98+
},
99+
channel: Some(tokens[7].to_owned().into()),
100+
time: parse_time(&self.context, tokens[0], tokens[1]),
101+
}));
102+
}
103+
// 2016-02-25 01:38:55 <-- Foo (host@mask.foo) has quit (Some reason)
104+
else if len >= 8 && tokens[5] == "has" && tokens[6] == "quit" {
105+
return Some(Ok(Event {
106+
ty: Type::Quit {
107+
nick: tokens[3].to_owned().into(),
108+
mask: Some(strip_one(tokens[4]).into()),
109+
reason: Some(strip_one(&rejoin(&tokens[7..], &split_tokens[7..])).into()),
110+
},
111+
time: parse_time(&self.context, tokens[0], tokens[1]),
112+
channel: self.context.channel.clone().map(Into::into),
113+
}));
117114
} else if len >= 3 && tokens[2] == "--" {
118115
// 2016-02-25 04:32:15 -- Notice(playbot-veno): ""
119116
if len >= 5 && tokens[3].starts_with("Notice(") {
@@ -176,7 +173,7 @@ impl<'a> Iterator for Iter<'a> {
176173
}
177174

178175
impl Decode for Weechat {
179-
fn decode<'a>(&'a mut self,
176+
fn decode<'a>(&'a self,
180177
context: &'a Context,
181178
input: &'a mut BufRead)
182179
-> Box<Iterator<Item = ilc_base::Result<Event<'a>>> + 'a> {
@@ -252,7 +249,12 @@ impl Encode for Weechat {
252249
from,
253250
content))
254251
}
255-
_ => (),
252+
_ => {
253+
if option_env!("FUSE").is_some() {
254+
panic!("Shouldn't reach here, this is a bug!")
255+
}
256+
()
257+
}
256258
}
257259
Ok(())
258260
}

0 commit comments

Comments
 (0)