Refactor main.rs into separate files
Create new `commands` mod with file for each command line option. Create a couple more extractor files for moving 7zip and unrar methods into.
This commit is contained in:
@@ -7,6 +7,10 @@ use std::io::Seek;
|
||||
use std::io::SeekFrom;
|
||||
use tracing::{info, info_span};
|
||||
|
||||
use crate::models::file::File;
|
||||
use crate::models::game_mod::Mod;
|
||||
use crate::plugin_processor::process_plugin;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExtractorError;
|
||||
|
||||
@@ -78,3 +82,19 @@ impl<'a> Iterator for Extractor<'a> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn extract_with_compress_tools(
|
||||
file: &mut std::fs::File,
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
db_file: &File,
|
||||
db_mod: &Mod,
|
||||
) -> Result<()> {
|
||||
let extractor = Extractor::new(file);
|
||||
for plugin in extractor.into_iter() {
|
||||
let (file_path, mut plugin_buf) = plugin?;
|
||||
let plugin_span = info_span!("plugin", name = ?file_path);
|
||||
let _plugin_span = plugin_span.enter();
|
||||
process_plugin(&mut plugin_buf, &pool, &db_file, &db_mod, &file_path).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1 +1,7 @@
|
||||
pub mod compress_tools;
|
||||
pub mod seven_zip;
|
||||
pub mod unrar;
|
||||
|
||||
pub use self::compress_tools::extract_with_compress_tools;
|
||||
pub use self::unrar::extract_with_unrar;
|
||||
pub use seven_zip::extract_with_7zip;
|
||||
|
||||
61
src/extractors/seven_zip.rs
Normal file
61
src/extractors/seven_zip.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use anyhow::Result;
|
||||
use std::io::{Seek, SeekFrom};
|
||||
use std::process::Command;
|
||||
use tempfile::tempdir;
|
||||
use tracing::{info, info_span};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::models::file::File;
|
||||
use crate::models::game_mod::Mod;
|
||||
use crate::plugin_processor::process_plugin;
|
||||
|
||||
pub async fn extract_with_7zip(
|
||||
file: &mut std::fs::File,
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
db_file: &File,
|
||||
db_mod: &Mod,
|
||||
) -> Result<()> {
|
||||
file.seek(SeekFrom::Start(0))?;
|
||||
let temp_dir = tempdir()?;
|
||||
let temp_file_path = temp_dir.path().join("download.zip");
|
||||
let mut temp_file = std::fs::File::create(&temp_file_path)?;
|
||||
std::io::copy(file, &mut temp_file)?;
|
||||
drop(temp_file); // close handle to temp file so 7zip process can open it
|
||||
let extracted_path = temp_dir.path().join("extracted");
|
||||
|
||||
Command::new("7z")
|
||||
.args(&[
|
||||
"x",
|
||||
&format!("-o{}", &extracted_path.to_string_lossy()),
|
||||
&temp_file_path.to_string_lossy().to_string(),
|
||||
])
|
||||
.status()?;
|
||||
|
||||
for entry in WalkDir::new(&extracted_path)
|
||||
.contents_first(true)
|
||||
.into_iter()
|
||||
.filter_entry(|e| {
|
||||
if let Some(extension) = e.path().extension() {
|
||||
extension == "esp" || extension == "esm" || extension == "esl"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
{
|
||||
let entry = entry?;
|
||||
let file_path = entry.path();
|
||||
let plugin_span = info_span!("plugin", name = ?file_path);
|
||||
let _plugin_span = plugin_span.enter();
|
||||
info!("processing uncompressed file from downloaded archive");
|
||||
let mut plugin_buf = std::fs::read(extracted_path.join(file_path))?;
|
||||
process_plugin(
|
||||
&mut plugin_buf,
|
||||
&pool,
|
||||
&db_file,
|
||||
&db_mod,
|
||||
&file_path.to_string_lossy(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
88
src/extractors/unrar.rs
Normal file
88
src/extractors/unrar.rs
Normal file
@@ -0,0 +1,88 @@
|
||||
use anyhow::Result;
|
||||
use tempfile::tempdir;
|
||||
use tracing::{error, info, warn};
|
||||
use unrar::Archive;
|
||||
|
||||
use crate::models::file::{self, File};
|
||||
use crate::models::game_mod::Mod;
|
||||
use crate::plugin_processor::process_plugin;
|
||||
|
||||
pub async fn extract_with_unrar(
|
||||
file: &mut std::fs::File,
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
db_file: &File,
|
||||
db_mod: &Mod,
|
||||
checked_metadata: bool,
|
||||
) -> Result<()> {
|
||||
let temp_dir = tempdir()?;
|
||||
let temp_file_path = temp_dir.path().join("download.rar");
|
||||
let mut temp_file = std::fs::File::create(&temp_file_path)?;
|
||||
std::io::copy(file, &mut temp_file)?;
|
||||
|
||||
let mut plugin_file_paths = Vec::new();
|
||||
let list = Archive::new(&temp_file_path.to_string_lossy().to_string())?.list();
|
||||
match list {
|
||||
Ok(list) => {
|
||||
for entry in list.flatten() {
|
||||
if let Some(extension) = entry.filename.extension() {
|
||||
if entry.is_file()
|
||||
&& (extension == "esp" || extension == "esm" || extension == "esl")
|
||||
{
|
||||
plugin_file_paths.push(entry.filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
if !checked_metadata {
|
||||
warn!("failed to read archive and server has no metadata, skipping file");
|
||||
file::update_unable_to_extract_plugins(&pool, db_file.id, true).await?;
|
||||
return Ok(());
|
||||
} else {
|
||||
error!("failed to read archive, but server had metadata");
|
||||
panic!("failed to read archive, but server had metadata");
|
||||
}
|
||||
}
|
||||
}
|
||||
info!(
|
||||
num_plugin_files = plugin_file_paths.len(),
|
||||
"listed plugins in downloaded archive"
|
||||
);
|
||||
|
||||
if !plugin_file_paths.is_empty() {
|
||||
info!("uncompressing downloaded archive");
|
||||
let extract = Archive::new(&temp_file_path.to_string_lossy().to_string())?
|
||||
.extract_to(temp_dir.path().to_string_lossy().to_string());
|
||||
|
||||
let mut extract = match extract {
|
||||
Err(err) => {
|
||||
warn!(error = %err, "failed to extract with unrar");
|
||||
file::update_unable_to_extract_plugins(&pool, db_file.id, true).await?;
|
||||
return Ok(());
|
||||
}
|
||||
Ok(extract) => extract,
|
||||
};
|
||||
if let Err(err) = extract.process() {
|
||||
warn!(error = %err, "failed to extract with unrar");
|
||||
file::update_unable_to_extract_plugins(&pool, db_file.id, true).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for file_path in plugin_file_paths.iter() {
|
||||
info!(
|
||||
?file_path,
|
||||
"processing uncompressed file from downloaded archive"
|
||||
);
|
||||
let mut plugin_buf = std::fs::read(temp_dir.path().join(file_path))?;
|
||||
process_plugin(
|
||||
&mut plugin_buf,
|
||||
&pool,
|
||||
&db_file,
|
||||
&db_mod,
|
||||
&file_path.to_string_lossy(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user