1
Fork 0
mirror of https://github.com/redstrate/Auracite.git synced 2025-04-25 05:57:44 +00:00
auracite/src/lib.rs

137 lines
4.4 KiB
Rust
Raw Normal View History

pub mod data;
pub mod downloader;
pub mod html;
pub mod parser;
use clap::Parser;
use serde::Deserialize;
use std::convert::Infallible;
use std::fs::{read, write};
use std::path::Path;
use std::sync::{Arc, Mutex};
use touche::server::Service;
use touche::{Body, HttpBody, Request, Response, Server, StatusCode};
use wasm_bindgen::prelude::wasm_bindgen;
use crate::downloader::download;
use crate::html::write_html;
use crate::parser::parse_search;
const LODESTONE_HOST: &str = "https://na.finalfantasyxiv.com";
#[derive(Default, Deserialize, Clone)]
struct Package {
playtime: String,
height: i32,
bust_size: i32,
gil: u32,
is_battle_mentor: bool,
is_trade_mentor: bool,
is_novice: bool,
is_returner: bool,
player_commendations: i32,
}
#[derive(Clone)]
struct PackageService<'a> {
wants_stop: Arc<Mutex<bool>>, // TODO: THIS IS TERRIBLE STOP STOP STOP
package: &'a Arc<Mutex<Package>>,
}
impl Service for PackageService<'_> {
type Body = &'static str;
type Error = Infallible;
fn call(&self, req: Request<Body>) -> Result<Response<Self::Body>, Self::Error> {
*self.package.lock().unwrap() = serde_json::from_str(&String::from_utf8(req.into_body().into_bytes().unwrap()).unwrap()).unwrap();
*self.wants_stop.lock().unwrap() = true;
Ok(Response::builder()
.status(StatusCode::OK)
.body("")
.unwrap())
}
// TODO: NO NO NO NO
fn wants_stop(&self) -> bool {
*self.wants_stop.lock().unwrap()
}
}
#[wasm_bindgen]
pub extern fn archive_character(character_name: &str, use_dalamud: bool) {
let search_page_path = Path::new("/tmp/search.html");
download(
&format!("{LODESTONE_HOST}/lodestone/character/?q={}", character_name),
search_page_path,
)
.expect("Failed to download the search page from the Lodestone.");
let href = parse_search(&String::from_utf8(read(search_page_path).unwrap()).unwrap());
if href.is_empty() {
println!("Unable to find character!");
}
let char_page_path = Path::new("/tmp/character.html");
download(&format!("{LODESTONE_HOST}{}", href), char_page_path)
.expect("Failed to download the character page from the Lodestone.");
let mut char_data = crate::parser::parse_lodestone(&String::from_utf8(read(char_page_path).unwrap()).unwrap());
let character_folder = Path::new(&character_name);
if !character_folder.exists() {
std::fs::create_dir(character_folder).unwrap();
}
if !char_data.portrait_url.is_empty() {
download(
&char_data.portrait_url,
&character_folder.join("portrait.jpg"),
)
.expect("Failed to download the character portrait image.");
}
if !char_data.face_url.is_empty() {
download(&char_data.face_url, &character_folder.join("face.jpg"))
.expect("Failed to download the character face image.");
}
if use_dalamud {
println!("Now waiting for the Dalamud plugin. Type /auracite begin in chat.");
let package = Arc::new(Mutex::new(Package::default()));
Server::bind("0.0.0.0:8000").serve_single_thread(PackageService { wants_stop: Arc::new(Mutex::new(false)), package: &package }).unwrap();
let package = &*package.lock().unwrap();
char_data.playtime = package.playtime.parse().unwrap();
char_data.appearance.height = package.height;
char_data.appearance.bust_size = package.bust_size;
char_data.currencies.gil = package.gil; // TODO: also fetch from the lodestone
char_data.is_battle_mentor = package.is_battle_mentor;
char_data.is_trade_mentor = package.is_trade_mentor;
char_data.is_novice = package.is_novice;
char_data.is_returner = package.is_returner;
char_data.player_commendations = package.player_commendations; // TODO: fetch from the lodestone?
}
let serialized = serde_json::to_string(&char_data).unwrap();
write(character_folder.join("character.json"), serialized)
.expect("Failed to write the character JSON file.");
println!(
"Download complete! The archive is located at: {}",
character_folder.file_name().unwrap().to_str().unwrap()
);
write_html(
&char_data,
&character_folder
.join("character.html")
.into_os_string()
.into_string()
.unwrap(),
)
.expect("Failed to write the character HTML file.");
}