orca/app/
listings.rs

1use std::collections::HashMap;
2
3use failure::Error;
4use hyper::{Body, Request};
5use json::Value;
6use url::Url;
7
8use data::{Comment, Comments, Listing, Post, Thing};
9use net::{body_from_map, uri_params_from_map};
10use {App, Sort};
11
12impl App {
13	/// Loads a thing and casts it to the type of anything as long as it implements the Thing trait. Experimental
14	/// # Arguments
15	/// * `fullame` - fullname of the thing
16	pub fn load_post(&self, fullname: &str) -> Result<Post, Error> {
17		let mut params: HashMap<&str, &str> = HashMap::new();
18		params.insert("names", fullname);
19
20		let req = Request::get(format!("https://www.reddit.com/by_id/{}/.json", fullname)).body(Body::empty()).unwrap();
21		let response = self.conn.run_request(req)?;
22
23		Post::from_value(&response, self)
24	}
25
26	/// Get the posts in a subreddit sorted in a specific way
27	/// # Arguments
28	/// * `sub` - Name of subreddit to query
29	/// * `sort` - Sort method of query
30	/// # Returns
31	/// A result containing a json listing of posts
32	pub fn get_posts(&self, sub: &str, sort: Sort) -> Result<Value, Error> {
33		let req = Request::get(
34			Url::parse_with_params(
35				&format!(
36					"https://www.reddit.com/r/{}/.\
37					 json",
38					sub
39				),
40				sort.param(),
41			)?
42			.into_string(),
43		)
44		.body(Body::empty())
45		.unwrap();
46
47		self.conn.run_request(req)
48	}
49
50	/// Get a iterator of all comments in order of being posted
51	/// # Arguments
52	/// * `sub` - Name of the subreddit to pull comments from. Can be 'all' to pull from all of reddit
53	pub fn create_comment_stream(&self, sub: &str) -> Comments {
54		Comments::new(self, sub)
55	}
56
57	/// Gets the most recent comments in a subreddit. This function is also usually called internally but
58	/// can be called if a one time retrieval of recent comments from a subreddit is necessary
59	/// # Arguments
60	/// * `sub` - Subreddit to load recent comments from
61	/// * `limit` - Optional limit to amount of comments loaded
62	/// * `before` - Optional comment to be the starting point for the next comments loaded
63	/// # Returns
64	/// A listing of comments that should be flat (no replies)
65	pub fn get_recent_comments(&self, sub: &str, limit: Option<i32>, before: Option<&str>) -> Result<Listing<Comment>, Error> {
66		let limit_str;
67		let mut params: HashMap<&str, &str> = HashMap::new();
68		if let Some(limit) = limit {
69			limit_str = limit.to_string();
70			params.insert("limit", &limit_str);
71		}
72		if let Some(ref before) = before {
73			params.insert("before", before);
74		}
75
76		let req = Request::get(uri_params_from_map(&format!("https://www.reddit.com/r/{}/comments.json", sub), &params)?).body(Body::empty()).unwrap();
77
78		let resp = self.conn.run_request(req)?;
79		let comments = Listing::from_value(&resp["data"]["children"], "", self)?;
80
81		Ok(comments)
82	}
83
84	/// Loads the comment tree of a post, returning a listing of the Comment enum, which can be
85	/// either Loaded or NotLoaded
86	/// # Arguments
87	/// * `post` - The name of the post to retrieve the tree from
88	/// # Returns
89	/// A fully populated listing of commments (no `more` values)
90	pub fn get_comment_tree(&self, post: &str) -> Result<Listing<Comment>, Error> {
91		// TODO add sorting and shit
92
93		let mut params: HashMap<&str, &str> = HashMap::new();
94		params.insert("limit", "2147483648");
95		params.insert("depth", "2147483648");
96		let req = Request::get(format!("https://www.reddit.com/comments/{}/.json", post)).body(body_from_map(&params)).unwrap();
97
98		let data = self.conn.run_request(req)?;
99		let data = data[1]["data"]["children"].clone();
100
101		Listing::from_value(&data, post, self)
102	}
103}