Various fixes to errors that occurred during runs
Don't crash if metadata link 404s. If extracting file from zip fails, try using linux unzip command instead. This fixes errors due to deflate64 compression.
This commit is contained in:
parent
5514fb5d29
commit
4e500f0b0b
90
src/main.rs
90
src/main.rs
@ -9,6 +9,7 @@ use std::env;
|
|||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::Seek;
|
use std::io::Seek;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
|
use std::process::Command;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
use tokio::io::{AsyncReadExt, AsyncSeekExt};
|
use tokio::io::{AsyncReadExt, AsyncSeekExt};
|
||||||
@ -189,16 +190,34 @@ pub async fn main() -> Result<()> {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let Some(contains_plugin) =
|
match nexus_api::metadata::contains_plugin(&client, &api_file).await {
|
||||||
nexus_api::metadata::contains_plugin(&client, &api_file).await?
|
Ok(contains_plugin) => {
|
||||||
{
|
if let Some(contains_plugin) = contains_plugin {
|
||||||
if !contains_plugin {
|
if !contains_plugin {
|
||||||
info!("file metadata does not contain a plugin, skip downloading");
|
info!("file metadata does not contain a plugin, skip downloading");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn!("file has no metadata link");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
} else {
|
Err(err) => {
|
||||||
warn!("file has no metadata link");
|
if let Some(reqwest_err) = err.downcast_ref::<reqwest::Error>() {
|
||||||
}
|
if reqwest_err.status() == Some(StatusCode::NOT_FOUND) {
|
||||||
|
warn!(
|
||||||
|
status = ?reqwest_err.status(),
|
||||||
|
"metadata for file not found on server"
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}?;
|
||||||
|
|
||||||
let download_link_resp =
|
let download_link_resp =
|
||||||
nexus_api::download_link::get(&client, db_mod.nexus_mod_id, api_file.file_id)
|
nexus_api::download_link::get(&client, db_mod.nexus_mod_id, api_file.file_id)
|
||||||
@ -208,7 +227,6 @@ pub async fn main() -> Result<()> {
|
|||||||
if reqwest_err.status() == Some(StatusCode::NOT_FOUND) {
|
if reqwest_err.status() == Some(StatusCode::NOT_FOUND) {
|
||||||
warn!(
|
warn!(
|
||||||
status = ?reqwest_err.status(),
|
status = ?reqwest_err.status(),
|
||||||
file_id = api_file.file_id,
|
|
||||||
"failed to get download link for file"
|
"failed to get download link for file"
|
||||||
);
|
);
|
||||||
file::update_has_download_link(&pool, db_file.id, false).await?;
|
file::update_has_download_link(&pool, db_file.id, false).await?;
|
||||||
@ -255,8 +273,8 @@ pub async fn main() -> Result<()> {
|
|||||||
if let Ok(list) = list {
|
if let Ok(list) = list {
|
||||||
for entry in list {
|
for entry in list {
|
||||||
if let Ok(entry) = entry {
|
if let Ok(entry) = entry {
|
||||||
if entry.is_file() && (
|
if entry.is_file()
|
||||||
entry.filename.ends_with(".esp")
|
&& (entry.filename.ends_with(".esp")
|
||||||
|| entry.filename.ends_with(".esm")
|
|| entry.filename.ends_with(".esm")
|
||||||
|| entry.filename.ends_with(".esl"))
|
|| entry.filename.ends_with(".esl"))
|
||||||
{
|
{
|
||||||
@ -324,7 +342,53 @@ pub async fn main() -> Result<()> {
|
|||||||
file.seek(SeekFrom::Start(0))?;
|
file.seek(SeekFrom::Start(0))?;
|
||||||
let mut buf = Vec::default();
|
let mut buf = Vec::default();
|
||||||
info!("uncompressing plugin file from downloaded archive");
|
info!("uncompressing plugin file from downloaded archive");
|
||||||
uncompress_archive_file(&mut file, &mut buf, file_name)?;
|
match uncompress_archive_file(&mut file, &mut buf, file_name) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(err) => {
|
||||||
|
if kind.mime_type() == "application/zip" {
|
||||||
|
// compress_tools or libarchive failed to extract zip file (e.g. archive is deflate64 compressed)
|
||||||
|
// Attempt to uncompress the archive using `unzip` unix command instead
|
||||||
|
warn!(error = %err, "failed to extract file with compress_tools, extracting whole archive with unzip instead");
|
||||||
|
file.seek(SeekFrom::Start(0))?;
|
||||||
|
let temp_dir = tempdir()?;
|
||||||
|
let temp_file_path = temp_dir
|
||||||
|
.path()
|
||||||
|
.join(format!("download.{}", kind.extension()));
|
||||||
|
let mut temp_file = std::fs::File::create(&temp_file_path)?;
|
||||||
|
std::io::copy(&mut file, &mut temp_file)?;
|
||||||
|
let extracted_path = temp_dir.path().join("extracted");
|
||||||
|
|
||||||
|
Command::new("unzip")
|
||||||
|
.args(&[
|
||||||
|
&temp_file_path.to_string_lossy(),
|
||||||
|
"-d",
|
||||||
|
&extracted_path.to_string_lossy(),
|
||||||
|
])
|
||||||
|
.status()?;
|
||||||
|
|
||||||
|
for file_name in plugin_file_paths.iter() {
|
||||||
|
info!(
|
||||||
|
?file_name,
|
||||||
|
"processing uncompressed file from downloaded archive"
|
||||||
|
);
|
||||||
|
let mut plugin_buf =
|
||||||
|
std::fs::read(extracted_path.join(file_name))?;
|
||||||
|
process_plugin(
|
||||||
|
&mut plugin_buf,
|
||||||
|
&pool,
|
||||||
|
&mut plugins_archive,
|
||||||
|
&db_file,
|
||||||
|
&db_mod,
|
||||||
|
file_name,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
}?;
|
||||||
process_plugin(
|
process_plugin(
|
||||||
&mut buf,
|
&mut buf,
|
||||||
&pool,
|
&pool,
|
||||||
|
Loading…
Reference in New Issue
Block a user