pub mod error;
pub mod types;
use std::collections::HashMap;
use reqwest::Client;
pub use error::*;
pub use types::*;
use std::path::Path;
use reqwest::multipart::Form;
use reqwest::multipart::Part;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Default)]
pub struct AccountBuilder {
access_token: Option<String>,
short_name: String,
author_name: Option<String>,
author_url: Option<String>,
}
impl AccountBuilder {
pub fn new(short_name: &str) -> Self {
AccountBuilder {
short_name: short_name.to_owned(),
..Default::default()
}
}
pub fn short_name(mut self, short_name: &str) -> Self {
self.short_name = short_name.to_owned();
self
}
pub fn access_token(mut self, access_token: &str) -> Self {
self.access_token = Some(access_token.to_owned());
self
}
pub fn author_name(mut self, author_name: &str) -> Self {
self.author_name = Some(author_name.to_owned());
self
}
pub fn author_url(mut self, author_url: &str) -> Self {
self.author_url = Some(author_url.to_owned());
self
}
pub fn create(mut self) -> Result<Telegraph> {
if self.access_token.is_none() {
let account = Telegraph::create_account(
&self.short_name,
self.author_name.as_ref().map(|s| &**s),
self.author_url.as_ref().map(|s| &**s),
)?;
self.access_token = Some(account.access_token.unwrap().to_owned());
}
Ok(Telegraph {
client: Client::new(),
access_token: self.access_token.unwrap().to_owned(),
short_name: self.short_name.to_owned(),
author_name: self.author_name.unwrap_or(self.short_name.to_owned()),
author_url: self.author_url.clone(),
})
}
pub fn edit(self) -> Result<Telegraph> {
let mut response = Client::new()
.get("https://api.telegra.ph/editAccountInfo")
.query(&[
("access_token", self.access_token.as_ref().unwrap()),
("short_name", &self.short_name),
("author_name", self.author_name.as_ref().unwrap()),
("author_url", self.author_url.as_ref().unwrap_or(&String::new())),
])
.send()?;
let json: Result<Account> = response.json::<ApiResult<Account>>()?.into();
let json = json?;
Ok(Telegraph {
client: Client::new(),
access_token: self.access_token.clone().unwrap(),
short_name: json.short_name.clone().unwrap(),
author_name: json.author_name.unwrap_or(json.short_name.clone().unwrap()),
author_url: json.author_url.clone(),
})
}
}
#[derive(Debug)]
pub struct Telegraph {
client: Client,
access_token: String,
short_name: String,
author_name: String,
author_url: Option<String>,
}
impl Telegraph {
pub fn new(short_name: &str) -> AccountBuilder {
AccountBuilder {
short_name: short_name.to_owned(),
..Default::default()
}
}
pub(crate) fn create_account(
short_name: &str,
author_name: Option<&str>,
author_url: Option<&str>,
) -> Result<Account> {
let mut params = HashMap::new();
params.insert("short_name", short_name);
if let Some(author_name) = author_name {
params.insert("author_name", author_name);
}
if let Some(author_url) = author_url {
params.insert("author_url", author_url);
}
let mut response = Client::new()
.get("https://api.telegra.ph/createAccount")
.query(¶ms)
.send()?;
response.json::<ApiResult<Account>>()?.into()
}
pub fn create_page(&self, title: &str, content: &str, return_content: bool) -> Result<Page> {
let mut response = self
.client
.post("https://api.telegra.ph/createPage")
.form(&[
("access_token", &*self.access_token),
("title", title),
("author_name", &*self.author_name),
("content", content),
("return_content", &*return_content.to_string()),
])
.send()?;
response.json::<ApiResult<Page>>()?.into()
}
pub fn edit_account_info(self) -> AccountBuilder {
AccountBuilder {
access_token: Some(self.access_token.clone()),
short_name: self.short_name.clone(),
author_name: Some(self.author_name.clone()),
author_url: self.author_url.clone(),
}
}
pub fn edit_page(
&self,
path: &str,
title: &str,
content: &str,
return_content: bool,
) -> Result<Page> {
let mut response = self
.client
.post("https://api.telegra.ph/editPage")
.form(&[
("access_token", &*self.access_token),
("path", path),
("title", title),
("author_name", &*self.author_name),
("content", content),
("return_content", &*return_content.to_string()),
])
.send()?;
response.json::<ApiResult<Page>>()?.into()
}
pub fn get_account_info(&self, fields: &[&str]) -> Result<Account> {
let mut response = self
.client
.get("https://api.telegra.ph/getAccountInfo")
.query(&[
("access_token", &self.access_token),
("fields", &serde_json::to_string(fields).unwrap()),
])
.send()?;
response.json::<ApiResult<Account>>()?.into()
}
pub fn get_page(path: &str, return_content: bool) -> Result<Page> {
let mut response = Client::new()
.get(&format!("https://api.telegra.ph/getPage/{}", path))
.query(&[("return_content", return_content.to_string())])
.send()?;
response.json::<ApiResult<Page>>()?.into()
}
pub fn get_page_list(&self, offset: i32, limit: i32) -> Result<PageList> {
let mut response = self
.client
.get("https://api.telegra.ph/getPageList")
.query(&[
("access_token", &self.access_token),
("offset", &offset.to_string()),
("limit", &limit.to_string()),
])
.send()?;
response.json::<ApiResult<PageList>>()?.into()
}
pub fn get_views(path: &str, time: &[i32]) -> Result<PageViews> {
let params = ["year", "month", "day", "hour"].iter().zip(time)
.collect::<HashMap<_, _>>();
let mut response = Client::new()
.get(&format!("https://api.telegra.ph/getViews/{}", path))
.query(¶ms)
.send()?;
response.json::<ApiResult<PageViews>>()?.into()
}
pub fn revoke_access_token(&mut self) -> Result<Account> {
let mut response = self
.client
.get("https://api.telegra.ph/revokeAccessToken")
.query(&[("access_token", &self.access_token)])
.send()?;
let json: Result<Account> = response.json::<ApiResult<Account>>()?.into();
if json.is_ok() {
self.access_token = json
.as_ref()
.unwrap()
.access_token
.as_ref()
.unwrap()
.to_owned();
}
json
}
pub fn upload<P: AsRef<Path>>(files: &[P]) -> Result<Vec<UploadResult>> {
let mut form = Form::new();
for (idx, file) in files.into_iter().enumerate() {
let part = Part::file(file)?;
form = form.part(idx.to_string(), part);
}
let mut response = Client::new()
.post("https://telegra.ph/upload")
.multipart(form)
.send()?;
Ok(response.json::<Vec<UploadResult>>()?)
}
}
#[cfg(test)]
mod tests {
use crate::Telegraph;
#[test]
fn create_and_revoke_account() {
let result = Telegraph::create_account("sample", Some("a"), None);
println!("{:?}", result);
assert!(result.is_ok());
let mut telegraph = Telegraph::new("test")
.access_token(&result.unwrap().access_token.unwrap().to_owned())
.create()
.unwrap();
let result = telegraph.revoke_access_token();
println!("{:?}", result);
assert!(result.is_ok());
}
#[test]
fn edit_account_info() {
let result = Telegraph::new("test")
.access_token("b968da509bb76866c35425099bc0989a5ec3b32997d55286c657e6994bbb")
.create()
.unwrap()
.edit_account_info()
.short_name("wow")
.edit();
println!("{:?}", result);
assert!(result.is_ok());
}
#[test]
fn get_account_info() {
let result = Telegraph::new("test")
.access_token("b968da509bb76866c35425099bc0989a5ec3b32997d55286c657e6994bbb")
.create()
.unwrap()
.get_account_info(&["short_name"]);
println!("{:?}", result);
assert!(result.is_ok());
}
#[test]
fn create_get_edit_page() {
let telegraph = Telegraph::new("test")
.access_token("b968da509bb76866c35425099bc0989a5ec3b32997d55286c657e6994bbb")
.create()
.unwrap();
let page = telegraph.create_page(
"OVO",
r#"[{"tag":"p","children":["Hello,+world!"]}]"#,
false,
);
println!("{:?}", page);
assert!(page.is_ok());
let page = Telegraph::get_page(&page.unwrap().path, true);
println!("{:?}", page);
assert!(page.is_ok());
let page = telegraph.edit_page(
&page.unwrap().path,
"QAQ",
r#"[{"tag":"p","children":["Goodbye,+world!"]}]"#,
false,
);
println!("{:?}", page);
assert!(page.is_ok());
}
#[test]
fn get_page_list() {
let telegraph = Telegraph::new("test")
.access_token("b968da509bb76866c35425099bc0989a5ec3b32997d55286c657e6994bbb")
.create()
.unwrap();
let page_list = telegraph.get_page_list(0, 3);
println!("{:?}", page_list);
assert!(page_list.is_ok());
}
#[test]
fn get_views() {
let views = Telegraph::get_views("Sample-Page-12-15", &vec![2016, 12]);
println!("{:?}", views);
assert!(views.is_ok());
}
#[ignore]
#[test]
fn upload() {
let images = Telegraph::upload(&vec!["1.jpeg", "2.jpeg"]);
println!("{:?}", images);
}
}