Initial commit with barely working stuff
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
Cargo.lock
|
||||||
|
rust.json
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "rapr"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Uttarayan Mondal <uttarayan21@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
reqwest = "0.11.*"
|
||||||
|
chrono = "0.4.*"
|
||||||
|
json = "0.12.*"
|
||||||
|
tokio = { version = "1.3.*", features = ["full"] }
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# rapr-rs
|
||||||
|
|
||||||
|
Reddit api wrapper in rust.
|
||||||
|
|
||||||
|
Not usable currently.
|
||||||
|
|
||||||
|
Currently doing this to learn rust.
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
mod rapr;
|
||||||
|
pub use crate::rapr::RaprClient;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[tokio::test]
|
||||||
|
async fn subreddit() {
|
||||||
|
use crate::rapr::RaprClient;
|
||||||
|
let client = RaprClient::new();
|
||||||
|
let mut sub = RaprClient::subreddit("rust");
|
||||||
|
client.fetch(10, &mut sub).await.unwrap();
|
||||||
|
println!("{:#?}", sub.posts.len());
|
||||||
|
client.fetch(5, &mut sub).await.unwrap();
|
||||||
|
println!("{:#?}", sub.posts.len());
|
||||||
|
println!("{:#?}", sub.pinned_posts());
|
||||||
|
}
|
||||||
|
}
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
extern crate json;
|
||||||
|
extern crate reqwest;
|
||||||
|
extern crate tokio;
|
||||||
|
use chrono::{DateTime, Local};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
JsonParseError,
|
||||||
|
HttpGetError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RaPost {
|
||||||
|
id: String,
|
||||||
|
datetime: DateTime<Local>,
|
||||||
|
title: String,
|
||||||
|
text: Option<String>,
|
||||||
|
json: json::JsonValue,
|
||||||
|
pinned: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for RaPost {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("RaPost")
|
||||||
|
.field("id", &self.id)
|
||||||
|
.field("datetime", &self.datetime)
|
||||||
|
.field("title", &self.title)
|
||||||
|
.field("text", &self.text)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RaPost {
|
||||||
|
pub fn new(id: &str, title: &str, json: &json::JsonValue, pinned: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
id: id.to_string(),
|
||||||
|
title: title.to_string(),
|
||||||
|
datetime: Local::now(), // Temp
|
||||||
|
text: Some(String::from("")),
|
||||||
|
json: json.clone(),
|
||||||
|
pinned,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn parse(post: &json::JsonValue) -> Result<RaPost, json::Error> {
|
||||||
|
Ok(RaPost::new(
|
||||||
|
json::stringify(post["name"].clone()).as_str(),
|
||||||
|
json::stringify(post["title"].clone()).as_str(),
|
||||||
|
post,
|
||||||
|
post["pinned"].as_bool().unwrap(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RaSub {
|
||||||
|
pub name: String,
|
||||||
|
pub posts: Vec<RaPost>,
|
||||||
|
after: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RaSub {
|
||||||
|
pub fn pinned_posts(&self) -> Option<Vec<RaPost>> {
|
||||||
|
let mut pinned_posts: Vec<RaPost> = Vec::new();
|
||||||
|
for post in &self.posts {
|
||||||
|
if post.pinned {
|
||||||
|
pinned_posts.push(post.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pinned_posts.is_empty() {
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
return Some(pinned_posts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RaprClient {
|
||||||
|
oauth: Option<String>,
|
||||||
|
rwclient: reqwest::Client,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RaprClient {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
oauth: None,
|
||||||
|
rwclient: reqwest::Client::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn subreddit(name: &str) -> RaSub {
|
||||||
|
RaSub {
|
||||||
|
name: String::from(name),
|
||||||
|
posts: Vec::new(),
|
||||||
|
after: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn fetch(&self, count: u32, sub: &mut RaSub) -> Result<Vec<RaPost>, Error> {
|
||||||
|
let url = match self.oauth {
|
||||||
|
None => format!("https://reddit.com/r/{}.json", sub.name),
|
||||||
|
Some(_) => format!("https://oauth.reddit.com/r/{}.json", sub.name),
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = match &sub.after {
|
||||||
|
None => self
|
||||||
|
.rwclient
|
||||||
|
.get(url)
|
||||||
|
.query(&[("limit", count)])
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
Some(after) => self
|
||||||
|
.rwclient
|
||||||
|
.get(url)
|
||||||
|
.query(&[("limit", count.to_string()), ("after", after.to_string())])
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut parsed = json::parse(res.text().await.unwrap().as_str()).unwrap();
|
||||||
|
|
||||||
|
let raw_posts: Vec<json::JsonValue> = match parsed["data"]["children"].take() {
|
||||||
|
json::JsonValue::Array(arr) => arr,
|
||||||
|
_ => return Err(Error::JsonParseError),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut parsed_posts: Vec<RaPost> = Vec::new();
|
||||||
|
|
||||||
|
for post in raw_posts {
|
||||||
|
parsed_posts.push(RaPost::parse(&post["data"]).unwrap());
|
||||||
|
}
|
||||||
|
if parsed["data"]["after"].is_string() {
|
||||||
|
sub.after = Some(parsed["data"]["after"].to_string());
|
||||||
|
}
|
||||||
|
sub.posts.append(&mut parsed_posts);
|
||||||
|
Ok(parsed_posts)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user