herta/extractor/
enemy.rs

1use super::{parse_html, parse_url};
2use crate::url::{canonicalize, get_original_image};
3use scraper::{Html, Selector};
4
5pub struct Enemy {
6    pub id: usize,
7    pub link: String,
8    pub name: String,
9}
10
11pub fn get_enemy_portrait(html: &str) -> Option<String> {
12    let html = parse_html(html);
13
14    let selector = Selector::parse("img.pi-image-thumbnail").unwrap();
15
16    let image = parse_url(html.select(&selector).next()?.value().attr("src").unwrap());
17
18    Some(get_original_image(&image).unwrap().to_string())
19}
20
21pub fn index_enemies(html: String) -> Vec<Enemy> {
22    let html = parse_html(&html);
23    let selector = Selector::parse("a.category-page__member-link").unwrap();
24
25    html.select(&selector)
26        .enumerate()
27        .filter_map(|(indx, e)| {
28            let out = Enemy {
29                id: indx,
30                link: canonicalize(e.value().attr("href").unwrap().to_string()),
31                name: e.value().attr("title").unwrap().to_string(),
32            };
33
34            if out.name.starts_with("Category") {
35                None
36            } else {
37                Some(out)
38            }
39        })
40        .collect()
41}
42
43// pub fn get_enemy_drops(html: String, enemy: &mut Enemy) {
44//     let html = parse_html(html);
45//     let selector = Selector::parse("div.card-container span.card-image a").unwrap();
46//     let image_selector = Selector::parse("img").unwrap();
47
48//     let drops = html
49//         .select(&selector)
50//         .map(|e| {
51//             let image = e
52//                 .select(&image_selector)
53//                 .next()
54//                 .unwrap()
55//                 .value()
56//                 .attr("src")
57//                 .unwrap()
58//                 .to_string();
59//             let link = canonicalize(e.value().attr("href").unwrap().to_string());
60
61//             EnemyDrops { image, link }
62//         })
63//         .collect::<Vec<_>>();
64
65//     enemy.drops = Some(drops);
66// }
67
68pub fn get_enemy_resistances(html: &str) -> Vec<u8> {
69    let html = parse_html(html);
70
71    let table_selector = Selector::parse("table.wikitable").unwrap();
72    let row_selector = Selector::parse("tr").unwrap();
73    let col_selector = Selector::parse("td").unwrap();
74
75    select_table(0, html, &table_selector, &row_selector, &col_selector)
76}
77
78pub fn get_enemy_debuff_resistances(html: &str) -> Vec<u8> {
79    let html = parse_html(html);
80
81    let table_selector = Selector::parse("table.wikitable").unwrap();
82    let row_selector = Selector::parse("tr").unwrap();
83    let col_selector = Selector::parse("td").unwrap();
84
85    select_table(1, html, &table_selector, &row_selector, &col_selector)
86}
87
88fn select_table(
89    n: usize,
90    html: Html,
91    table_selector: &Selector,
92    row_selector: &Selector,
93    col_selector: &Selector,
94) -> Vec<u8> {
95    html.select(table_selector)
96        .nth(n)
97        .unwrap()
98        .select(row_selector)
99        .nth(2)
100        .unwrap()
101        .select(col_selector)
102        .map(|e| {
103            let percent = e.inner_html();
104
105            // This is weird syntax, but
106            // it basically strips the newline
107            // if it exists
108            if percent.ends_with('\n') {
109                percent.strip_suffix('\n').unwrap()
110            } else {
111                percent.as_str()
112            }
113            .strip_suffix('%')
114            .unwrap()
115            .parse::<u8>()
116            .unwrap()
117        })
118        .collect()
119}