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
use super::models;
use anyhow::{Error, Result};
use mediawiki::api::Api;
const USER_AGENT: &str = toolforge::user_agent!("suggestor");
async fn build_api(wiki: &str, token: Option<&str>) -> Api {
let mut api = Api::new(&format!("https://{}/w/api.php", wiki))
.await
.unwrap();
api.set_user_agent(USER_AGENT);
api.set_maxlag(None);
if let Some(token) = token {
api.set_oauth2(token);
}
api
}
pub async fn get_username(token: &str) -> Option<String> {
let api = build_api("meta.wikimedia.org", Some(token)).await;
match api
.get_query_api_json(&mediawiki::hashmap![
"action".to_string() => "query".to_string(),
"meta".to_string() => "userinfo".to_string(),
"formatversion".to_string() => "2".to_string()
])
.await
{
Ok(resp) => {
let info = &resp["query"]["userinfo"];
if info.get("anon").is_some() {
return None;
}
Some(
resp["query"]["userinfo"]["name"]
.as_str()
.unwrap()
.to_string(),
)
}
Err(_) => None,
}
}
pub async fn get_diff(edit: &models::Edit) -> String {
let api = build_api(&edit.wiki, None).await;
let params = api.params_into(&[
("action", "compare"),
("formatversion", "2"),
("fromrev", &edit.baserevid.to_string()),
("toslots", "main"),
("totext-main", std::str::from_utf8(&edit.text).unwrap()),
]);
match api.post_query_api_json(¶ms).await {
Ok(resp) => resp["compare"]["body"].as_str().unwrap().to_string(),
Err(_) => panic!("API action=compare request failed"),
}
}
pub async fn make_edit(edit: models::Edit, token: &str) -> Result<()> {
let mut api = build_api(&edit.wiki, Some(token)).await;
let token = api.get_edit_token().await?;
if token == "+\\" {
return Err(Error::msg(
"OAuth token no longer valid, please log in again",
));
}
let params = api.params_into(&[
("action", "edit"),
("formatversion", "2"),
("assert", "user"),
("pageid", &edit.pageid.to_string()),
("text", std::str::from_utf8(&edit.text).unwrap()),
(
"summary",
&format!("Edit on behalf of Tor user: {}", edit.summary),
),
("baserevid", &edit.baserevid.to_string()),
("token", &token),
]);
api.post_query_api_json(¶ms).await?;
Ok(())
}