aboutsummaryrefslogtreecommitdiffstats
path: root/meetup/src/client.rs
blob: c2a58ba95ad0f6f0f17a11c0d6fe7e54b027d92c (plain)
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
// Copyright © 2018 Teddy Wing
//
// This file is part of Meetup Find Events RSS.
//
// Meetup Find Events RSS is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// Meetup Find Events RSS is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Meetup Find Events RSS. If not, see
// <http://www.gnu.org/licenses/>.

use reqwest;
use serde_json;

use errors::*;
use event::Event;

const MEETUP_BASE_URL: &'static str = "https://api.meetup.com";

pub struct Client {
    pub token: String,
}

impl Client {
    pub fn new(token: String) -> Client {
        Client { token: token }
    }

    pub fn find_upcoming_events(
        &self,
        latitude: String,
        longitude: String,
        end_date_range: String,
        radius: Option<String>,
        page: Option<String>,
    ) -> Result<Vec<Event>> {
        let mut params = vec![
            ("key", self.token.clone()),
            ("lat", latitude),
            ("lon", longitude),
            ("end_date_range", end_date_range),
            ("order", "time".to_owned()),
        ];

        if let Some(r) = radius {
            params.push(("radius", r))
        }

        if let Some(p) = page {
            params.push(("page", p))
        }

        let client = reqwest::Client::new();
        let response_text = client
            .get(&format!("{}{}", MEETUP_BASE_URL, "/find/upcoming_events"))
            .query(&params)
            .send()?
            .text()?;

        Ok(parse_json(response_text)?)
    }
}


fn parse_json(json: String) -> Result<Vec<Event>> {
    let parsed: serde_json::Value = serde_json::from_str(json.as_ref())?;
    let events: Vec<Event> = serde_json::from_value(parsed["events"].clone())?;

    Ok(events)
}


#[cfg(test)]
mod tests {
    use super::*;
    use event::Venue;

    #[test]
    fn test_parse_json_parses_event_json() {
        let events = parse_json(
            include_str!("../testdata/meetup--find-upcoming_events.json")
                .to_owned()
        ).unwrap();

        assert_eq!(
            events,
            vec![
                Event {
                    name: "Hackspace Project Night - Open to Everyone!".to_owned(),
                    description: Some("<p>Spend some time on your project by bringing it along to our weekly project night, an evening designed around you and what you're working on.</p> <p>This weekly event is about finding time to tinker, being creative, and meeting other members of the community. You'll get the chance to see what others are working on, share your projects, and to get inspiration and feedback from fellow tinkerers.</p> <p>On any given Tuesday night you have people working on electronics, knitting, writing code, wood-working, or just their plans for world domination. Beer is also consumed.</p> <p>We’ll provide: space to work, basic tools, power, a room full of like minded people.</p> <p>You’ll provide: your project, ideas and beer (optional). A laptop would probably be useful too.</p> <p>Sometimes we work on group projects together, which are usually set up as separate meetup events. Keep an eye on our events page to see what we’re working on next.</p> <p>Note: We usually have around 10 or 20 people at these events, many of our members come along but aren't counted as they don't respond on meetup.</p> <p><img src=\"http://photos3.meetupstatic.com/photos/event/b/3/b/2/600_459406002.jpeg\" /></p> ".to_owned()),
                    link: "https://www.meetup.com/Cambridge-Hackspace/events/249620800/".to_owned(),
                    local_date: Some("2018-04-17".to_owned()),
                    local_time: Some("18:30".to_owned()),
                    venue: Some(Venue {
                        name: "Cambridge Hackspace".to_owned(),
                        address_1: "438 Somerville Avenue".to_owned(),
                        city: "Somerville".to_owned(),
                        localized_country_name: "USA".to_owned(),
                    }),
                },
                Event {
                    name: "PyCon Rehearsal Night #1".to_owned(),
                    description: Some("<p>.</p> ".to_owned()),
                    link: "https://www.meetup.com/bostonpython/events/247552529/".to_owned(),
                    local_date: Some("2018-04-25".to_owned()),
                    local_time: Some("19:00".to_owned()),
                    venue: Some(Venue {
                        name: "VMWare".to_owned(),
                        address_1: "2 Ave de Lafayette".to_owned(),
                        city: "Boston".to_owned(),
                        localized_country_name: "USA".to_owned(),
                    }),
                },
            ]
        );
    }
}