1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use scraper::Selector;

use super::{parse_html, parse_url};
use crate::url::{canonicalize, get_original_image};

pub struct Character {
    pub name: String,
    pub link: String,
    pub rarity: String,
    pub rarity_image: String,
    pub path: String,
    pub path_image: String,
    pub ctype: String,
    pub ctype_image: String,
}

pub fn index_characters(html: String) -> Vec<Character> {
    let html = parse_html(html);
    let selector = Selector::parse("table.article-table>tbody").unwrap();
    let row_selector = Selector::parse("tr").unwrap();
    let name_selector = Selector::parse("td>a").unwrap();
    let rarity_selector = Selector::parse("td>img").unwrap();
    let path_selector = Selector::parse("td>span>a").unwrap();
    let path_image_selector = Selector::parse("img").unwrap();
    let ctype_selector = Selector::parse("td>span>span>b").unwrap();
    let ctype_image_selector = Selector::parse("td img").unwrap();

    let mut res = vec![];
    let table = html.select(&selector).next().unwrap();
    for entry in table.select(&row_selector).skip(1) {
        let link = entry.select(&name_selector).next().unwrap().value();
        let name = link.attr("title").unwrap();
        let link = canonicalize(link.attr("href").unwrap());

        // we skip the trailblazer because
        // its an 'adaptive' character. there
        // will be a special implementation
        // for Steele and Caelus
        if name == "Trailblazer" {
            continue;
        }

        let rarity = entry.select(&rarity_selector).next().unwrap().value();
        let rarity_image = rarity.attr("data-src").unwrap();
        let rarity = rarity.attr("alt").unwrap();

        let path = entry.select(&path_selector).next().unwrap();
        let path_image = path
            .select(&path_image_selector)
            .next()
            .unwrap()
            .value()
            .attr("data-src")
            .unwrap();
        let path = path.value().attr("title").unwrap();

        let ctype = entry.select(&ctype_selector).next().unwrap();
        let ctype_image = entry
            .select(&ctype_image_selector)
            .last()
            .unwrap()
            .value()
            .attr("data-src")
            .unwrap();
        let ctype = ctype.inner_html();

        res.push(Character {
            link: link.to_string(),
            name: name.to_string(),
            rarity: rarity.to_string(),
            rarity_image: get_original_image(&parse_url(rarity_image))
                .unwrap()
                .to_string(),
            path: path.to_string(),
            path_image: path_image.to_string(),
            ctype: ctype.to_string(),
            ctype_image: get_original_image(&parse_url(ctype_image))
                .unwrap()
                .to_string(),
        })
    }

    res
}

pub fn get_character_art(html: String) -> Option<(String, String)> {
    let html = parse_html(html);
    let portrait_selector = Selector::parse("img[alt=Portrait]").ok()?;
    let splash_selector = Selector::parse("img[alt=\"Splash Art\"]").ok()?;

    let portrait = get_original_image(&parse_url(
        html.select(&portrait_selector)
            .next()?
            .value()
            .attr("data-src")?,
    ))
    .unwrap()
    .to_string();

    let splash = get_original_image(&parse_url(
        html.select(&splash_selector)
            .next()?
            .value()
            .attr("data-src")?,
    ))
    .unwrap()
    .to_string();

    Some((portrait, splash))
}

pub fn get_voice_overs(html: String) -> Vec<(String, String)> {
    let html = parse_html(html);
    let voice_over_entry = Selector::parse("table.wikitable>tbody>tr").unwrap();
    let vo_type = Selector::parse("th>div").unwrap();
    let vo_audio = Selector::parse("td>span>a").unwrap();

    let mut res = vec![];
    for voice_over in html.select(&voice_over_entry) {
        let audio = voice_over.select(&vo_audio).next();
        let audio_type = voice_over.select(&vo_type).next();

        if audio.is_none() || audio_type.is_none() {
            continue;
        }

        let audio = audio.unwrap();

        if audio
            .value()
            .classes()
            .collect::<Vec<_>>()
            .contains(&"no-audio")
        {
            continue;
        }

        let audio_link = audio.value().attr("href").unwrap().to_string();
        let audio_type = audio_type.unwrap().value().id().unwrap().to_string();
        // let audio_type = audio_type.value().id().unwrap().to_string();

        res.push((audio_type, audio_link));
    }

    res
}