2019-06-06 09:00:13 +00:00
|
|
|
use super::*;
|
|
|
|
use crate::preproc::rga_preproc;
|
2019-06-06 14:48:31 +00:00
|
|
|
use ::zip::read::ZipFile;
|
2019-06-06 09:00:13 +00:00
|
|
|
use failure::*;
|
|
|
|
use lazy_static::lazy_static;
|
2019-06-06 21:43:30 +00:00
|
|
|
|
2019-06-06 09:00:13 +00:00
|
|
|
// 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
|
|
|
|
static EXTENSIONS: &[&str] = &["zip"];
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
static ref METADATA: AdapterMeta = AdapterMeta {
|
|
|
|
name: "zip".to_owned(),
|
|
|
|
version: 1,
|
2019-06-07 22:04:48 +00:00
|
|
|
description: "Reads a zip file as a stream and recurses down into its contents".to_owned(),
|
2019-06-16 10:19:01 +00:00
|
|
|
recurses: true,
|
2019-06-11 11:34:04 +00:00
|
|
|
fast_matchers: EXTENSIONS
|
2019-06-06 09:00:13 +00:00
|
|
|
.iter()
|
2019-06-11 11:34:04 +00:00
|
|
|
.map(|s| FastMatcher::FileExtension(s.to_string()))
|
2019-06-06 09:00:13 +00:00
|
|
|
.collect(),
|
2019-06-11 12:40:58 +00:00
|
|
|
slow_matchers: Some(vec![SlowMatcher::MimeType("application/zip".to_owned())])
|
2019-06-06 09:00:13 +00:00
|
|
|
};
|
|
|
|
}
|
2019-06-06 21:43:30 +00:00
|
|
|
#[derive(Default)]
|
2019-06-06 09:00:13 +00:00
|
|
|
pub struct ZipAdapter;
|
|
|
|
|
|
|
|
impl ZipAdapter {
|
|
|
|
pub fn new() -> ZipAdapter {
|
|
|
|
ZipAdapter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl GetMetadata for ZipAdapter {
|
2019-06-06 21:43:30 +00:00
|
|
|
fn metadata(&self) -> &AdapterMeta {
|
2019-06-06 09:00:13 +00:00
|
|
|
&METADATA
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-06 14:48:31 +00:00
|
|
|
// https://github.com/mvdnes/zip-rs/commit/b9af51e654793931af39f221f143b9dea524f349
|
|
|
|
fn is_dir(f: &ZipFile) -> bool {
|
|
|
|
f.name()
|
|
|
|
.chars()
|
|
|
|
.rev()
|
|
|
|
.next()
|
|
|
|
.map_or(false, |c| c == '/' || c == '\\')
|
|
|
|
}
|
|
|
|
|
2019-06-06 09:00:13 +00:00
|
|
|
impl FileAdapter for ZipAdapter {
|
2019-06-16 10:19:01 +00:00
|
|
|
fn adapt(&self, ai: AdaptInfo, _detection_reason: &SlowMatcher) -> Fallible<()> {
|
2019-06-06 09:00:13 +00:00
|
|
|
let AdaptInfo {
|
|
|
|
filepath_hint,
|
|
|
|
mut inp,
|
|
|
|
oup,
|
|
|
|
line_prefix,
|
2019-06-07 13:43:19 +00:00
|
|
|
archive_recursion_depth,
|
2019-06-07 17:00:24 +00:00
|
|
|
config,
|
2019-06-06 09:00:13 +00:00
|
|
|
..
|
|
|
|
} = ai;
|
|
|
|
loop {
|
|
|
|
match ::zip::read::read_zipfile_from_stream(&mut inp) {
|
|
|
|
Ok(None) => break,
|
|
|
|
Ok(Some(mut file)) => {
|
2019-06-06 14:48:31 +00:00
|
|
|
if is_dir(&file) {
|
|
|
|
continue;
|
|
|
|
}
|
2019-06-06 09:00:13 +00:00
|
|
|
eprintln!(
|
2019-06-07 18:12:24 +00:00
|
|
|
"{}{}|{}: {} bytes ({} bytes packed)",
|
|
|
|
line_prefix,
|
2019-06-06 09:00:13 +00:00
|
|
|
filepath_hint.to_string_lossy(),
|
|
|
|
file.name(),
|
|
|
|
file.size(),
|
|
|
|
file.compressed_size()
|
|
|
|
);
|
2019-06-06 21:43:30 +00:00
|
|
|
let line_prefix = &format!("{}{}: ", line_prefix, file.name());
|
2019-06-07 17:00:24 +00:00
|
|
|
rga_preproc(AdaptInfo {
|
|
|
|
filepath_hint: &file.sanitized_name(),
|
|
|
|
is_real_file: false,
|
|
|
|
inp: &mut file,
|
|
|
|
oup,
|
|
|
|
line_prefix,
|
|
|
|
archive_recursion_depth: archive_recursion_depth + 1,
|
2019-06-07 18:12:24 +00:00
|
|
|
config: config.clone(),
|
2019-06-07 17:00:24 +00:00
|
|
|
})?;
|
2019-06-06 09:00:13 +00:00
|
|
|
}
|
|
|
|
Err(e) => return Err(e.into()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|