Reset main.rs back w/ fix to listing RAR files

This commit is contained in:
Tyler Hallada 2021-07-26 17:02:14 -04:00
parent 5d62fb7d61
commit f62324d36c
2 changed files with 271 additions and 279 deletions

View File

@ -222,105 +222,98 @@ pub async fn main() -> Result<()> {
while has_next_page { while has_next_page {
let page_span = info_span!("page", page); let page_span = info_span!("page", page);
let _page_span = page_span.enter(); let _page_span = page_span.enter();
// let mod_list_resp = nexus_scraper::get_mod_list_page(&client, page).await?; let mod_list_resp = nexus_scraper::get_mod_list_page(&client, page).await?;
// let scraped = mod_list_resp.scrape_mods()?; let scraped = mod_list_resp.scrape_mods()?;
// TODO: delete has_next_page = scraped.has_next_page;
has_next_page = false; let present_mods = game_mod::bulk_get_present_nexus_mod_ids(
// has_next_page = scraped.has_next_page; &pool,
// let present_mods = game_mod::bulk_get_present_nexus_mod_ids( &scraped
// &pool, .mods
// &scraped .iter()
// .mods .map(|scraped_mod| scraped_mod.nexus_mod_id)
// .iter() .collect::<Vec<i32>>(),
// .map(|scraped_mod| scraped_mod.nexus_mod_id) )
// .collect::<Vec<i32>>(), .await?;
// ) let mods_to_create: Vec<UnsavedMod> = scraped
// .await?; .mods
// let mods_to_create: Vec<UnsavedMod> = scraped .iter()
// .mods .filter(|scraped_mod| !present_mods.contains(&scraped_mod.nexus_mod_id))
// .iter() .map(|scraped_mod| UnsavedMod {
// .filter(|scraped_mod| !present_mods.contains(&scraped_mod.nexus_mod_id)) name: scraped_mod.name,
// .map(|scraped_mod| UnsavedMod { nexus_mod_id: scraped_mod.nexus_mod_id,
// name: scraped_mod.name, author: scraped_mod.author,
// nexus_mod_id: scraped_mod.nexus_mod_id, category: scraped_mod.category,
// author: scraped_mod.author, description: scraped_mod.desc,
// category: scraped_mod.category, game_id: game.id,
// description: scraped_mod.desc, })
// game_id: game.id, .collect();
// })
// .collect();
// let mods = game_mod::batched_insert(&pool, &mods_to_create).await?; let mods = game_mod::batched_insert(&pool, &mods_to_create).await?;
for db_file in file::get_files_that_need_backfill(&pool).await? { for db_mod in mods {
let db_mod = game_mod::get(&pool, db_file.mod_id)
.await?
.expect("a mod to exist for file");
let mod_span = info_span!("mod", name = ?&db_mod.name, id = &db_mod.nexus_mod_id); let mod_span = info_span!("mod", name = ?&db_mod.name, id = &db_mod.nexus_mod_id);
let _mod_span = mod_span.enter(); let _mod_span = mod_span.enter();
// let files_resp = nexus_api::files::get(&client, db_mod.nexus_mod_id).await?; let files_resp = nexus_api::files::get(&client, db_mod.nexus_mod_id).await?;
// debug!(duration = ?files_resp.wait, "sleeping"); debug!(duration = ?files_resp.wait, "sleeping");
// sleep(files_resp.wait).await; sleep(files_resp.wait).await;
// Filter out replaced/deleted files (indicated by null category) and archived files // Filter out replaced/deleted files (indicated by null category) and archived files
// let files = files_resp let files = files_resp
// .files()? .files()?
// .into_iter() .into_iter()
// .filter(|file| match file.category { .filter(|file| match file.category {
// None => { None => {
// info!( info!(
// name = file.file_name, name = file.file_name,
// id = file.file_id, id = file.file_id,
// "skipping file with no category" "skipping file with no category"
// ); );
// false false
// } }
// Some(category) if category == "ARCHIVED" => false, Some(category) if category == "ARCHIVED" => false,
// Some(_) => true, Some(_) => true,
// }); });
// for api_file in files { for api_file in files {
let file_span = info_span!("file", id = &db_file.nexus_file_id); let file_span =
info_span!("file", name = &api_file.file_name, id = &api_file.file_id);
let _file_span = file_span.enter(); let _file_span = file_span.enter();
// let db_file = file::insert( let db_file = file::insert(
// &pool, &pool,
// api_file.name, api_file.name,
// api_file.file_name, api_file.file_name,
// api_file.file_id as i32, api_file.file_id as i32,
// db_mod.id, db_mod.id,
// api_file.category, api_file.category,
// api_file.version, api_file.version,
// api_file.mod_version, api_file.mod_version,
// api_file.size, api_file.size,
// api_file.uploaded_at, api_file.uploaded_at,
// )
// .await?;
// let mut checked_metadata = false;
// match nexus_api::metadata::contains_plugin(&client, &api_file).await {
// Ok(contains_plugin) => {
// if let Some(contains_plugin) = contains_plugin {
// checked_metadata = true;
// if !contains_plugin {
// info!("file metadata does not contain a plugin, skip downloading");
// continue;
// }
// } else {
// warn!("file has no metadata link, continuing with download");
// }
// }
// Err(err) => {
// warn!(error = %err, "error retreiving metadata for file, continuing with download");
// }
// };
let download_link_resp = nexus_api::download_link::get(
&client,
db_mod.nexus_mod_id,
db_file.nexus_file_id as i64,
) )
.await?;
let mut checked_metadata = false;
match nexus_api::metadata::contains_plugin(&client, &api_file).await {
Ok(contains_plugin) => {
if let Some(contains_plugin) = contains_plugin {
checked_metadata = true;
if !contains_plugin {
info!("file metadata does not contain a plugin, skip downloading");
continue;
}
} else {
warn!("file has no metadata link, continuing with download");
}
}
Err(err) => {
warn!(error = %err, "error retreiving metadata for file, continuing with download");
}
};
let download_link_resp =
nexus_api::download_link::get(&client, db_mod.nexus_mod_id, api_file.file_id)
.await; .await;
if let Err(err) = &download_link_resp { if let Err(err) = &download_link_resp {
if let Some(reqwest_err) = err.downcast_ref::<reqwest::Error>() { if let Some(reqwest_err) = err.downcast_ref::<reqwest::Error>() {
@ -336,7 +329,7 @@ pub async fn main() -> Result<()> {
} }
let download_link_resp = download_link_resp?; let download_link_resp = download_link_resp?;
let mut tokio_file = download_link_resp.download_file(&client).await?; let mut tokio_file = download_link_resp.download_file(&client).await?;
info!("download finished"); info!(bytes = api_file.size, "download finished");
initialize_plugins_archive(db_mod.nexus_mod_id, db_file.nexus_file_id)?; initialize_plugins_archive(db_mod.nexus_mod_id, db_file.nexus_file_id)?;
let mut plugins_archive = ZipWriter::new_append( let mut plugins_archive = ZipWriter::new_append(
@ -363,9 +356,7 @@ pub async fn main() -> Result<()> {
match kind.mime_type() { match kind.mime_type() {
"application/vnd.rar" => { "application/vnd.rar" => {
info!( info!("downloaded archive is RAR archive, attempt to uncompress entire archive");
"downloaded archive is RAR archive, attempt to uncompress entire archive"
);
// Use unrar to uncompress the entire .rar file to avoid bugs with compress_tools uncompressing certain .rar files: // Use unrar to uncompress the entire .rar file to avoid bugs with compress_tools uncompressing certain .rar files:
// https://github.com/libarchive/libarchive/issues/373, https://github.com/libarchive/libarchive/issues/1426 // https://github.com/libarchive/libarchive/issues/373, https://github.com/libarchive/libarchive/issues/1426
tokio_file.seek(SeekFrom::Start(0)).await?; tokio_file.seek(SeekFrom::Start(0)).await?;
@ -376,7 +367,8 @@ pub async fn main() -> Result<()> {
std::io::copy(&mut file, &mut temp_file)?; std::io::copy(&mut file, &mut temp_file)?;
let mut plugin_file_paths = Vec::new(); let mut plugin_file_paths = Vec::new();
let list = Archive::new(&temp_file_path.to_string_lossy().to_string())?.list(); let list =
Archive::new(&temp_file_path.to_string_lossy().to_string())?.list();
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 {
@ -392,8 +384,13 @@ pub async fn main() -> Result<()> {
} }
} }
} else { } else {
warn!("failed to read archive, skipping file"); if !checked_metadata {
warn!("failed to read archive and server has no metadata, skipping file");
continue; continue;
} else {
error!("failed to read archive, but server had metadata");
panic!("failed to read archive, but server had metadata");
}
} }
info!( info!(
num_plugin_files = plugin_file_paths.len(), num_plugin_files = plugin_file_paths.len(),
@ -402,7 +399,8 @@ pub async fn main() -> Result<()> {
if plugin_file_paths.len() > 0 { if plugin_file_paths.len() > 0 {
info!("uncompressing downloaded archive"); info!("uncompressing downloaded archive");
let extract = Archive::new(&temp_file_path.to_string_lossy().to_string())? let extract =
Archive::new(&temp_file_path.to_string_lossy().to_string())?
.extract_to(temp_dir.path().to_string_lossy().to_string()); .extract_to(temp_dir.path().to_string_lossy().to_string());
extract extract
.expect("failed to extract") .expect("failed to extract")
@ -414,7 +412,8 @@ pub async fn main() -> Result<()> {
?file_path, ?file_path,
"processing uncompressed file from downloaded archive" "processing uncompressed file from downloaded archive"
); );
let mut plugin_buf = std::fs::read(temp_dir.path().join(file_path))?; let mut plugin_buf =
std::fs::read(temp_dir.path().join(file_path))?;
process_plugin( process_plugin(
&mut plugin_buf, &mut plugin_buf,
&pool, &pool,
@ -434,12 +433,17 @@ pub async fn main() -> Result<()> {
let mut plugin_file_paths = Vec::new(); let mut plugin_file_paths = Vec::new();
let archive_files = match list_archive_files(&file) { let archive_files = match list_archive_files(&file) {
Ok(files) => files, Ok(files) => Ok(files),
Err(err) => { Err(err) => {
warn!(error = %err, "failed to read archive, skipping file"); if !checked_metadata {
warn!(error = %err, "failed to read archive and server has no metadata, skipping file");
continue; continue;
} else {
error!(error = %err, "failed to read archive, but server had metadata");
Err(err)
} }
}; }
}?;
for file_path in archive_files { for file_path in archive_files {
if file_path.ends_with(".esp") if file_path.ends_with(".esp")
|| file_path.ends_with(".esm") || file_path.ends_with(".esm")
@ -485,11 +489,10 @@ pub async fn main() -> Result<()> {
.status()?; .status()?;
for file_path in plugin_file_paths.iter() { for file_path in plugin_file_paths.iter() {
let plugin_span = info_span!("plugin", name = ?file_path); let plugin_span =
info_span!("plugin", name = ?file_path);
let _plugin_span = plugin_span.enter(); let _plugin_span = plugin_span.enter();
info!( info!("processing uncompressed file from downloaded archive");
"processing uncompressed file from downloaded archive"
);
let mut plugin_buf = let mut plugin_buf =
std::fs::read(extracted_path.join(file_path))?; std::fs::read(extracted_path.join(file_path))?;
process_plugin( process_plugin(
@ -525,7 +528,7 @@ pub async fn main() -> Result<()> {
debug!(duration = ?download_link_resp.wait, "sleeping"); debug!(duration = ?download_link_resp.wait, "sleeping");
sleep(download_link_resp.wait).await; sleep(download_link_resp.wait).await;
} }
// } }
page += 1; page += 1;
debug!(?page, ?has_next_page, "sleeping 1 second"); debug!(?page, ?has_next_page, "sleeping 1 second");

View File

@ -91,14 +91,3 @@ pub async fn update_has_download_link(
.await .await
.context("Failed to update file") .context("Failed to update file")
} }
#[instrument(level = "debug", skip(pool))]
pub async fn get_files_that_need_backfill(pool: &sqlx::Pool<sqlx::Postgres>) -> Result<Vec<File>> {
sqlx::query_as!(
File,
"SELECT * FROM files WHERE created_at >= '2021-07-24 02:07:25' and file_name like '%.rar'",
)
.fetch_all(pool)
.await
.context("Failed to get files")
}