aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTill Hoeppner2015-03-24 23:47:03 +0100
committerTill Hoeppner2015-03-24 23:47:29 +0100
commitbead9324f053957f73042b1e33905aaa73b57649 (patch)
tree27ad07702fff7f6bfcf388b93b1bd1d27ab70a84
parentd972eed6b596d415a0aa6117a05bd107dbb8a0ae (diff)
downloadilc-bead9324f053957f73042b1e33905aaa73b57649.tar.gz
ilc-bead9324f053957f73042b1e33905aaa73b57649.tar.xz
ilc-bead9324f053957f73042b1e33905aaa73b57649.zip
Partial parsing/formatting of weechat3, plus basic CLI interface
-rw-r--r--src/format/weechat3.rs163
-rw-r--r--src/log.rs13
-rw-r--r--src/main.rs10
3 files changed, 127 insertions, 59 deletions
diff --git a/src/format/weechat3.rs b/src/format/weechat3.rs
index f546983..d0dba67 100644
--- a/src/format/weechat3.rs
+++ b/src/format/weechat3.rs
@@ -1,8 +1,8 @@
-use std::io::BufRead;
+use std::io::{ self, BufRead, Write };
use std::borrow::ToOwned;
use log::Event;
-use format::Decode;
+use format::{ Encode, Decode };
use regex::Regex;
@@ -12,8 +12,8 @@ pub struct Weechat3;
static NORMAL_LINE: Regex = regex!(r"^(\d+-\d+-\d+ \d+:\d+:\d+)\t[@%+~&]?([^ <-]\S+)\t(.*)");
static ACTION_LINE: Regex = regex!(r"^(\d+-\d+-\d+ \d+:\d+:\d+)\t \*\t(\S+) (.*)");
-//static OTHER_LINES: Regex = regex!(r"^(\d+-\d+-\d+ \d+:\d+:\d+)\s(?:--|<--|-->)\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)\n$");
-static OTHER_LINES: Regex = regex!(r"(.*)");
+static OTHER_LINES: Regex = regex!(r"^(\d+-\d+-\d+ \d+:\d+:\d+)\s(?:--|<--|-->)\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)(.*)\n$");
+//static OTHER_LINES: Regex = regex!(r"(.+)");
static TIME_DATE_FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";
@@ -28,69 +28,122 @@ impl<R> Iterator for Iter<R> where R: BufRead {
fn time(s: &str) -> i64 {
UTC.datetime_from_str(s, TIME_DATE_FORMAT).unwrap().timestamp()
}
-
- println!("Reading line...");
- self.buffer.clear();
- match self.input.read_line(&mut self.buffer) {
- Ok(0) | Err(_) => return None,
- Ok(_) => ()
+ fn mask(s: &str) -> String {
+ s.trim_left_matches('(').trim_right_matches(')').to_owned()
}
- let line = &self.buffer;
- println!("Read line: {}", line);
- if let Some(cap) = NORMAL_LINE.captures(line) {
- return Some(Ok(Event::Msg {
- from: cap.at(1).unwrap().to_owned(),
- content: cap.at(2).unwrap().to_owned(),
- time: time(cap.at(0).unwrap())
- }))
- } else if let Some(cap) = ACTION_LINE.captures(line) {
- return Some(Ok(Event::Action {
- from: cap.at(1).unwrap().to_owned(),
- content: cap.at(2).unwrap().to_owned(),
- time: time(cap.at(0).unwrap())
- }))
- } else if let Some(cap) = OTHER_LINES.captures(line) {
- if cap.at(4) == Some("has") && cap.at(5) == Some("kicked") {
- return Some(Ok(Event::Kick {
- kicked_nick: cap.at(6).unwrap().to_owned(),
- kicking_nick: cap.at(3).unwrap().to_owned(),
- kick_message: cap.at(4).unwrap().to_owned(),
- time: time(cap.at(0).unwrap())
- }))
- } else if cap.at(3) == Some("has") && cap.at(5) == Some("changed") && cap.at(6) == Some("topic") {
- return Some(Ok(Event::Topic {
- new_topic: cap.at(5).unwrap().to_owned(),
- time: time(cap.at(0).unwrap())
- }))
- } else if cap.at(3) == Some("Mode") {
- return Some(Ok(Event::Mode {
- time: time(cap.at(0).unwrap())
+
+ loop {
+ self.buffer.clear();
+ match self.input.read_line(&mut self.buffer) {
+ Ok(0) | Err(_) => return None,
+ Ok(_) => ()
+ }
+ let line = &self.buffer;
+ if let Some(cap) = NORMAL_LINE.captures(line) {
+ return Some(Ok(Event::Msg {
+ from: cap.at(1).unwrap().to_owned(),
+ content: cap.at(2).unwrap().to_owned(),
+ time: time(cap.at(1).unwrap())
}))
- } else if cap.at(5) == Some("has") && cap.at(6) == Some("joined") {
- return Some(Ok(Event::Join {
- nick: cap.at(3).unwrap().to_owned(),
- mask: String::new(),
- time: time(cap.at(0).unwrap())
+ } else if let Some(cap) = ACTION_LINE.captures(line) {
+ return Some(Ok(Event::Action {
+ from: cap.at(1).unwrap().to_owned(),
+ content: cap.at(2).unwrap().to_owned(),
+ time: time(cap.at(1).unwrap())
}))
- } else if cap.at(5) == Some("now") && cap.at(6) == Some("known") {
-
+ } else if let Some(cap) = OTHER_LINES.captures(line) {
+ println!("{:?}", cap.iter().collect::<Vec<_>>());
+ if cap.at(4) == Some("has") && cap.at(5) == Some("kicked") {
+ println!(" Matched Event::Kick");
+ return Some(Ok(Event::Kick {
+ kicked_nick: cap.at(6).unwrap().to_owned(),
+ kicking_nick: cap.at(3).unwrap().to_owned(),
+ kick_message: cap.at(4).unwrap().to_owned(),
+ time: time(cap.at(1).unwrap())
+ }))
+ } else if cap.at(2) == Some("Topic") && cap.at(3) == Some("for") {
+ return Some(Ok(Event::Topic {
+ topic: { let mut s = cap.at(6).unwrap().to_string(); s.push_str(cap.at(7).unwrap()); s },
+ time: time(cap.at(1).unwrap())
+ }))
+ } else if cap.at(3) == Some("has") && cap.at(5) == Some("changed") && cap.at(6) == Some("topic") {
+ return Some(Ok(Event::TopicChange {
+ new_topic: cap.at(5).unwrap().to_owned(),
+ time: time(cap.at(1).unwrap())
+ }))
+ } else if cap.at(3) == Some("Mode") {
+ return Some(Ok(Event::Mode {
+ time: time(cap.at(1).unwrap())
+ }))
+ } else if cap.at(4) == Some("has") && cap.at(5) == Some("joined") {
+ return Some(Ok(Event::Join {
+ nick: cap.at(2).unwrap().to_owned(),
+ channel: cap.at(6).unwrap().to_owned(),
+ mask: mask(cap.at(3).unwrap()),
+ time: time(cap.at(1).unwrap())
+ }))
+ } else if cap.at(4) == Some("has") && cap.at(5) == Some("left") {
+ return Some(Ok(Event::Part {
+ nick: cap.at(2).unwrap().to_owned(),
+ channel: cap.at(6).unwrap().to_owned(),
+ reason: cap.at(7).unwrap().to_owned(),
+ mask: mask(cap.at(3).unwrap()),
+ time: time(cap.at(1).unwrap())
+ }))
+ } else if cap.at(5) == Some("now") && cap.at(6) == Some("known") {
+ return Some(Ok(Event::Nick {
+ old: String::new(),
+ new: String::new(),
+ time: time(cap.at(1).unwrap())
+ }))
+ }
}
}
- Some(Err(::IlcError::Parse(format!("Line `{}` didn't match any rules.", line))))
}
}
impl<R> Decode<R, Iter<R>> for Weechat3 where R: BufRead {
- fn decode(&mut self, input: R) -> Iter<R> {/*
- for line in input.lines() {
- let line = &*try!(line);
- } else {
- handler.err(&format!("Malformatted line: {}", line));
- }
- }*/
+ fn decode(&mut self, input: R) -> Iter<R> {
Iter {
input: input,
buffer: String::new()
}
}
}
+
+impl<W> Encode<W> for Weechat3 where W: Write {
+ fn encode(&self, mut output: W, event: &Event) -> io::Result<()> {
+ fn date(t: i64) -> String {
+ format!("{}", UTC.timestamp(t, 0).format(TIME_DATE_FORMAT))
+ }
+ match event {
+ &Event::Msg { ref from, ref content, ref time } => {
+ try!(write!(&mut output, "{}\t{}\t{}\n", date(*time), from, content))
+ },
+ &Event::Action { ref from, ref content, ref time } => {
+ try!(write!(&mut output, "{}\t*\t{} {}\n", date(*time), from, content))
+ },
+ &Event::Join { ref nick, ref mask, ref channel, ref time } => {
+ try!(write!(&mut output, "{}\t-->\t{} ({}) has joined {}\n",
+ date(*time), nick, mask, channel))
+ },
+ &Event::Part { ref nick, ref mask, ref channel, ref time, ref reason } => {
+ try!(write!(&mut output, "{}\t<--\t{} ({}) has left {}",
+ date(*time), nick, mask, channel));
+ if reason.len() > 0 {
+ try!(write!(&mut output, " ({})", reason));
+ }
+ try!(write!(&mut output, "\n"))
+ },
+ &Event::Quit { ref nick, ref mask, ref time, ref reason } => {
+ try!(write!(&mut output, "{}\t<--\t{} ({}) has quit", date(*time), nick, mask));
+ if reason.len() > 0 {
+ try!(write!(&mut output, " ({})", reason));
+ }
+ try!(write!(&mut output, "\n"))
+ },
+ _ => ()
+ }
+ Ok(())
+ }
+}
diff --git a/src/log.rs b/src/log.rs
index 3079b38..1b6ed45 100644
--- a/src/log.rs
+++ b/src/log.rs
@@ -23,12 +23,21 @@ pub enum Event {
},
Join {
nick: String,
+ channel: String,
mask: String,
time: i64
},
+ Part {
+ nick: String,
+ channel: String,
+ mask: String,
+ reason: String,
+ time: i64
+ },
Quit {
nick: String,
mask: String,
+ reason: String,
time: i64
},
Nick {
@@ -48,6 +57,10 @@ pub enum Event {
time: i64
},
Topic {
+ topic: String,
+ time: i64
+ },
+ TopicChange {
new_topic: String,
time: i64
},
diff --git a/src/main.rs b/src/main.rs
index 1bdf090..b5f65a9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,11 +8,11 @@ extern crate libc;
extern crate regex;
use std::fs::File;
-use std::io::BufReader;
+use std::io::{ self, BufReader };
use docopt::Docopt;
-use ilc::format::{ self, Decode };
+use ilc::format::{ self, Encode, Decode };
static USAGE: &'static str = "
A converter and statistics utility for IRC log files.
@@ -47,8 +47,10 @@ fn main() {
for file in args.arg_file {
let f: BufReader<File> = BufReader::new(File::open(file).unwrap());
let iter = parser.decode(f);
- println!("Obtained event iterator");
- for e in iter { println!("{:?}", e) }
+ let events: Vec<_> = iter.collect();
+ for e in events {
+ parser.encode(io::stdout(), &e.unwrap());
+ }
}
}
}