mirror of
https://codeberg.org/icewind/logsmash.git
synced 2026-06-03 18:14:11 +02:00
support selecting a file from an archive
This commit is contained in:
parent
4f3d6a17ab
commit
9634736d8c
5 changed files with 94 additions and 22 deletions
|
|
@ -25,8 +25,6 @@ pub enum ReadError {
|
|||
Zip(#[from] ZipError),
|
||||
#[error(transparent)]
|
||||
Zstd(#[from] FrameDecoderError),
|
||||
#[error("archive contains multiple files")]
|
||||
MultipleFiles,
|
||||
#[error("archive contains no files")]
|
||||
NoFiles,
|
||||
#[error("log file contained non-utf8 characters: {0:#}")]
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ mod archive;
|
|||
use crate::error::ReadError;
|
||||
use crate::logfile::archive::{Archive, ArchiveEntry, TarArchive, ZipArchive};
|
||||
use bzip2_rs::DecoderReader;
|
||||
use dialoguer::Select;
|
||||
use flate2::read::GzDecoder;
|
||||
use ruzstd::StreamingDecoder;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::io::{Cursor, Read, Seek};
|
||||
use xz2::read::XzDecoder;
|
||||
|
||||
pub struct LogFile {
|
||||
|
|
@ -14,14 +14,10 @@ pub struct LogFile {
|
|||
}
|
||||
|
||||
impl LogFile {
|
||||
pub fn open(path: &str) -> Result<LogFile, ReadError> {
|
||||
let file = File::open(path)?;
|
||||
let file = BufReader::new(file);
|
||||
pub fn open<R: Read + Seek>(path: &str, file: R) -> Result<LogFile, ReadError> {
|
||||
if path.ends_with(".zip") {
|
||||
let mut zip = ZipArchive::new(file)?;
|
||||
let content = select_file(&mut zip)?;
|
||||
|
||||
return Ok(LogFile { content });
|
||||
return select_file(&mut zip);
|
||||
}
|
||||
|
||||
if let Some(path) = path.strip_suffix(".gz") {
|
||||
|
|
@ -44,9 +40,7 @@ impl LogFile {
|
|||
fn open_no_seek<R: Read>(path: &str, mut file: R) -> Result<LogFile, ReadError> {
|
||||
if path.ends_with(".tar") {
|
||||
let mut zip = TarArchive::new(file)?;
|
||||
let content = select_file(&mut zip)?;
|
||||
|
||||
Ok(LogFile { content })
|
||||
select_file(&mut zip)
|
||||
} else {
|
||||
let mut content = String::new();
|
||||
file.read_to_string(&mut content)?;
|
||||
|
|
@ -64,21 +58,32 @@ impl LogFile {
|
|||
}
|
||||
}
|
||||
|
||||
fn select_file<A: Archive>(archive: &mut A) -> Result<String, ReadError> {
|
||||
fn select_file<A: Archive>(archive: &mut A) -> Result<LogFile, ReadError> {
|
||||
let entry = {
|
||||
let mut entries = archive
|
||||
.entries()
|
||||
.filter(|entry| !entry.name().starts_with("__MACOSX"))
|
||||
.filter(|entry| !entry.name().starts_with("__MACOSX") && !entry.name().ends_with('/'))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// todo: present a picker instead
|
||||
if entries.len() > 1 {
|
||||
return Err(ReadError::MultipleFiles);
|
||||
} else if entries.is_empty() {
|
||||
if entries.is_empty() {
|
||||
return Err(ReadError::NoFiles);
|
||||
}
|
||||
entries.pop().unwrap()
|
||||
|
||||
let index = if entries.len() == 1 {
|
||||
0usize
|
||||
} else {
|
||||
let names = entries.iter().map(A::Entry::name).collect::<Vec<_>>();
|
||||
Select::new()
|
||||
.with_prompt("Select file to load?")
|
||||
.items(&names)
|
||||
.interact()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
entries.remove(index)
|
||||
};
|
||||
let name = entry.name().to_string();
|
||||
let raw = entry.extract()?;
|
||||
Ok(String::from_utf8(raw)?)
|
||||
|
||||
LogFile::open(&name, Cursor::new(raw))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ use main_error::MainResult;
|
|||
use rayon::prelude::*;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::iter::once;
|
||||
|
||||
mod app;
|
||||
|
|
@ -39,7 +41,9 @@ struct Args {
|
|||
fn main() -> MainResult {
|
||||
let args = Args::parse();
|
||||
|
||||
let log_file = LogFile::open(&args.file).map_err(|err| LogError::Read {
|
||||
let file = File::open(&args.file)?;
|
||||
let file = BufReader::new(file);
|
||||
let log_file = LogFile::open(&args.file, file).map_err(|err| LogError::Read {
|
||||
err,
|
||||
path: args.file,
|
||||
})?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue