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
#![warn(bad_style)]
#![warn(unused)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
extern crate failure;
extern crate oauth_client as oauth;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
use oauth::Token;
use std::borrow::Cow;
use std::collections::HashMap;
type Result<T> = std::result::Result<T, failure::Error>;
mod api_twitter_oauth {
pub const REQUEST_TOKEN: &'static str = "https://api.twitter.com/oauth/request_token";
pub const AUTHORIZE: &'static str = "https://api.twitter.com/oauth/authorize";
pub const ACCESS_TOKEN: &'static str = "https://api.twitter.com/oauth/access_token";
}
mod api_twitter_soft {
pub const UPDATE_STATUS: &'static str = "https://api.twitter.com/1.1/statuses/update.json";
pub const HOME_TIMELINE: &'static str = "https://api.twitter.com/1.1/statuses/home_timeline.\
json";
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Tweet {
pub created_at: String,
pub text: String,
}
impl Tweet {
pub fn parse_timeline(json_string: String) -> Result<Vec<Tweet>> {
let conf = serde_json::from_str(&json_string)?;
Ok(conf)
}
}
fn split_query<'a>(query: &'a str) -> HashMap<Cow<'a, str>, Cow<'a, str>> {
let mut param = HashMap::new();
for q in query.split('&') {
let mut s = q.splitn(2, '=');
let k = s.next().unwrap();
let v = s.next().unwrap();
let _ = param.insert(k.into(), v.into());
}
param
}
pub fn get_request_token(consumer: &Token) -> Result<Token<'static>> {
let bytes = oauth::get(api_twitter_oauth::REQUEST_TOKEN, consumer, None, None)?;
let resp = String::from_utf8(bytes)?;
let param = split_query(&resp);
let token = Token::new(
param.get("oauth_token").unwrap().to_string(),
param.get("oauth_token_secret").unwrap().to_string(),
);
Ok(token)
}
pub fn get_authorize_url(request: &Token) -> String {
format!(
"{}?oauth_token={}",
api_twitter_oauth::AUTHORIZE,
request.key
)
}
pub fn get_access_token(consumer: &Token, request: &Token, pin: &str) -> Result<Token<'static>> {
let mut param = HashMap::new();
let _ = param.insert("oauth_verifier".into(), pin.into());
let bytes = oauth::get(
api_twitter_oauth::ACCESS_TOKEN,
consumer,
Some(request),
Some(¶m),
)?;
let resp = String::from_utf8(bytes)?;
let param = split_query(&resp);
let token = Token::new(
param.get("oauth_token").unwrap().to_string(),
param.get("oauth_token_secret").unwrap().to_string(),
);
Ok(token)
}
pub fn update_status(consumer: &Token, access: &Token, status: &str) -> Result<()> {
let mut param = HashMap::new();
let _ = param.insert("status".into(), status.into());
let _ = oauth::post(
api_twitter_soft::UPDATE_STATUS,
consumer,
Some(access),
Some(¶m),
)?;
Ok(())
}
pub fn get_last_tweets(consumer: &Token, access: &Token) -> Result<Vec<Tweet>> {
let bytes = oauth::get(
api_twitter_soft::HOME_TIMELINE,
consumer,
Some(access),
None,
)?;
let last_tweets_json = String::from_utf8(bytes)?;
let ts = Tweet::parse_timeline(last_tweets_json)?;
Ok(ts)
}