eve_log_parser/
watcher.rs1use std::{
5 fs::{self, File},
6 io::{Read, Seek, SeekFrom},
7 path::PathBuf,
8};
9
10use futures::{
11 channel::mpsc::{channel, Receiver},
12 future, SinkExt, Stream, StreamExt, TryStreamExt,
13};
14use home::home_dir;
15use log::{debug, error, info};
16use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher};
17
18use crate::{models::Log, parse_log_line};
19
20pub fn get_log_folder() -> PathBuf {
24 let mut path = home_dir().unwrap(); path.push("Documents");
26 path.push("EVE");
27 path.push("logs");
28 path.push("Gamelogs");
29 path
30}
31
32pub async fn watch_log_file(logfile: PathBuf) -> impl Stream<Item = Log> {
34 let (mut watcher, rx) = create_watcher().unwrap();
35
36 watcher
37 .watch(&logfile, RecursiveMode::NonRecursive)
38 .unwrap();
39 info!("Watcher started on file {:?}", &logfile);
40
41 let mut log_contents = fs::read_to_string(&logfile).unwrap();
42 let mut pos_in_file = log_contents.len() as u64;
43
44 rx.into_stream()
45 .inspect_err(|err| error!("Error in the watcher: {}", err))
46 .filter(|element| {
47 future::ready(match element {
48 Ok(event) => filter_ok_events(event),
49 _ => false,
50 })
51 })
52 .map(move |_| -> Option<Log> {
53 let mut f = File::open(&logfile).unwrap();
54 f.seek(SeekFrom::Start(pos_in_file)).unwrap();
55
56 pos_in_file = f.metadata().unwrap().len();
57
58 log_contents.clear();
59 f.read_to_string(&mut log_contents).unwrap();
60 info!("new content: {}", log_contents);
61 parse_log_line(&log_contents)
62 })
63 .filter_map(future::ready) }
65
66fn filter_ok_events(event: &Event) -> bool {
68 if let notify::event::EventKind::Modify(notify::event::ModifyKind::Data(_)) = event.kind {
69 return true;
70 }
71 false
72}
73
74fn create_watcher() -> notify::Result<(RecommendedWatcher, Receiver<notify::Result<Event>>)> {
76 debug!("Starting to create a watcher and the receiver");
77 let (mut tx, rx) = channel(1);
78 let watcher = RecommendedWatcher::new(
79 move |res| {
80 futures::executor::block_on(async {
81 tx.send(res).await.unwrap();
82 })
83 },
84 Config::default(),
85 )?;
86
87 Ok((watcher, rx))
88}