Add option to export plain text room logs

This commit is contained in:
Joscha 2022-07-07 03:41:44 +02:00
parent 02d3b067b8
commit 0ccf788d7b
5 changed files with 258 additions and 14 deletions

72
src/export.rs Normal file
View file

@ -0,0 +1,72 @@
//! Export logs from the vault to plain text files.
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;
use unicode_width::UnicodeWidthStr;
use crate::euph::api::Snowflake;
use crate::store::{MsgStore, Tree};
use crate::vault::{EuphMsg, Vault};
const TIME_FORMAT: &str = "%F %T";
const TIME_EMPTY: &str = " ";
pub async fn export(vault: &Vault, room: String, file: &Path) -> anyhow::Result<()> {
let mut file = BufWriter::new(File::create(file)?);
let vault = vault.euph(room);
let mut tree_id = vault.first_tree().await;
while let Some(some_tree_id) = tree_id {
let tree = vault.tree(&some_tree_id).await;
write_tree(&mut file, &tree, some_tree_id, 0)?;
tree_id = vault.next_tree(&some_tree_id).await;
}
Ok(())
}
fn write_tree(
file: &mut BufWriter<File>,
tree: &Tree<EuphMsg>,
id: Snowflake,
indent: usize,
) -> anyhow::Result<()> {
let indent_string = "| ".repeat(indent);
if let Some(msg) = tree.msg(&id) {
write_msg(file, &indent_string, msg)?;
} else {
write_placeholder(file, &indent_string)?;
}
if let Some(children) = tree.children(&id) {
for child in children {
write_tree(file, tree, *child, indent + 1)?;
}
}
Ok(())
}
fn write_msg(file: &mut BufWriter<File>, indent_string: &str, msg: &EuphMsg) -> anyhow::Result<()> {
let nick = &msg.nick;
let nick_empty = " ".repeat(nick.width());
for (i, line) in msg.content.lines().enumerate() {
if i == 0 {
let time = msg.time.0.format(TIME_FORMAT);
writeln!(file, "{time} {indent_string}[{nick}] {line}")?;
} else {
writeln!(file, "{TIME_EMPTY} {indent_string} {nick_empty} {line}")?;
}
}
Ok(())
}
fn write_placeholder(file: &mut BufWriter<File>, indent_string: &str) -> anyhow::Result<()> {
writeln!(file, "{TIME_EMPTY} {indent_string}...")?;
Ok(())
}