Update to pull from scryfall

This commit is contained in:
shylie 2026-01-15 00:28:57 -05:00
parent 9444bdd9b7
commit 5b985bd5ff
3 changed files with 1759 additions and 18 deletions

1675
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -6,3 +6,5 @@ edition = "2024"
[dependencies]
nusb = "0.2.1"
image = { version = "0.25.9", features = ["png"], default-features = false }
reqwest = { version = "0.13.1", features = ["blocking", "json"] }
serde = { version = "1.0.228", features = ["derive"] }

View File

@ -1,8 +1,10 @@
use image::imageops::FilterType;
use image::ImageError;
use image::{EncodableLayout, ImageError};
use nusb::transfer::{Bulk, Out, TransferError};
use nusb::MaybeFuture;
use nusb::{list_devices, ErrorKind};
use reqwest::header::ACCEPT;
use serde::Deserialize;
use std::env;
use std::fmt::{Display, Formatter};
use std::io::Write;
@ -51,12 +53,80 @@ impl From<ImageError> for Error {
}
}
impl From<reqwest::Error> for Error {
fn from(_: reqwest::Error) -> Self {
Error {
message: "Error retrieving card info"
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}
#[derive(Deserialize)]
struct ImageUris {
pub png: String
}
#[derive(Deserialize)]
struct ScryfallCardInfo {
pub cmc: f32,
pub colors: Vec<String>,
pub name: String,
pub image_uris: ImageUris
}
struct RelevantCardInfo {
pub cmc: u8,
pub colors: u8,
pub name: String,
pub image: Vec<u8>
}
fn get_relevant_card_info(set_code: &str, collector_number: &str) -> Result<RelevantCardInfo, Error> {
let client = reqwest::blocking::ClientBuilder::new()
.user_agent("Digital MtG Token/0.1.0")
.build()?;
let card_uri = format!("https://api.scryfall.com/cards/{set_code}/{collector_number}");
let response = client.get(card_uri).header(ACCEPT, "*/*").send()?;
let card_info: ScryfallCardInfo = response.json()?;
let card_image = client.get(&card_info.image_uris.png).header(ACCEPT, "*/*").send()?.bytes()?.to_vec();
let mut colors = 0;
for color in &card_info.colors {
match color.as_str() {
"W" => {
colors |= 0b10000;
},
"U" => {
colors |= 0b1000;
},
"B" => {
colors |= 0b100;
},
"R" => {
colors |= 0b10;
},
"G" => {
colors |= 0b1;
}
_ => {}
}
}
Ok(RelevantCardInfo {
cmc: card_info.cmc.trunc() as u8,
colors,
name: card_info.name.to_ascii_lowercase(),
image: card_image
})
}
fn main() -> Result<(), Error> {
let device = list_devices().wait()?
.find(|dev| dev.vendor_id() == 0xCAFE && dev.product_id() == 0xCA6D)
@ -71,21 +141,35 @@ fn main() -> Result<(), Error> {
if args.len() == 1 {
writer.write(&[0x42])?;
writer.flush()?;
} else {
}
else {
let slash_position = args[1].find("/").ok_or(Error {
message: "Error retrieving card info"
})?;
let set_code = &args[1][0..slash_position];
let collectors_number = &args[1][slash_position + 1..];
let relevant_info = get_relevant_card_info(set_code, collectors_number)?;
// converted mana cost
writer.write(&[20])?;
writer.write(&[relevant_info.cmc])?;
// colors
writer.write(&[0b11111])?;
writer.write(&[relevant_info.colors])?;
let name = relevant_info.name.as_str();
let name_len = if name.len() >= 32 { 31 } else { name.len() };
// length of card name
writer.write(&[0])?;
writer.write(&[name_len as u8])?;
// name of card
writer.write(name[0..name_len].as_bytes())?;
let img = image::open(&args[1])?;
let img = image::load_from_memory(relevant_info.image.as_bytes())?;
let img = img.crop_imm(28, 28, img.width() - 56, img.height() - 56);
let img = img.resize_exact(240, 320, FilterType::Gaussian);
let img = img.resize_exact(240, 320, FilterType::Lanczos3);
let img = img.into_rgb8();
// image of card