partial fixes

This commit is contained in:
phiresky 2020-06-12 00:09:37 +02:00
parent 2f580b135a
commit 766211edc4
7 changed files with 78 additions and 20 deletions

View File

@ -1,6 +1,6 @@
pub mod custom;
pub mod decompress;
//pub mod ffmpeg;
pub mod ffmpeg;
pub mod fns;
//pub mod pdfpages;
pub mod poppler;
@ -95,7 +95,7 @@ pub fn get_all_adapters(custom_adapters: Option<Vec<CustomAdapterConfig>>) -> Ad
}
let internal_adapters: Vec<Rc<dyn FileAdapter>> = vec![
//Rc::new(ffmpeg::FFmpegAdapter::new()),
Rc::new(ffmpeg::FFmpegAdapter::new()),
//Rc::new(zip::ZipAdapter::new()),
Rc::new(decompress::DecompressAdapter::new()),
// Rc::new(tar::TarAdapter::new()),

View File

@ -3,9 +3,12 @@ use super::{
AdapterMeta, GetMetadata,
};
use crate::matching::{FastMatcher, SlowMatcher};
use anyhow::{Context, Result};
use lazy_static::lazy_static;
use regex::{Captures, Regex};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::path::Path;
// mostly the same as AdapterMeta + SpawningFileAdapter
#[derive(Debug, Deserialize, Serialize, JsonSchema, Default, PartialEq, Clone)]
@ -115,17 +118,59 @@ impl GetMetadata for CustomSpawningFileAdapter {
&self.meta
}
}
fn arg_replacer(arg: &str, filepath_hint: &Path) -> Result<String> {
lazy_static::lazy_static! {
static ref ARG_REP: Regex = Regex::new(r"\{([a-z_]+)\}").unwrap();
}
let mut err = None;
let r = ARG_REP.replace_all(arg, |m: &Captures| -> String {
let idx = m.get(0).unwrap().range();
if arg.chars().nth(idx.start - 1) == Some('{') {
// skip
return m.get(0).unwrap().as_str().to_string();
}
if arg.chars().nth(idx.end + 1) == Some('}') {
// skip
return m.get(0).unwrap().as_str().to_string();
}
let key = m.get(1).unwrap().as_str();
if key == "file_extension" {
return filepath_hint
.extension()
.map(|e| e.to_string_lossy().to_string())
.unwrap_or("".to_string());
}
err = Some(anyhow::anyhow!(
"Unknown arg replacement key '{}' in '{}'",
key,
arg
));
"".to_string()
//let
});
if let Some(err) = err {
Err(err)
} else {
Ok(r.to_string())
}
}
impl SpawningFileAdapterTrait for CustomSpawningFileAdapter {
fn get_exe(&self) -> &str {
&self.binary
}
fn command(
&self,
_filepath_hint: &std::path::Path,
filepath_hint: &std::path::Path,
mut command: std::process::Command,
) -> std::process::Command {
command.args(&self.args);
command
) -> Result<std::process::Command> {
command.args(
self.args
.iter()
.map(|arg| arg_replacer(arg, &filepath_hint))
.collect::<Result<Vec<_>>>()?,
);
log::debug!("running command {:?}", command);
Ok(command)
}
}
impl CustomAdapterConfig {

View File

@ -2,9 +2,11 @@ use super::spawning::map_exe_error;
use super::*;
use anyhow::*;
use lazy_static::lazy_static;
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::io::BufReader;
use std::process::*;
use writing::{WritingFileAdapter, WritingFileAdapterTrait};
// todo:
// maybe todo: read list of extensions from
// ffmpeg -demuxers | tail -n+5 | awk '{print $2}' | while read demuxer; do echo MUX=$demuxer; ffmpeg -h demuxer=$demuxer | grep 'Common extensions'; done 2>/dev/null
@ -26,12 +28,12 @@ lazy_static! {
};
}
#[derive(Default)]
#[derive(Default, Clone)]
pub struct FFmpegAdapter;
impl FFmpegAdapter {
pub fn new() -> FFmpegAdapter {
FFmpegAdapter
pub fn new() -> WritingFileAdapter {
WritingFileAdapter::new(Box::new(FFmpegAdapter))
}
}
impl GetMetadata for FFmpegAdapter {
@ -48,12 +50,16 @@ struct FFprobeOutput {
struct FFprobeStream {
codec_type: String, // video,audio,subtitle
}
impl FileAdapter for FFmpegAdapter {
fn adapt(&self, ai: AdaptInfo, _detection_reason: &SlowMatcher) -> Result<()> {
impl WritingFileAdapterTrait for FFmpegAdapter {
fn adapt_write(
&self,
ai: AdaptInfo,
_detection_reason: &SlowMatcher,
oup: &mut dyn Write,
) -> Result<()> {
let AdaptInfo {
is_real_file,
filepath_hint,
oup,
line_prefix,
..
} = ai;
@ -80,7 +86,7 @@ impl FileAdapter for FFmpegAdapter {
"stream=codec_type",
])
.arg("-i")
.arg(inp_fname)
.arg(&inp_fname)
.output()
.map_err(spawn_fail)?;
if !probe.status.success() {
@ -107,7 +113,7 @@ impl FileAdapter for FFmpegAdapter {
//"-count_packets",
])
.arg("-i")
.arg(inp_fname)
.arg(&inp_fname)
.stdout(Stdio::piped())
.spawn()?;
for line in BufReader::new(probe.stdout.as_mut().unwrap()).lines() {
@ -125,7 +131,7 @@ impl FileAdapter for FFmpegAdapter {
.arg("-loglevel")
.arg("panic")
.arg("-i")
.arg(inp_fname)
.arg(&inp_fname)
.arg("-f")
.arg("webvtt")
.arg("-");

View File

@ -34,6 +34,7 @@ where
inner: R,
next_read: Vec<u8>,
replacer: Box<dyn FnMut(u8) -> Vec<u8>>,
haystacker: Box<dyn Fn(&[u8]) -> Option<usize>>,
}
impl<R> ByteReplacer<R>
@ -77,7 +78,7 @@ where
match read {
Ok(u) => {
match memchr::memchr2(b'\n', b'\x0c', &buf[0..u]) {
match (self.haystacker)(&buf[0..u]) {
Some(i) => {
let data = (self.replacer)(buf[i]);
@ -98,6 +99,7 @@ pub fn postprocB(_line_prefix: &str, inp: impl Read) -> Result<impl Read> {
Ok(ByteReplacer {
inner: inp,
next_read: Vec::new(),
haystacker: Box::new(|buf| memchr::memchr2(b'\n', b'\x0c', buf)),
replacer: Box::new(move |b| match b {
b'\n' => format!("\nPage {}:", page_count).into_bytes(),
b'\x0c' => {

View File

@ -2,6 +2,7 @@ use super::*;
use anyhow::*;
use encoding_rs_io::DecodeReaderBytesBuilder;
use log::*;
use regex::Regex;
use std::io::prelude::*;
use std::io::BufReader;
use std::process::Command;
@ -55,7 +56,7 @@ pub fn postproc_line_prefix(
}
pub trait SpawningFileAdapterTrait: GetMetadata {
fn get_exe(&self) -> &str;
fn command(&self, filepath_hint: &Path, command: Command) -> Command;
fn command(&self, filepath_hint: &Path, command: Command) -> Result<Command>;
/*fn postproc(&self, line_prefix: &str, inp: &mut dyn Read, oup: &mut dyn Write) -> Result<()> {
postproc_line_prefix(line_prefix, inp, oup)
@ -146,7 +147,10 @@ impl FileAdapter for SpawningFileAdapter {
} = ai;
let cmd = Command::new(self.inner.get_exe());
let cmd = self.inner.command(&filepath_hint, cmd);
let cmd = self
.inner
.command(&filepath_hint, cmd)
.with_context(|| format!("Could not set cmd arguments for {}", self.inner.get_exe()))?;
debug!("executing {:?}", cmd);
pipe_output(&line_prefix, cmd, &mut inp, self.inner.get_exe(), "")
}

View File

@ -2,6 +2,7 @@ use super::{FileAdapter, GetMetadata, ReadBox};
use anyhow::Result;
use std::io::Write;
// this trait / struct split is necessary because of "conflicting trait implementation" otherwise with SpawningFileAdapter
#[dyn_clonable::clonable]
pub trait WritingFileAdapterTrait: GetMetadata + Send + Clone {
fn adapt_write(

View File

@ -16,7 +16,7 @@ fn main() -> anyhow::Result<()> {
std::env::current_dir()?.join(&filepath)
};
let i = File::open(&path)?;
let i = File::open(&path).context("Specified input file not found")?;
let mut o = std::io::stdout();
let cache = if args.no_cache {
None
@ -31,7 +31,7 @@ fn main() -> anyhow::Result<()> {
archive_recursion_depth: 0,
config: PreprocConfig { cache, args },
};
let mut oup = rga_preproc(ai)?;
let mut oup = rga_preproc(ai).context("during preprocessing")?;
std::io::copy(&mut oup, &mut o).context("copying adapter output to stdout")?;
Ok(())
}