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
use url::Url;
use reqwest;
use std::io::Read;
use hyper::header::{Headers, UserAgent, AcceptLanguage};

use consts;
use parser::top250;
use error::Error;
use models::Movie;
use language::Language;

/// Client to retrieve information from IMDb.

pub struct IMDb {
    /// Reqwest client
    client: reqwest::Client,
    /// Language
    lang: Option<AcceptLanguage>,
    /// User-Agent
    ua: Option<UserAgent>,
}

impl Default for IMDb {
    fn default() -> Self {
        IMDb {
            client: reqwest::Client::new(),
            lang: None,
            ua: None,
        }
    }
}

impl IMDb {
    /// Creates a new IMDb Client instance.
    pub fn new() -> Self {
        IMDb::default()
    }

    /// Sets language  for HTTP requests.
    pub fn accept_language(&mut self, lang: Language) -> &mut Self {
        self.lang = Some(lang.accept_language_header());
        self
    }

    /// Sets _User-Agent_ for HTTP requests.
    pub fn user_agent(&mut self, ua: UserAgent) -> &mut Self {
        self.ua = Some(ua);
        self
    }

    /// Makes HTTP requests.
    fn get(&self, path: &str) -> Result<reqwest::Response, Error> {
        let base = Url::parse(consts::BASE_URL).unwrap();
        let url = base.join(path).unwrap();

        let mut headers = Headers::new();

        if let Some(ref lang) = self.lang {
            headers.set(lang.clone());
        }

        if let Some(ref ua) = self.ua {
            headers.set(ua.clone());
        }

        info!("Sending HTTP request for `{}`.", url);
        self.client.get(url).headers(headers).send().map_err(
            Error::ReqwestError,
        )
    }

    /// Get _Top 250 Movies_.
    pub fn top250_movies(&self) -> Result<Vec<Movie>, Error> {

        let mut response = self.get("chart/top")?;

        let mut html = String::with_capacity(800 * 1024);
        response.read_to_string(&mut html).map_err(Error::IOError)?;

        let movies = top250::parse_top250_movies_html(&html);

        Ok(movies)
    }
}