mirror of
https://github.com/redstrate/Auracite.git
synced 2025-07-01 01:57:45 +00:00
Fix the outstanding warnings
This commit is contained in:
parent
1ade743f82
commit
c3f4679c4b
6 changed files with 88 additions and 91 deletions
|
@ -27,7 +27,7 @@ serde = { version = "1.0", features = ["derive"], default-features = false }
|
||||||
regex = { version = "1.11", default-features = false, features = ["unicode-perl"] }
|
regex = { version = "1.11", default-features = false, features = ["unicode-perl"] }
|
||||||
|
|
||||||
# Used to generate the HTML page to easily preview your exported data
|
# Used to generate the HTML page to easily preview your exported data
|
||||||
minijinja = { version = "2.11", default-features = false }
|
minijinja = { version = "2.11", features = ["serde"], default-features = false }
|
||||||
|
|
||||||
# Download files
|
# Download files
|
||||||
reqwest = { version = "0.12" }
|
reqwest = { version = "0.12" }
|
||||||
|
@ -38,7 +38,7 @@ zip = { version = "4.2", default-features = false }
|
||||||
# Exporting propietary game data
|
# Exporting propietary game data
|
||||||
physis = { git = "https://github.com/redstrate/Physis" }
|
physis = { git = "https://github.com/redstrate/Physis" }
|
||||||
|
|
||||||
# Encoding the character archive to base64 so the browser can download it and decoding the base64 images from the c lient
|
# Encoding the character archive to base64 so the browser can download it and decoding the base64 images from the client
|
||||||
base64 = { version = "0.22", default-features = false }
|
base64 = { version = "0.22", default-features = false }
|
||||||
|
|
||||||
# Not used directly by us, but to disable the "std" feature and is used by the scraper crate.
|
# Not used directly by us, but to disable the "std" feature and is used by the scraper crate.
|
||||||
|
|
|
@ -51,7 +51,7 @@ pub struct BackendRust {}
|
||||||
|
|
||||||
impl bridge::Backend {
|
impl bridge::Backend {
|
||||||
pub fn archive_character_by_name(
|
pub fn archive_character_by_name(
|
||||||
mut self: Pin<&mut Self>,
|
self: Pin<&mut Self>,
|
||||||
character_name: &QString,
|
character_name: &QString,
|
||||||
use_dalamud: bool,
|
use_dalamud: bool,
|
||||||
filename: &QString,
|
filename: &QString,
|
||||||
|
@ -83,7 +83,7 @@ impl bridge::Backend {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn archive_character_by_id(
|
pub fn archive_character_by_id(
|
||||||
mut self: Pin<&mut Self>,
|
self: Pin<&mut Self>,
|
||||||
character_id: &QString,
|
character_id: &QString,
|
||||||
use_dalamud: bool,
|
use_dalamud: bool,
|
||||||
filename: &QString,
|
filename: &QString,
|
||||||
|
|
|
@ -66,7 +66,7 @@ fn main() {
|
||||||
&QUrl::from(&QString::from("https://redstrate.com/rss-image.png")),
|
&QUrl::from(&QString::from("https://redstrate.com/rss-image.png")),
|
||||||
));
|
));
|
||||||
|
|
||||||
KAboutData::set_application_data(&*about_data);
|
KAboutData::set_application_data(&about_data);
|
||||||
QGuiApplication::set_desktop_file_name(&QString::from("zone.xiv.auracite"));
|
QGuiApplication::set_desktop_file_name(&QString::from("zone.xiv.auracite"));
|
||||||
|
|
||||||
let mut command_line_parser = QCommandLineParser::default();
|
let mut command_line_parser = QCommandLineParser::default();
|
||||||
|
@ -91,7 +91,7 @@ fn main() {
|
||||||
command_line_parser.add_option(&dalamud_option);
|
command_line_parser.add_option(&dalamud_option);
|
||||||
|
|
||||||
command_line_parser.process(&QStringList::from(&QList::from(
|
command_line_parser.process(&QStringList::from(&QList::from(
|
||||||
&args().map(|x| QString::from(x)).collect::<Vec<QString>>(),
|
&args().map(QString::from).collect::<Vec<QString>>(),
|
||||||
)));
|
)));
|
||||||
about_data
|
about_data
|
||||||
.as_mut()
|
.as_mut()
|
||||||
|
@ -102,15 +102,16 @@ fn main() {
|
||||||
.value(&QString::from("name"))
|
.value(&QString::from("name"))
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
println!("Downloading character data for {}...", character_name);
|
println!("Downloading character data for {character_name}...");
|
||||||
|
|
||||||
let id = search_character_blocking(&character_name).expect("Couldn't find character!");
|
let id = search_character_blocking(&character_name).expect("Couldn't find character!");
|
||||||
|
|
||||||
archive_character_blocking(
|
archive_character_blocking(
|
||||||
id,
|
id,
|
||||||
command_line_parser.is_set(&QString::from("dalamud")),
|
command_line_parser.is_set(&QString::from("dalamud")),
|
||||||
&format!("{}.zip", character_name),
|
&format!("{character_name}.zip"),
|
||||||
);
|
)
|
||||||
|
.expect("Failed to archive the requested character!");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -122,13 +123,14 @@ fn main() {
|
||||||
.parse()
|
.parse()
|
||||||
.expect("Not a valid ID!");
|
.expect("Not a valid ID!");
|
||||||
|
|
||||||
println!("Downloading character data for {}...", id);
|
println!("Downloading character data for {id}...");
|
||||||
|
|
||||||
archive_character_blocking(
|
archive_character_blocking(
|
||||||
id,
|
id,
|
||||||
command_line_parser.is_set(&QString::from("dalamud")),
|
command_line_parser.is_set(&QString::from("dalamud")),
|
||||||
&format!("{}.zip", id), // TODO: give it the character's name
|
&format!("{id}.zip"), // TODO: give it the character's name
|
||||||
);
|
)
|
||||||
|
.expect("Failed to archive the requested character!");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
44
src/lib.rs
44
src/lib.rs
|
@ -10,12 +10,11 @@ use crate::downloader::download;
|
||||||
use crate::html::{create_character_html, create_plate_html};
|
use crate::html::{create_character_html, create_plate_html};
|
||||||
use crate::parser::parse_search;
|
use crate::parser::parse_search;
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
use data::{Appearance, Currencies};
|
use data::Appearance;
|
||||||
use package::Package;
|
use package::Package;
|
||||||
use physis::savedata::chardat;
|
use physis::savedata::chardat;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
use serde::Deserialize;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
#[cfg(target_family = "wasm")]
|
#[cfg(target_family = "wasm")]
|
||||||
|
@ -124,7 +123,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
LODESTONE_HOST
|
LODESTONE_HOST
|
||||||
};
|
};
|
||||||
|
|
||||||
let char_page_url = Url::parse(&format!("{lodestone_host}/lodestone/character/{}/", id))
|
let char_page_url = Url::parse(&format!("{lodestone_host}/lodestone/character/{id}/"))
|
||||||
.map_err(|_| ArchiveError::UnknownError)?;
|
.map_err(|_| ArchiveError::UnknownError)?;
|
||||||
let char_page = download(&char_page_url)
|
let char_page = download(&char_page_url)
|
||||||
.await
|
.await
|
||||||
|
@ -135,8 +134,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
parser::parse_profile(&char_page, &mut char_data);
|
parser::parse_profile(&char_page, &mut char_data);
|
||||||
|
|
||||||
let classjob_page_url = Url::parse(&format!(
|
let classjob_page_url = Url::parse(&format!(
|
||||||
"{lodestone_host}/lodestone/character/{}/class_job/",
|
"{lodestone_host}/lodestone/character/{id}/class_job/"
|
||||||
id
|
|
||||||
))
|
))
|
||||||
.map_err(|_| ArchiveError::UnknownError)?;
|
.map_err(|_| ArchiveError::UnknownError)?;
|
||||||
let classjob_page = download(&classjob_page_url)
|
let classjob_page = download(&classjob_page_url)
|
||||||
|
@ -160,14 +158,14 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
} else {
|
} else {
|
||||||
&char_data.portrait_url
|
&char_data.portrait_url
|
||||||
};
|
};
|
||||||
let portrait_url = Url::parse(&portrait_url).map_err(|_| ArchiveError::UnknownError)?;
|
let portrait_url = Url::parse(portrait_url).map_err(|_| ArchiveError::UnknownError)?;
|
||||||
|
|
||||||
let portrait = download(&portrait_url)
|
let portrait = download(&portrait_url)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| ArchiveError::DownloadFailed(portrait_url.to_string()))?;
|
.map_err(|_| ArchiveError::DownloadFailed(portrait_url.to_string()))?;
|
||||||
|
|
||||||
zip.start_file("portrait.jpg", options)?;
|
zip.start_file("portrait.jpg", options)?;
|
||||||
zip.write_all(&*portrait)?;
|
zip.write_all(&portrait)?;
|
||||||
}
|
}
|
||||||
if !char_data.face_url.is_empty() {
|
if !char_data.face_url.is_empty() {
|
||||||
let face_url = if cfg!(target_family = "wasm") {
|
let face_url = if cfg!(target_family = "wasm") {
|
||||||
|
@ -175,26 +173,26 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
} else {
|
} else {
|
||||||
&char_data.face_url
|
&char_data.face_url
|
||||||
};
|
};
|
||||||
let face_url = Url::parse(&face_url).map_err(|_| ArchiveError::UnknownError)?;
|
let face_url = Url::parse(face_url).map_err(|_| ArchiveError::UnknownError)?;
|
||||||
|
|
||||||
let face = download(&face_url)
|
let face = download(&face_url)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| ArchiveError::DownloadFailed(face_url.to_string()))?;
|
.map_err(|_| ArchiveError::DownloadFailed(face_url.to_string()))?;
|
||||||
|
|
||||||
zip.start_file("face.jpg", options)?;
|
zip.start_file("face.jpg", options)?;
|
||||||
zip.write_all(&*face)?;
|
zip.write_all(&face)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if use_dalamud {
|
if use_dalamud {
|
||||||
let dalamud_url = Url::parse(&"http://localhost:42072/package")
|
let dalamud_url =
|
||||||
.map_err(|_| ArchiveError::UnknownError)?;
|
Url::parse("http://localhost:42072/package").map_err(|_| ArchiveError::UnknownError)?;
|
||||||
let package = download(&dalamud_url)
|
let package = download(&dalamud_url)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| ArchiveError::CouldNotConnectToDalamud)?;
|
.map_err(|_| ArchiveError::CouldNotConnectToDalamud)?;
|
||||||
let package = String::from_utf8(package).map_err(|_| ArchiveError::ParsingError)?;
|
let package = String::from_utf8(package).map_err(|_| ArchiveError::ParsingError)?;
|
||||||
// Remove BOM at the start
|
// Remove BOM at the start
|
||||||
let package = package.trim_start_matches("\u{feff}");
|
let package = package.trim_start_matches("\u{feff}");
|
||||||
let package: Package = serde_json::from_str(&package.trim_start()).unwrap();
|
let package: Package = serde_json::from_str(package.trim_start()).unwrap();
|
||||||
|
|
||||||
// appearance data
|
// appearance data
|
||||||
char_data.appearance = Some(Appearance {
|
char_data.appearance = Some(Appearance {
|
||||||
|
@ -264,7 +262,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
|
|
||||||
zip.start_file("plate-portrait.png", options)?;
|
zip.start_file("plate-portrait.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(
|
.decode(
|
||||||
package
|
package
|
||||||
.portrait
|
.portrait
|
||||||
|
@ -276,7 +274,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
if let Some(base_plate) = package.base_plate {
|
if let Some(base_plate) = package.base_plate {
|
||||||
zip.start_file("base-plate.png", options)?;
|
zip.start_file("base-plate.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(base_plate.trim_start_matches("data:image/png;base64,"))
|
.decode(base_plate.trim_start_matches("data:image/png;base64,"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -285,7 +283,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
if let Some(pattern_overlay) = package.pattern_overlay {
|
if let Some(pattern_overlay) = package.pattern_overlay {
|
||||||
zip.start_file("pattern-overlay.png", options)?;
|
zip.start_file("pattern-overlay.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(pattern_overlay.trim_start_matches("data:image/png;base64,"))
|
.decode(pattern_overlay.trim_start_matches("data:image/png;base64,"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -294,7 +292,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
if let Some(backing) = package.backing {
|
if let Some(backing) = package.backing {
|
||||||
zip.start_file("backing.png", options)?;
|
zip.start_file("backing.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(backing.trim_start_matches("data:image/png;base64,"))
|
.decode(backing.trim_start_matches("data:image/png;base64,"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -303,7 +301,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
if let Some(top_border) = package.top_border {
|
if let Some(top_border) = package.top_border {
|
||||||
zip.start_file("top-border.png", options)?;
|
zip.start_file("top-border.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(top_border.trim_start_matches("data:image/png;base64,"))
|
.decode(top_border.trim_start_matches("data:image/png;base64,"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -312,7 +310,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
if let Some(bottom_border) = package.bottom_border {
|
if let Some(bottom_border) = package.bottom_border {
|
||||||
zip.start_file("bottom-border.png", options)?;
|
zip.start_file("bottom-border.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(bottom_border.trim_start_matches("data:image/png;base64,"))
|
.decode(bottom_border.trim_start_matches("data:image/png;base64,"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -321,7 +319,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
if let Some(portrait_frame) = package.portrait_frame {
|
if let Some(portrait_frame) = package.portrait_frame {
|
||||||
zip.start_file("portrait-frame.png", options)?;
|
zip.start_file("portrait-frame.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(portrait_frame.trim_start_matches("data:image/png;base64,"))
|
.decode(portrait_frame.trim_start_matches("data:image/png;base64,"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -330,7 +328,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
if let Some(plate_frame) = package.plate_frame {
|
if let Some(plate_frame) = package.plate_frame {
|
||||||
zip.start_file("plate-frame.png", options)?;
|
zip.start_file("plate-frame.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(plate_frame.trim_start_matches("data:image/png;base64,"))
|
.decode(plate_frame.trim_start_matches("data:image/png;base64,"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -339,7 +337,7 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
if let Some(accent) = package.accent {
|
if let Some(accent) = package.accent {
|
||||||
zip.start_file("accent.png", options)?;
|
zip.start_file("accent.png", options)?;
|
||||||
zip.write_all(
|
zip.write_all(
|
||||||
&*BASE64_STANDARD
|
&BASE64_STANDARD
|
||||||
.decode(accent.trim_start_matches("data:image/png;base64,"))
|
.decode(accent.trim_start_matches("data:image/png;base64,"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
|
@ -388,11 +386,11 @@ pub async fn archive_character(id: u64, use_dalamud: bool) -> Result<Vec<u8>, Ar
|
||||||
};
|
};
|
||||||
|
|
||||||
zip.start_file("FFXIV_CHARA_01.dat", options)?;
|
zip.start_file("FFXIV_CHARA_01.dat", options)?;
|
||||||
zip.write_all(&*char_dat.write_to_buffer().unwrap())?;
|
zip.write_all(&char_dat.write_to_buffer().unwrap())?;
|
||||||
|
|
||||||
// Stop the HTTP server
|
// Stop the HTTP server
|
||||||
let stop_url =
|
let stop_url =
|
||||||
Url::parse(&"http://localhost:42072/stop").map_err(|_| ArchiveError::UnknownError)?;
|
Url::parse("http://localhost:42072/stop").map_err(|_| ArchiveError::UnknownError)?;
|
||||||
// I'm intentionally ignoring the message because it doesn't matter if it fails - and it usually does
|
// I'm intentionally ignoring the message because it doesn't matter if it fails - and it usually does
|
||||||
let _ = download(&stop_url).await;
|
let _ = download(&stop_url).await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,18 +17,16 @@ pub fn parse_search(data: &str) -> String {
|
||||||
let mut href = String::new();
|
let mut href = String::new();
|
||||||
|
|
||||||
for element in document.select(&Selector::parse(ENTRY_SELECTOR).unwrap()) {
|
for element in document.select(&Selector::parse(ENTRY_SELECTOR).unwrap()) {
|
||||||
if let Some(block_name) = element
|
if let Some(_) = element
|
||||||
.select(&Selector::parse(ENTRY_NAME_SELECTOR).unwrap())
|
.select(&Selector::parse(ENTRY_NAME_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
&& let Some(block_name) = element
|
||||||
if let Some(block_name) = element
|
|
||||||
.select(&Selector::parse("a.entry__link").unwrap())
|
.select(&Selector::parse("a.entry__link").unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
href = block_name.attr("href").unwrap().parse().unwrap();
|
href = block_name.attr("href").unwrap().parse().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
href
|
href
|
||||||
}
|
}
|
||||||
|
@ -54,34 +52,35 @@ pub fn parse_profile(data: &str, char_data: &mut CharacterData) {
|
||||||
|
|
||||||
if let Some(title) = document
|
if let Some(title) = document
|
||||||
.select(&Selector::parse(TITLE_SELECTOR).unwrap())
|
.select(&Selector::parse(TITLE_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
char_data.title = Some(title.inner_html().as_str().to_string());
|
char_data.title = Some(title.inner_html().as_str().to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let world_re = Regex::new(r"(\w+)\s\[(\w+)\]").unwrap();
|
||||||
for element in document.select(&Selector::parse(WORLD_DATA_CENTER_SELECTOR).unwrap()) {
|
for element in document.select(&Selector::parse(WORLD_DATA_CENTER_SELECTOR).unwrap()) {
|
||||||
let re = Regex::new(r"(\w+)\s\[(\w+)\]").unwrap();
|
|
||||||
let inner_html = element.inner_html();
|
let inner_html = element.inner_html();
|
||||||
let captures = re.captures(&inner_html).unwrap();
|
let captures = world_re.captures(&inner_html).unwrap();
|
||||||
// TODO: use error
|
// TODO: use error
|
||||||
char_data.world = WorldValue::try_from(captures.get(1).unwrap().as_str()).unwrap();
|
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();
|
char_data.data_center = captures.get(2).unwrap().as_str().to_owned();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let block_re = Regex::new(r"([^<]+)<br>([^\/]+)\s\/\s(\W)").unwrap();
|
||||||
|
let grand_re = Regex::new(r"([^\/]+)\s\/\s([^\/]+)").unwrap();
|
||||||
for element in document.select(&Selector::parse(CHARACTER_BLOCK_SELECTOR).unwrap()) {
|
for element in document.select(&Selector::parse(CHARACTER_BLOCK_SELECTOR).unwrap()) {
|
||||||
if let Some(block_title) = element
|
if let Some(block_title) = element
|
||||||
.select(&Selector::parse(CHARACTER_BLOCK_TITLE_SELECTOR).unwrap())
|
.select(&Selector::parse(CHARACTER_BLOCK_TITLE_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
let name = block_title.inner_html();
|
let name = block_title.inner_html();
|
||||||
if name == "Race/Clan/Gender" {
|
if name == "Race/Clan/Gender" {
|
||||||
if let Some(block_name) = element
|
if let Some(block_name) = element
|
||||||
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
let re = Regex::new(r"([^<]+)<br>([^\/]+)\s\/\s(\W)").unwrap();
|
|
||||||
let inner_html = block_name.inner_html();
|
let inner_html = block_name.inner_html();
|
||||||
let captures = re.captures(&inner_html).unwrap();
|
let captures = block_re.captures(&inner_html).unwrap();
|
||||||
|
|
||||||
char_data.race =
|
char_data.race =
|
||||||
RaceValue::try_from(captures.get(1).unwrap().as_str()).unwrap();
|
RaceValue::try_from(captures.get(1).unwrap().as_str()).unwrap();
|
||||||
|
@ -93,7 +92,7 @@ pub fn parse_profile(data: &str, char_data: &mut CharacterData) {
|
||||||
} else if name == "City-state" {
|
} else if name == "City-state" {
|
||||||
if let Some(block_name) = element
|
if let Some(block_name) = element
|
||||||
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
char_data.city_state =
|
char_data.city_state =
|
||||||
CityStateValue::try_from(block_name.inner_html().as_str()).unwrap();
|
CityStateValue::try_from(block_name.inner_html().as_str()).unwrap();
|
||||||
|
@ -106,29 +105,27 @@ pub fn parse_profile(data: &str, char_data: &mut CharacterData) {
|
||||||
|
|
||||||
if let Some(block_name) = element
|
if let Some(block_name) = element
|
||||||
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
char_data.guardian =
|
char_data.guardian =
|
||||||
GuardianValue::try_from(block_name.inner_html().as_str()).unwrap();
|
GuardianValue::try_from(block_name.inner_html().as_str()).unwrap();
|
||||||
}
|
}
|
||||||
} else if name == "Grand Company" {
|
} else if name == "Grand Company"
|
||||||
if let Some(block_name) = element
|
&& let Some(block_name) = element
|
||||||
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
.select(&Selector::parse(CHARACTER_BLOCK_NAME_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
let re = Regex::new(r"([^\/]+)\s\/\s([^\/]+)").unwrap();
|
|
||||||
let inner_html = block_name.inner_html();
|
let inner_html = block_name.inner_html();
|
||||||
let captures = re.captures(&inner_html).unwrap();
|
let captures = grand_re.captures(&inner_html).unwrap();
|
||||||
|
|
||||||
char_data.grand_company.name = captures.get(1).unwrap().as_str().to_string();
|
char_data.grand_company.name = captures.get(1).unwrap().as_str().to_string();
|
||||||
char_data.grand_company.rank = captures.get(2).unwrap().as_str().to_string();
|
char_data.grand_company.rank = captures.get(2).unwrap().as_str().to_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(free_company) = element
|
if let Some(free_company) = element
|
||||||
.select(&Selector::parse(FREE_COMPANY_SELECTOR).unwrap())
|
.select(&Selector::parse(FREE_COMPANY_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
char_data.free_company = Some(free_company.inner_html().as_str().to_string());
|
char_data.free_company = Some(free_company.inner_html().as_str().to_string());
|
||||||
}
|
}
|
||||||
|
@ -138,9 +135,9 @@ pub fn parse_profile(data: &str, char_data: &mut CharacterData) {
|
||||||
char_data.face_url = element.attr("src").unwrap().parse().unwrap();
|
char_data.face_url = element.attr("src").unwrap().parse().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
for element in document
|
if let Some(element) = document
|
||||||
.select(&Selector::parse(PORTRAIT_IMG_SELECTOR).unwrap())
|
.select(&Selector::parse(PORTRAIT_IMG_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
char_data.portrait_url = element.attr("src").unwrap().parse().unwrap();
|
char_data.portrait_url = element.attr("src").unwrap().parse().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -163,8 +160,9 @@ pub fn parse_profile(data: &str, char_data: &mut CharacterData) {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (i, selector) in item_slot_selectors.iter().enumerate() {
|
for (i, selector) in item_slot_selectors.iter().enumerate() {
|
||||||
if let Some(slot) = document.select(&Selector::parse(selector).unwrap()).nth(0) {
|
if let Some(slot) = document.select(&Selector::parse(selector).unwrap()).next()
|
||||||
if let Some(item) = slot.select(&Selector::parse(".db-tooltip").unwrap()).nth(0) {
|
&& let Some(item) = slot.select(&Selector::parse(".db-tooltip").unwrap()).next()
|
||||||
|
{
|
||||||
let parsed_item = parse_item_tooltip(&item);
|
let parsed_item = parse_item_tooltip(&item);
|
||||||
let slot = match i {
|
let slot = match i {
|
||||||
0 => &mut char_data.equipped.main_hand,
|
0 => &mut char_data.equipped.main_hand,
|
||||||
|
@ -186,7 +184,6 @@ pub fn parse_profile(data: &str, char_data: &mut CharacterData) {
|
||||||
*slot = parsed_item;
|
*slot = parsed_item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CLASSJOB_SELECTOR: &str = ".character__job > li";
|
const CLASSJOB_SELECTOR: &str = ".character__job > li";
|
||||||
|
@ -201,15 +198,15 @@ pub fn parse_classjob(data: &str, char_data: &mut CharacterData) {
|
||||||
for element in document.select(&Selector::parse(CLASSJOB_SELECTOR).unwrap()) {
|
for element in document.select(&Selector::parse(CLASSJOB_SELECTOR).unwrap()) {
|
||||||
let level = element
|
let level = element
|
||||||
.select(&Selector::parse(CLASSJOB_LEVEL_SELECTOR).unwrap())
|
.select(&Selector::parse(CLASSJOB_LEVEL_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let name = element
|
let name = element
|
||||||
.select(&Selector::parse(CLASSJOB_NAME_SELECTOR).unwrap())
|
.select(&Selector::parse(CLASSJOB_NAME_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let exp_element = element
|
let exp_element = element
|
||||||
.select(&Selector::parse(CLASSJOB_EXP_SELECTOR).unwrap())
|
.select(&Selector::parse(CLASSJOB_EXP_SELECTOR).unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut exp = None;
|
let mut exp = None;
|
||||||
|
@ -234,7 +231,7 @@ pub fn parse_classjob(data: &str, char_data: &mut CharacterData) {
|
||||||
fn parse_item_tooltip(element: &scraper::ElementRef<'_>) -> Option<ItemValue> {
|
fn parse_item_tooltip(element: &scraper::ElementRef<'_>) -> Option<ItemValue> {
|
||||||
if let Some(slot) = element
|
if let Some(slot) = element
|
||||||
.select(&Selector::parse(".db-tooltip__item__name").unwrap())
|
.select(&Selector::parse(".db-tooltip__item__name").unwrap())
|
||||||
.nth(0)
|
.next()
|
||||||
{
|
{
|
||||||
let mut text: String = slot.text().collect();
|
let mut text: String = slot.text().collect();
|
||||||
if text.contains("\u{e03c}") {
|
if text.contains("\u{e03c}") {
|
||||||
|
|
|
@ -283,7 +283,7 @@ impl TryFrom<&str> for NamedayValue {
|
||||||
|
|
||||||
fn try_from(value: &str) -> Result<Self, ArchiveError> {
|
fn try_from(value: &str) -> Result<Self, ArchiveError> {
|
||||||
let re = Regex::new(r"(\d{1,2})[^\d]+(\d{1,2})").unwrap();
|
let re = Regex::new(r"(\d{1,2})[^\d]+(\d{1,2})").unwrap();
|
||||||
let captures = re.captures(&value).unwrap();
|
let captures = re.captures(value).unwrap();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
value: value.to_string(),
|
value: value.to_string(),
|
||||||
|
|
Loading…
Add table
Reference in a new issue