mirror of
https://github.com/redstrate/Auracite.git
synced 2025-05-02 00:47:45 +00:00
Start giving numerical values/ids for fields when possible
This makes it easier to build tools off of, such as Kawari which needs the internal ID for things.
This commit is contained in:
parent
236731374a
commit
90a2eeda8a
5 changed files with 336 additions and 29 deletions
18
src/data.rs
18
src/data.rs
|
@ -1,5 +1,9 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::value::{
|
||||
CityStateValue, GenderValue, GuardianValue, NamedayValue, RaceValue, TribeValue, WorldValue,
|
||||
};
|
||||
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct Currencies {
|
||||
pub gil: u32,
|
||||
|
@ -38,14 +42,14 @@ pub struct Appearance {
|
|||
#[derive(Default, Serialize)]
|
||||
pub struct CharacterData {
|
||||
pub name: String,
|
||||
pub world: String,
|
||||
pub world: WorldValue,
|
||||
pub data_center: String,
|
||||
pub city_state: String,
|
||||
pub nameday: String,
|
||||
pub guardian: String,
|
||||
pub race: String,
|
||||
pub gender: String,
|
||||
pub tribe: String,
|
||||
pub city_state: CityStateValue,
|
||||
pub nameday: NamedayValue,
|
||||
pub guardian: GuardianValue,
|
||||
pub race: RaceValue,
|
||||
pub gender: GenderValue,
|
||||
pub tribe: TribeValue,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub currencies: Option<Currencies>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
14
src/html.rs
14
src/html.rs
|
@ -14,13 +14,13 @@ pub fn create_character_html(char_data: &CharacterData) -> String {
|
|||
template
|
||||
.render(context! {
|
||||
name => char_data.name,
|
||||
world => char_data.world,
|
||||
world => char_data.world.name,
|
||||
data_center => char_data.data_center,
|
||||
race => char_data.race,
|
||||
subrace => char_data.tribe,
|
||||
gender => char_data.gender,
|
||||
nameday => char_data.nameday,
|
||||
city_state => char_data.city_state
|
||||
race => char_data.race.name,
|
||||
subrace => char_data.tribe.name,
|
||||
gender => char_data.gender.name,
|
||||
nameday => char_data.nameday.value,
|
||||
city_state => char_data.city_state.name
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ pub fn create_plate_html(char_data: &CharacterData) -> String {
|
|||
template
|
||||
.render(context! {
|
||||
name => char_data.name,
|
||||
world => char_data.world,
|
||||
world => char_data.world.name,
|
||||
data_center => char_data.data_center,
|
||||
title => char_data.plate_title,
|
||||
level => char_data.plate_classjob_level,
|
||||
|
|
|
@ -3,6 +3,7 @@ pub mod downloader;
|
|||
pub mod html;
|
||||
pub mod package;
|
||||
pub mod parser;
|
||||
pub mod value;
|
||||
|
||||
use crate::data::CharacterData;
|
||||
use crate::downloader::download;
|
||||
|
@ -168,9 +169,9 @@ pub async fn archive_character(
|
|||
|
||||
// appearance data
|
||||
char_data.appearance = Some(Appearance {
|
||||
race: char_data.race.clone(),
|
||||
tribe: char_data.tribe.clone(),
|
||||
gender: char_data.gender.clone(),
|
||||
race: char_data.race.name.clone(),
|
||||
tribe: char_data.tribe.name.clone(),
|
||||
gender: char_data.gender.name.clone(),
|
||||
model_type: package.model_type,
|
||||
height: package.height,
|
||||
face_type: package.face_type,
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
use crate::data::CharacterData;
|
||||
use crate::{
|
||||
data::CharacterData,
|
||||
value::{
|
||||
CityStateValue, GenderValue, GuardianValue, NamedayValue, RaceValue, TribeValue, WorldValue,
|
||||
},
|
||||
};
|
||||
use regex::Regex;
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
|
@ -50,7 +55,8 @@ pub fn parse_lodestone(data: &str) -> CharacterData {
|
|||
let re = Regex::new(r"(\w+)\s\[(\w+)\]").unwrap();
|
||||
let inner_html = element.inner_html();
|
||||
let captures = re.captures(&inner_html).unwrap();
|
||||
char_data.world = captures.get(1).unwrap().as_str().to_owned();
|
||||
// TODO: use error
|
||||
char_data.world = WorldValue::try_from(captures.get(1).unwrap().as_str()).unwrap();
|
||||
char_data.data_center = captures.get(2).unwrap().as_str().to_owned();
|
||||
}
|
||||
|
||||
|
@ -69,31 +75,33 @@ pub fn parse_lodestone(data: &str) -> CharacterData {
|
|||
let inner_html = block_name.inner_html();
|
||||
let captures = re.captures(&inner_html).unwrap();
|
||||
|
||||
char_data.race = captures.get(1).unwrap().as_str().to_owned();
|
||||
char_data.tribe = captures.get(2).unwrap().as_str().to_owned();
|
||||
if captures.get(3).unwrap().as_str() == "♀" {
|
||||
char_data.gender = "Female".parse().unwrap();
|
||||
} else {
|
||||
char_data.gender = "Male".parse().unwrap();
|
||||
}
|
||||
char_data.race =
|
||||
RaceValue::try_from(captures.get(1).unwrap().as_str()).unwrap();
|
||||
char_data.tribe =
|
||||
TribeValue::try_from(captures.get(2).unwrap().as_str()).unwrap();
|
||||
char_data.gender =
|
||||
GenderValue::try_from(captures.get(3).unwrap().as_str()).unwrap();
|
||||
}
|
||||
} else if name == "City-state" {
|
||||
if let Some(block_name) = element
|
||||
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
||||
.nth(0)
|
||||
{
|
||||
char_data.city_state = block_name.inner_html();
|
||||
char_data.city_state =
|
||||
CityStateValue::try_from(block_name.inner_html().as_str()).unwrap();
|
||||
}
|
||||
} else if name == "Nameday" {
|
||||
for element in element.select(&Selector::parse(NAMEDAY_SELECTOR).unwrap()) {
|
||||
char_data.nameday = element.inner_html();
|
||||
char_data.nameday =
|
||||
NamedayValue::try_from(element.inner_html().as_str()).unwrap();
|
||||
}
|
||||
|
||||
if let Some(block_name) = element
|
||||
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
||||
.nth(0)
|
||||
{
|
||||
char_data.guardian = block_name.inner_html();
|
||||
char_data.guardian =
|
||||
GuardianValue::try_from(block_name.inner_html().as_str()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
294
src/value.rs
Normal file
294
src/value.rs
Normal file
|
@ -0,0 +1,294 @@
|
|||
use regex::Regex;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::ArchiveError;
|
||||
|
||||
// TODO: does it make sense to implement Default?
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct WorldValue {
|
||||
/// Name of the world.
|
||||
pub name: String,
|
||||
/// Internal ID of the world.
|
||||
pub value: i32,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for WorldValue {
|
||||
type Error = ArchiveError;
|
||||
|
||||
fn try_from(name: &str) -> Result<Self, ArchiveError> {
|
||||
let value = match name {
|
||||
"Adamantoise" => 73,
|
||||
"Cactuar" => 79,
|
||||
"Faerie" => 54,
|
||||
"Gilgamesh" => 63,
|
||||
"Jenova" => 40,
|
||||
"Midgardsormr" => 65,
|
||||
"Sargatanas" => 99,
|
||||
"Siren" => 57,
|
||||
"Balmung" => 91,
|
||||
"Brynhildr" => 34,
|
||||
"Coeurl" => 74,
|
||||
"Diabolos" => 62,
|
||||
"Goblin" => 81,
|
||||
"Malboro" => 75,
|
||||
"Mateus" => 37,
|
||||
"Zalera" => 41,
|
||||
"Behemoth" => 78,
|
||||
"Excalibur" => 93,
|
||||
"Exodus" => 53,
|
||||
"Famfrit" => 35,
|
||||
"Hyperion" => 95,
|
||||
"Lamia" => 55,
|
||||
"Leviathan" => 64,
|
||||
"Ultros" => 77,
|
||||
"Halicarnassus" => 406,
|
||||
"Maduin" => 407,
|
||||
"Marilith" => 404,
|
||||
"Seraph" => 405,
|
||||
"Cuchulainn" => 408,
|
||||
"Golem" => 411,
|
||||
"Kraken" => 409,
|
||||
"Rafflesia" => 410,
|
||||
"Cerberus" => 80,
|
||||
"Louisoix" => 83,
|
||||
"Moogle" => 71,
|
||||
"Omega" => 39,
|
||||
"Phantom" => 401,
|
||||
"Ragnarok" => 97,
|
||||
"Sagittarius" => 400,
|
||||
"Spriggan" => 85,
|
||||
"Alpha" => 402,
|
||||
"Lich" => 36,
|
||||
"Odin" => 66,
|
||||
"Phoenix" => 56,
|
||||
"Raiden" => 403,
|
||||
"Shiva" => 67,
|
||||
"Twintania" => 33,
|
||||
"Zodiark" => 42,
|
||||
"Aegis" => 90,
|
||||
"Atomos" => 68,
|
||||
"Carbuncle" => 45,
|
||||
"Garuda" => 58,
|
||||
"Gungnir" => 94,
|
||||
"Kujata" => 49,
|
||||
"Tonberry" => 72,
|
||||
"Typhon" => 50,
|
||||
"Alexander" => 43,
|
||||
"Bahamut" => 69,
|
||||
"Durandal" => 92,
|
||||
"Fenrir" => 46,
|
||||
"Ifrit" => 59,
|
||||
"Ridill" => 98,
|
||||
"Tiamat" => 76,
|
||||
"Ultima" => 51,
|
||||
"Anima" => 44,
|
||||
"Asura" => 23,
|
||||
"Chocobo" => 70,
|
||||
"Hades" => 47,
|
||||
"Ixion" => 48,
|
||||
"Masamune" => 96,
|
||||
"Pandaemonium" => 28,
|
||||
"Titan" => 61,
|
||||
"Belias" => 24,
|
||||
"Mandragora" => 82,
|
||||
"Ramuh" => 60,
|
||||
"Shinryu" => 29,
|
||||
"Unicorn" => 30,
|
||||
"Valefor" => 52,
|
||||
"Yojimbo" => 31,
|
||||
"Zeromus" => 32,
|
||||
"Bismarck" => 22,
|
||||
"Ravana" => 21,
|
||||
"Sephirot" => 86,
|
||||
"Sophia" => 87,
|
||||
"Zurvan" => 88,
|
||||
_ => return Err(ArchiveError::ParsingError),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name: name.to_string(),
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct CityStateValue {
|
||||
/// Name of the city-state.
|
||||
pub name: String,
|
||||
/// Internal ID of the city-state.
|
||||
pub value: i32,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for CityStateValue {
|
||||
type Error = ArchiveError;
|
||||
|
||||
fn try_from(name: &str) -> Result<Self, ArchiveError> {
|
||||
let value = match name {
|
||||
"Limsa Lominsa" => 1,
|
||||
"Gridania" => 2,
|
||||
"Ul'dah" => 3,
|
||||
_ => return Err(ArchiveError::ParsingError),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name: name.to_string(),
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct GenderValue {
|
||||
/// Name of the gender.
|
||||
pub name: String,
|
||||
/// Internal ID of the gender.
|
||||
pub value: i32,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for GenderValue {
|
||||
type Error = ArchiveError;
|
||||
|
||||
fn try_from(name: &str) -> Result<Self, ArchiveError> {
|
||||
let (value, name) = match name {
|
||||
"♂" => (0, "Male"),
|
||||
"♀" => (1, "Female"),
|
||||
_ => return Err(ArchiveError::ParsingError),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name: name.to_string(),
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct RaceValue {
|
||||
/// Name of the race.
|
||||
pub name: String,
|
||||
/// Internal ID of the race.
|
||||
pub value: i32,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for RaceValue {
|
||||
type Error = ArchiveError;
|
||||
|
||||
fn try_from(name: &str) -> Result<Self, ArchiveError> {
|
||||
let value = match name {
|
||||
"Hyur" => 1,
|
||||
"Elezen" => 2,
|
||||
"Lalafell" => 3,
|
||||
"Miqote" => 4,
|
||||
"Roegadyn" => 5,
|
||||
"AuRa" => 6,
|
||||
"Hrothgar" => 7,
|
||||
"Viera" => 8,
|
||||
_ => return Err(ArchiveError::ParsingError),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name: name.to_string(),
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct TribeValue {
|
||||
/// Name of the tribe.
|
||||
pub name: String,
|
||||
/// Internal ID of the tribe.
|
||||
pub value: i32,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for TribeValue {
|
||||
type Error = ArchiveError;
|
||||
|
||||
fn try_from(name: &str) -> Result<Self, ArchiveError> {
|
||||
let value = match name {
|
||||
"Midlander" => 1,
|
||||
"Highlander" => 2,
|
||||
"Wildwood" => 3,
|
||||
"Duskwight" => 4,
|
||||
"Plainsfolk" => 5,
|
||||
"Dunesfolk" => 6,
|
||||
"Seeker" => 7,
|
||||
"Keeper" => 8,
|
||||
"SeaWolf" => 9,
|
||||
"Hellsguard" => 10,
|
||||
"Raen" => 11,
|
||||
"Xaela" => 12,
|
||||
"Hellion" => 13,
|
||||
"Lost" => 14,
|
||||
"Rava" => 15,
|
||||
"Veena" => 16,
|
||||
_ => return Err(ArchiveError::ParsingError),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name: name.to_string(),
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct GuardianValue {
|
||||
/// Name of the guardian.
|
||||
pub name: String,
|
||||
/// Internal ID of the guardian.
|
||||
pub value: i32,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for GuardianValue {
|
||||
type Error = ArchiveError;
|
||||
|
||||
fn try_from(name: &str) -> Result<Self, ArchiveError> {
|
||||
let value = match name {
|
||||
"Halone, the Fury" => 1,
|
||||
"Menphina, the Lover" => 2,
|
||||
"Thaliak, the Scholar" => 3,
|
||||
"Nymeia, the Spinner" => 4,
|
||||
"Llymlaen, the Navigator" => 5,
|
||||
"Oschon, the Wanderer" => 6,
|
||||
"Byregot, the Builder" => 7,
|
||||
"Rhalgr, the Destroyer" => 8,
|
||||
"Azeyma, the Warden" => 9,
|
||||
"Nald'thal, the Traders" => 10,
|
||||
"Nophica, the Matron" => 11,
|
||||
"Althyk, the Keeper" => 12,
|
||||
_ => return Err(ArchiveError::ParsingError),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
name: name.to_string(),
|
||||
value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct NamedayValue {
|
||||
/// String represenation of your nameday.
|
||||
pub value: String,
|
||||
/// Day part of your nameday.
|
||||
pub day: i32,
|
||||
/// Month part of your nameday.
|
||||
pub month: i32,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for NamedayValue {
|
||||
type Error = ArchiveError;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, ArchiveError> {
|
||||
let re = Regex::new(r"(\d{1,2})[^\d]+(\d{1,2})").unwrap();
|
||||
let captures = re.captures(&value).unwrap();
|
||||
|
||||
Ok(Self {
|
||||
value: value.to_string(),
|
||||
day: captures.get(1).unwrap().as_str().parse::<i32>().unwrap(),
|
||||
month: captures.get(2).unwrap().as_str().parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue