From f4d8b1a521c567ccc8e2470299287b063e0d5926 Mon Sep 17 00:00:00 2001 From: Till Hoeppner Date: Fri, 12 Jun 2015 00:00:27 +0200 Subject: Add semi-proper conversion --- src/context.rs | 3 ++- src/event.rs | 4 +++- src/format/energymech.rs | 41 ++++++++++++++++++++++++++--------------- src/format/weechat3.rs | 12 ++++++------ src/freq.rs | 3 ++- src/main.rs | 43 ++++++++++++++++++++++++++++++++++++------- 6 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/context.rs b/src/context.rs index 6626714..1793361 100644 --- a/src/context.rs +++ b/src/context.rs @@ -4,5 +4,6 @@ use chrono::offset::fixed::FixedOffset; pub struct Context { pub timezone: FixedOffset, - pub override_date: NaiveDate + pub override_date: Option, + pub channel: Option } diff --git a/src/event.rs b/src/event.rs index a1c15c2..9c59df2 100644 --- a/src/event.rs +++ b/src/event.rs @@ -17,6 +17,7 @@ use std::borrow::Cow; +use chrono::naive::time::NaiveTime; use chrono::offset::fixed::FixedOffset; use chrono::offset::TimeZone; @@ -47,7 +48,8 @@ impl Time { pub fn with_format(&self, tz: &FixedOffset, f: &str) -> String { match self { &Time::Unknown => panic!("Time data for this event is not present"), - &Time::Hms(_h, _m, _s) => unimplemented!(), + &Time::Hms(h, m, s) => format!("{}", + NaiveTime::from_hms(h as u32, m as u32, s as u32).format(f)), &Time::Timestamp(t) => format!("{}", tz.timestamp(t, 0).format(f)) } } diff --git a/src/format/energymech.rs b/src/format/energymech.rs index 6e5d8ae..1fdc537 100644 --- a/src/format/energymech.rs +++ b/src/format/energymech.rs @@ -38,13 +38,18 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { type Item = ::Result>; fn next(&mut self) -> Option<::Result>> { fn parse_time(context: &Context, time: &str) -> Time { - Time::Timestamp(context.timezone.from_local_date(&context.override_date) - .and_time(NaiveTime::from_hms(time[1..3].parse::().unwrap(), - time[4..6].parse::().unwrap(), - time[7..9].parse::().unwrap())) - .single() - .expect("Transformed log times can't be represented, due to timezone transitions") - .timestamp()) + let h = time[1..3].parse::().unwrap(); + let m = time[4..6].parse::().unwrap(); + let s = time[7..9].parse::().unwrap(); + if let Some(date) = context.override_date { + Time::Timestamp(context.timezone.from_local_date(&date) + .and_time(NaiveTime::from_hms(h, m, s)) + .single() + .expect("Transformed log times can't be represented, due to timezone transitions") + .timestamp()) + } else { + Time::Hms(h as u8, m as u8, s as u8) + } } loop { @@ -71,7 +76,7 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { content: rejoin(content, &split_tokens[3..]) }, time: parse_time(&self.context, time), - channel: None + channel: self.context.channel.clone().map(Into::into) })), [time, "***", old, "is", "now", "known", "as", new] => return Some(Ok(Event { ty: Type::Nick { @@ -79,7 +84,8 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { new_nick: new.to_owned().into() }, time: parse_time(&self.context, time), - channel: None + channel: self.context.channel.clone().map(Into::into) + })), [time, "***", nick, "sets", "mode:", mode, masks..] => return Some(Ok(Event { ty: Type::Mode { @@ -88,7 +94,8 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { masks: rejoin(&masks, &split_tokens[6..]).to_owned().into() }, time: parse_time(&self.context, time), - channel: None + channel: self.context.channel.clone().map(Into::into) + })), [time, "***", "Joins:", nick, host] => return Some(Ok(Event { ty: Type::Join { @@ -96,7 +103,8 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { mask: Some(strip_one(host).into()) }, time: parse_time(&self.context, time), - channel: None + channel: self.context.channel.clone().map(Into::into) + })), [time, "***", "Parts:", nick, host, reason..] => return Some(Ok(Event { ty: Type::Part { @@ -105,7 +113,8 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { reason: Some(strip_one(&rejoin(reason, &split_tokens[5..])).into()) }, time: parse_time(&self.context, time), - channel: None + channel: self.context.channel.clone().map(Into::into) + })), [time, "***", "Quits:", nick, host, reason..] => return Some(Ok(Event { ty: Type::Quit { @@ -114,7 +123,8 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { reason: Some(strip_one(&rejoin(reason, &split_tokens[5..])).into()) }, time: parse_time(&self.context, time), - channel: None + channel: self.context.channel.clone().map(Into::into) + })), [time, "***", nick, "changes", "topic", "to", topic..] => return Some(Ok(Event { ty: Type::TopicChange { @@ -122,7 +132,8 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { new_topic: strip_one(&rejoin(topic, &split_tokens[6..])).into() }, time: parse_time(&self.context, time), - channel: None + channel: self.context.channel.clone().map(Into::into) + })), [time, nick, content..] if nick.starts_with('<') && nick.ends_with('>') @@ -132,7 +143,7 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { content: rejoin(content, &split_tokens[2..]) }, time: parse_time(&self.context, time), - channel: None + channel: self.context.channel.clone().map(Into::into) })), _ => () } diff --git a/src/format/weechat3.rs b/src/format/weechat3.rs index 20ee1dd..9e07e92 100644 --- a/src/format/weechat3.rs +++ b/src/format/weechat3.rs @@ -84,7 +84,7 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { reason: Some(strip_one(&rejoin(reason, &split_tokens[7..])).into()), }, time: parse_time(&self.context, date, time), - channel: None + channel: self.context.channel.clone().map(Into::into) })), [date, time, "--", notice, content..] if notice.starts_with("Notice(") @@ -94,13 +94,13 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { content: rejoin(content, &split_tokens[4..]), }, time: parse_time(&self.context, date, time), - channel: None + channel: self.context.channel.clone().map(Into::into) })), [date, time, "--", "irc:", "disconnected", "from", "server", _..] => return Some(Ok(Event { ty: Type::Disconnect, time: parse_time(&self.context, date, time), - channel: None + channel: self.context.channel.clone().map(Into::into) })), [date, time, "--", nick, verb, "now", "known", "as", new_nick] if verb == "is" || verb == "are" @@ -110,7 +110,7 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { new_nick: new_nick.to_owned().into() }, time: parse_time(&self.context, date, time), - channel: None + channel: self.context.channel.clone().map(Into::into) })), [date, time, sp, "*", nick, msg..] if sp.clone().is_empty() @@ -120,7 +120,7 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { content: rejoin(msg, &split_tokens[5..]), }, time: parse_time(&self.context, date, time), - channel: None + channel: self.context.channel.clone().map(Into::into) })), [date, time, nick, msg..] => return Some(Ok(Event { @@ -129,7 +129,7 @@ impl<'a, R: 'a> Iterator for Iter<'a, R> where R: BufRead { content: rejoin(msg, &split_tokens[3..]), }, time: parse_time(&self.context, date, time), - channel: None + channel: self.context.channel.clone().map(Into::into) })), _ => () } diff --git a/src/freq.rs b/src/freq.rs index 25810e7..39015ee 100644 --- a/src/freq.rs +++ b/src/freq.rs @@ -48,7 +48,8 @@ fn main() { let mut stats: HashMap = HashMap::new(); let context = Context { timezone: FixedOffset::west(0), - override_date: NaiveDate::from_ymd(2015, 6, 10) + override_date: Some(NaiveDate::from_ymd(2015, 6, 10)), + channel: Some("#code".to_owned()) }; let mut parser = format::weechat3::Weechat3; diff --git a/src/main.rs b/src/main.rs index de5f85c..a1f7f26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ extern crate env_logger; use std::fs::File; use std::io::{ self, BufReader }; +use std::str::FromStr; use docopt::Docopt; @@ -50,21 +51,36 @@ A converter and statistics utility for IRC log files. Usage: ilc parse ... - ilc + ilc convert [--date DATE] [--tz SECS] [--channel CH] + ilc (-h | --help | -v | --version) Options: -h --help Show this screen. -v --version Show the version (duh). + --date DATE Override the date for this log. ISO 8601, YYYY-MM-DD. + --tz SECONDS UTC offset in the direction of the western hemisphere. [default: 0] + --channel CH Set a channel for the given log. "#; #[derive(RustcDecodable, Debug)] struct Args { cmd_parse: bool, + cmd_convert: bool, arg_file: Vec, flag_help: bool, - flag_version: bool + flag_version: bool, + flag_date: Option, + flag_tz: i32, + flag_channel: Option } +/*fn encode<'a, W, F>(format: &str) -> F where F: Encode<'a, W> { + match format { + "weechat3" => format::weechat3::Weechat3, + "energymech" => format::energymech::Energymech + } +}*/ + fn main() { env_logger::init().unwrap(); let args: Args = Docopt::new(USAGE) @@ -75,13 +91,15 @@ fn main() { unsafe { libc::funcs::c95::stdlib::exit(1) } } + let context = Context { + timezone: FixedOffset::west(args.flag_tz), + override_date: args.flag_date.and_then(|d| NaiveDate::from_str(&d).ok()), + channel: args.flag_channel.clone() + }; + if args.cmd_parse { - let context = Context { - timezone: FixedOffset::west(0), - override_date: NaiveDate::from_ymd(2015, 6, 10) - }; let mut parser = format::energymech::Energymech; - let formatter = format::energymech::Energymech; + let formatter = format::binary::Binary; for file in args.arg_file { let f: BufReader = BufReader::new(File::open(file).unwrap()); let iter = parser.decode(&context, f); @@ -91,4 +109,15 @@ fn main() { } } } + + if args.cmd_convert { + let stdin = io::stdin(); + + let mut parser = format::energymech::Energymech; + let formatter = format::binary::Binary; + + for e in parser.decode(&context, stdin.lock()) { + drop(formatter.encode(&context, io::stdout(), &e.unwrap())) + } + } } -- cgit v1.2.3