40 个版本
0.1.39 | 2021 年 12 月 17 日 |
---|---|
0.1.38 | 2021 年 4 月 22 日 |
0.1.35 | 2021 年 2 月 27 日 |
0.1.33 | 2020 年 11 月 16 日 |
0.1.15 | 2020 年 8 月 29 日 |
#1076 in 网页编程
67 每月下载量
300KB
7K SLoC
这是什么?
Reddit API 的 WIP Rust 绑定
这是一个 WIP,你可能觉得它不太有用
设置
这里有一些手动编写的入门说明: https://github.com/tobymurray/mr_splashy_pants/blob/master/getting-started/getting-started.md。你可以使用 https://tobymurray.github.io/reddit-auth-generator/ 帮助生成授权字符串。
或者,你可以参考 https://github.com/reddit-archive/reddit/wiki/OAuth2 获取更完整的设置说明。
使用
设置一个可以访问 Reddit 账户的脚本,收集访问令牌、客户端 ID 和客户端密钥。一旦你有了这些,获取刷新令牌和访问令牌。一旦你有了这些,你就可以这样做
let pants = Pants::new(
USER_AGENT,
"<access-token>",
"<refresh_token>",
"<client-id>",
"<client-secret>",
);
例如,如果你使用 dotenv 并从环境中读取值
let pants = Pants::new(
USER_AGENT,
env::var("ACCESS_TOKEN").unwrap(),
&env::var("REFRESH_TOKEN").unwrap(),
&env::var("CLIENT_ID").unwrap(),
&env::var("CLIENT_SECRET").unwrap(),
);
然后你可以调用一些东西,例如
pants.me()
如果你的访问令牌过期,它应该会自动刷新。
目前实现了(部分)结构化响应
账户
- GET /api/v1/me
- GET /api/v1/me/karma
- GET /api/v1/me/prefs
- GET /prefs/friends
目前实现了(没有查询参数),带有 JSON 响应
账户
- GET /api/v1/me/trophies
- GET /prefs/blocked
- GET /prefs/messaging
- GET /prefs/trusted
- GET /api/v1/me/friends
- GET /api/v1/me/blocked
列表
- GET /api/trending_subreddits
- GET /best
- GET /by_id/names
- GET /comments/article
- GET /controversial
- GET /r/{subreddit}/controversial
- GET /duplicates/article
- GET /hot
- GET /r/{subreddit}/hot
- GET /new
- GET /r/{subreddit}/new
- GET /random
- GET /r/{subreddit}/random
- GET /rising
- GET /r/{subreddit}/rising
- GET /top
- GET /r/{subreddit}/top
链接和评论
- POST /api/submit
- 实现了跨帖发布(相同的API,不同的请求体)
- POST /api/del
管理
- GET /about/log
- GET /about/reports
- GET /about/spam
- GET /about/modqueue
- GET /about/unmoderated
- GET /about/edited
- GET /stylesheet
- GET /r/{subreddit}/about/log
- GET /r/{subreddit}/about/reports
- GET /r/{subreddit}/about/spam
- GET /r/{subreddit}/about/modqueue
- GET /r/{subreddit}/about/unmoderated
- GET /r/{subreddit}/about/edited
- GET /r/{subreddit}/stylesheet
用户
- GET /user/{username}/about
- GET /user/{username}/overview
- GET /user/{username}/submitted
- GET /user/{username}/comments
- GET /user/{username}/upvoted
- GET /user/{username}/downvoted
- GET /user/{username}/hidden
- GET /user/{username}/saved
- GET /user/{username}/gilded
向Reddit提交帖子
// Build the submission
let request_body = links_and_comments::ApiSubmit {
ad: "".to_string(),
api_type: "".to_string(),
app: "".to_string(),
collection_id: "".to_string(),
event_end: "".to_string(),
event_start: "".to_string(),
event_tz: "".to_string(),
extension: "".to_string(),
flair_id: "".to_string(),
flair_text: "".to_string(),
g_recaptcha_response: "".to_string(),
kind: "self".to_string(),
nsfw: "".to_string(),
resubmit: "".to_string(),
richtext_json: "".to_string(),
sendreplies: "".to_string(),
spoiler: "".to_string(),
sr: "name_of_subreddit".to_string(),
text: "Here's an example of the post's body".to_string(),
title: "This is the title of the post".to_string(),
uh: "".to_string(),
url: "".to_string(),
video_poster_url: "".to_string(),
};
// then submit the post
let submission_name = pants.submit(request_body).await {
Ok(response) => {
println!("Response to submit is: {}", serde_json::to_string_pretty(&response).unwrap());
response.json.data.name
},
Err(e) => panic!("An error ocurred: {}", e),
};
// remove it if you'd like
let delete_request_body = links_and_comments::ApiDel { id: submission_name };
pants.del(delete_request_body).await;
支持流式传输
免责声明:此流式传输实现与高流量subreddit不兼容。如果在任何30秒内提交超过25篇帖子,此流式传输方法可能会丢失一些。
use futures_util::pin_mut;
use futures_util::stream::StreamExt;
...
let stream = pants.subreddit("testingground4bots").stream_new();
pin_mut!(stream);
while let Some(value) = tokio_test::block_on(stream.next()) {
match value {
Ok(data) => {
println!("New post: {}", data);
}
Err(e) => {
// Note, this can get noisy if the failure persists
println!("Encountered an error: {}", e);
}
}
}
所有其他API均未实现
日志记录
如果事情出了问题,响应体将在跟踪日志级别进行记录。例如,使用fern
fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{}[{}][{}] {}",
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
record.target(),
record.level(),
message
))
})
.level(log::LevelFilter::Trace) // This has to be trace level
.chain(std::io::stdout())
.chain(fern::log_file("output.log")?)
.apply()?;
通往1.0版本的路径
目前,我在随意修改库以支持我当前正在做的事情。另外,我刚开始使用Rust,所以我通常不知道自己在做什么。因此,这个库的接口应被视为不稳定且通常不理想。在1.0版本之前,每个新版本都可能引入破坏性更改。我对这个库最终想达到什么目标并不清楚——它是应该成为一个仅向Reddit API提供类型的“低级”API包装器?还是应该尝试在原始API之上提供一些可用性改进?或者,它应该专注于简化机器人与Reddit交互的最常见用例?
在我对这些问题的看法变得清晰之前,这个库应该预计会有很大的变化。
依赖项
约6-18MB
约282K SLoC