Using ureq to download files

I might just throw out the TempFile thing - should actually save them somewhere. As
I think it would likely be useful for testing too
This commit is contained in:
2025-08-13 20:22:49 +01:00
parent 6b4105ecd9
commit 906aaa1e59
5 changed files with 587 additions and 366 deletions

View File

@@ -1,8 +1,83 @@
use chrono::NaiveDate;
use serde::Deserialize;
use serde_json::Value;
use std::fs;
use std::io::{Read, Seek, SeekFrom, Write};
use tempfile::NamedTempFile;
use ureq;
use uuid::Uuid;
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct ScryfallBulkData {
pub id: Uuid,
pub uri: String,
#[serde(rename = "type")]
pub stype: String,
pub name: String,
pub description: String,
pub download_uri: String,
pub updated_at: String,
pub content_type: String,
pub content_encoding: String,
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct ScryfallBulk {
pub object: String,
pub has_more: bool,
pub data: Vec<ScryfallBulkData>,
}
#[derive(Deserialize, PartialEq, Debug)]
pub enum ScryfallBulkType {
#[serde(rename = "oracle_cards")]
OracleCards,
#[serde(rename = "unique_artwork")]
UniqueArtwork,
#[serde(rename = "default_cards")]
DefaultCards,
#[serde(rename = "all_cards")]
AllCards,
#[serde(rename = "rulings")]
Rulings,
}
const SCRYFALL_BULK_API: &str = "https://api.scryfall.com/bulk-data";
pub fn download_latest(
_stype: ScryfallBulkType,
mut dest_file: &NamedTempFile,
) -> Result<(), Box<dyn std::error::Error>> {
let bulk_body: ScryfallBulk = ureq::get(SCRYFALL_BULK_API)
.header("User-Agent", "Arthur's Card Finger Testing v0.1")
.header("Accept", "application/json")
.call()?
.body_mut()
.read_json::<ScryfallBulk>()?;
let mut download_uri = String::new();
for scryfall_bulk in bulk_body.data {
// TODO: Actually implement getting different types
if scryfall_bulk.stype == "oracle_cards" {
download_uri = scryfall_bulk.download_uri;
}
}
assert!(!download_uri.is_empty());
let cards_response = ureq::get(download_uri)
.header("User-Agent", "Arthur's Card Finger Testing v0.1")
.header("Accept", "application/json")
.call()?
.body_mut()
.with_config()
.limit(700 * 1024 * 1024)
.read_to_string()?;
write!(dest_file, "{}", cards_response)?;
Ok(())
}
// Info from here:
// https://scryfall.com/docs/api/cards
#[allow(dead_code)]
@@ -110,7 +185,6 @@ struct ScryfallCard {
pub watermark: Option<String>,
pub preview: Option<Preview>,
// These aren't in the Scryfall docs, but some cards do have 'em
pub foil: Option<bool>,
pub nonfoil: Option<bool>,
@@ -785,4 +859,14 @@ mod tests {
let ac = fs::read_to_string(f).unwrap();
let _ac: Vec<ScryfallCard> = serde_json::from_str(&ac).unwrap();
}
#[test]
#[ignore]
fn get_scryfall_bulk_page() {
let mut file = NamedTempFile::new().unwrap();
let _ = download_latest(ScryfallBulkType::OracleCards, &file);
let file_size = file.seek(SeekFrom::End(0)).unwrap();
assert!(file_size > 4092);
println!("File size: {}", file_size);
}
}