Merge branch 'id-detection' into 'main'

Closes #4

Closes #4

See merge request Neshura/ascendance-of-a-bookworm-bot!1
This commit is contained in:
Neshura 2023-06-19 17:53:58 +00:00
commit 9433bf4cb5
4 changed files with 83 additions and 12 deletions

18
Cargo.lock generated
View file

@ -100,6 +100,7 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"strum_macros 0.25.0",
"url",
]
@ -666,7 +667,7 @@ dependencies = [
"serde",
"serde_json",
"strum",
"strum_macros",
"strum_macros 0.24.3",
"tokio",
"url",
"uuid",
@ -683,7 +684,7 @@ dependencies = [
"futures",
"serde",
"strum",
"strum_macros",
"strum_macros 0.24.3",
"tokio",
"tracing",
"tracing-error",
@ -1216,6 +1217,19 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "strum_macros"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe9f3bd7d2e45dcc5e265fbb88d6513e4747d8ef9444cf01a533119bce28a157"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.18",
]
[[package]]
name = "syn"
version = "1.0.109"

View file

@ -14,4 +14,5 @@ reqwest = { version = "0.11.18", features = ["blocking", "json"] }
serde = "1.0.164"
serde_derive = "1.0.164"
serde_json = "1.0.97"
strum_macros = "0.25.0"
url = "2.4.0"

View file

@ -5,7 +5,7 @@ use serde_derive::{Deserialize, Serialize};
macro_rules! pub_struct {
($name:ident {$($field:ident: $t:ty,)*}) => {
#[derive(Serialize, Deserialize, Clone)]
#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub(crate) struct $name {
$(pub(crate) $field: $t), *
}
@ -33,7 +33,7 @@ impl Secrets {
}
}
#[derive(Serialize, Deserialize, Clone)]
#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub(crate) struct LemmyLogin {
pub(crate) username: String,
password: String
@ -49,7 +49,7 @@ impl LemmyLogin {
}
}
#[derive(Serialize, Deserialize, Clone)]
#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub(crate) struct RedditLogin {
pub(crate) app_id: String,
app_secret: String,
@ -94,7 +94,7 @@ pub_struct!(FeedCommunities {
volume: LemmyCommunities,
});
#[derive(Serialize, Deserialize, Clone)]
#[derive(Serialize, Deserialize, Clone, PartialEq, strum_macros::Display)]
#[allow(non_camel_case_types)]
pub(crate) enum LemmyCommunities {
aobwebnovel,

View file

@ -1,9 +1,9 @@
use chrono::Utc;
use config::{Config, PrevPost, Secrets};
use config::{Config, PrevPost, Secrets, LemmyCommunities};
use lemmy_api_common::{
person::{Login, LoginResponse},
post::{CreatePost, GetPosts, GetPostsResponse},
sensitive::Sensitive,
sensitive::Sensitive, community::{ListCommunities, ListCommunitiesResponse},
};
use lemmy_db_schema::{
newtypes::{CommunityId, LanguageId},
@ -30,6 +30,7 @@ struct Bot {
secrets: Secrets,
config: Config,
post_history: Vec<PrevPost>,
community_ids: CommunitiesVector,
auth: Sensitive<String>,
}
@ -39,6 +40,7 @@ impl Bot {
secrets: Secrets::load(),
config: Config::load(),
post_history: PrevPost::load(),
community_ids: CommunitiesVector::new(),
auth: Sensitive::new("".to_string()),
}
}
@ -94,12 +96,61 @@ fn list_posts(auth: &Sensitive<String>) -> GetPostsResponse {
return serde_json::from_str(&res).unwrap();
}
struct CommunitiesVector {
ids: Vec<(CommunityId, String)>,
}
impl CommunitiesVector {
fn new() -> CommunitiesVector {
CommunitiesVector{ids: vec![]}
}
fn load(&mut self, auth: &Sensitive<String>) {
let params = ListCommunities {
auth: Some(auth.clone()),
..Default::default()
};
let res = CLIENT
.get("https://lemmy.neshweb.net/api/v3/community/list")
.query(&params)
.send()
.unwrap()
.text()
.unwrap();
let site_data: ListCommunitiesResponse = serde_json::from_str(&res).unwrap();
let mut ids = [].to_vec();
site_data.communities.iter().for_each(|entry| {
let new_id = (entry.community.id, entry.community.name.clone());
ids.push(new_id);
});
self.ids = ids;
}
fn find(&self, name: &LemmyCommunities) -> CommunityId {
let mut ret_id = CommunityId(0);
self.ids.iter().for_each(|id| {
let id_name = &id.1;
if &name.to_string() == id_name {
ret_id = id.0;
}
});
return ret_id;
}
}
fn main() {
// Get all needed auth tokens at the start
let mut old = Utc::now().time();
let mut this = Bot::new();
println!("{}", this.secrets.lemmy.username);
this.login();
this.community_ids.load(&this.auth);
// Create empty eTag list
println!("TODO: Etag list");
@ -108,11 +159,16 @@ fn main() {
loop {
let start = Utc::now();
print!("\x1B[2J\x1B[1;1H");
println!("Started loop at {} {}", start.format("%H:%M:%S"), start.timezone());
println!(
"Started loop at {} {}",
start.format("%H:%M:%S"),
start.timezone()
);
if start.time() - old > chrono::Duration::seconds(6) {
old = start.time();
this.config = Config::load();
this.community_ids.load(&this.auth);
}
// Start the polling process
@ -144,14 +200,14 @@ fn main() {
let item = &data.items[0];
let new_post = CreatePost {
name: item.title.clone(),
community_id: CommunityId(3), // TODO get community id by using community name at the start, save it in a list, planned refresh once a day
community_id: this.community_ids.find(&feed.communities.chapter),
url: Some(Url::parse(&item.url).unwrap()),
body: Some(
"[Reddit](https://reddit.com)\n\n[Discord](https://discord.com)".into(),
),
honeypot: None,
nsfw: Some(false),
language_id: Some(LanguageId(0)), // TODO get English language id by api (at the start)
language_id: Some(LanguageId(37)), // TODO get this id once every few hours per API request, the ordering of IDs suggests that the EN Id might change in the future
auth: this.auth.clone(),
};
post_queue.push(new_post);
@ -171,7 +227,7 @@ fn main() {
PrevPost::save(&this.post_history);
post_queue.iter().for_each(|post| {
println!("Posted: {}", post.name);
println!("Posting: {}", post.name);
this.post(post.clone());
});