This commit is contained in:
Neshura 2023-06-19 19:21:28 +02:00
parent 17283a9d9b
commit 3f50c7654c
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C
4 changed files with 83 additions and 12 deletions

18
Cargo.lock generated
View file

@ -100,6 +100,7 @@ dependencies = [
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"strum_macros 0.25.0",
"url", "url",
] ]
@ -666,7 +667,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"strum", "strum",
"strum_macros", "strum_macros 0.24.3",
"tokio", "tokio",
"url", "url",
"uuid", "uuid",
@ -683,7 +684,7 @@ dependencies = [
"futures", "futures",
"serde", "serde",
"strum", "strum",
"strum_macros", "strum_macros 0.24.3",
"tokio", "tokio",
"tracing", "tracing",
"tracing-error", "tracing-error",
@ -1216,6 +1217,19 @@ dependencies = [
"syn 1.0.109", "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]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"

View file

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

View file

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

View file

@ -1,9 +1,9 @@
use chrono::Utc; use chrono::Utc;
use config::{Config, PrevPost, Secrets}; use config::{Config, PrevPost, Secrets, LemmyCommunities};
use lemmy_api_common::{ use lemmy_api_common::{
person::{Login, LoginResponse}, person::{Login, LoginResponse},
post::{CreatePost, GetPosts, GetPostsResponse}, post::{CreatePost, GetPosts, GetPostsResponse},
sensitive::Sensitive, sensitive::Sensitive, community::{ListCommunities, ListCommunitiesResponse},
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
newtypes::{CommunityId, LanguageId}, newtypes::{CommunityId, LanguageId},
@ -30,6 +30,7 @@ struct Bot {
secrets: Secrets, secrets: Secrets,
config: Config, config: Config,
post_history: Vec<PrevPost>, post_history: Vec<PrevPost>,
community_ids: CommunitiesVector,
auth: Sensitive<String>, auth: Sensitive<String>,
} }
@ -39,6 +40,7 @@ impl Bot {
secrets: Secrets::load(), secrets: Secrets::load(),
config: Config::load(), config: Config::load(),
post_history: PrevPost::load(), post_history: PrevPost::load(),
community_ids: CommunitiesVector::new(),
auth: Sensitive::new("".to_string()), auth: Sensitive::new("".to_string()),
} }
} }
@ -94,12 +96,61 @@ fn list_posts(auth: &Sensitive<String>) -> GetPostsResponse {
return serde_json::from_str(&res).unwrap(); 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() { fn main() {
// Get all needed auth tokens at the start // Get all needed auth tokens at the start
let mut old = Utc::now().time(); let mut old = Utc::now().time();
let mut this = Bot::new(); let mut this = Bot::new();
println!("{}", this.secrets.lemmy.username); println!("{}", this.secrets.lemmy.username);
this.login(); this.login();
this.community_ids.load(&this.auth);
// Create empty eTag list // Create empty eTag list
println!("TODO: Etag list"); println!("TODO: Etag list");
@ -108,11 +159,16 @@ fn main() {
loop { loop {
let start = Utc::now(); let start = Utc::now();
print!("\x1B[2J\x1B[1;1H"); 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) { if start.time() - old > chrono::Duration::seconds(6) {
old = start.time(); old = start.time();
this.config = Config::load(); this.config = Config::load();
this.community_ids.load(&this.auth);
} }
// Start the polling process // Start the polling process
@ -144,14 +200,14 @@ fn main() {
let item = &data.items[0]; let item = &data.items[0];
let new_post = CreatePost { let new_post = CreatePost {
name: item.title.clone(), 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()), url: Some(Url::parse(&item.url).unwrap()),
body: Some( body: Some(
"[Reddit](https://reddit.com)\n\n[Discord](https://discord.com)".into(), "[Reddit](https://reddit.com)\n\n[Discord](https://discord.com)".into(),
), ),
honeypot: None, honeypot: None,
nsfw: Some(false), 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(), auth: this.auth.clone(),
}; };
post_queue.push(new_post); post_queue.push(new_post);
@ -171,7 +227,7 @@ fn main() {
PrevPost::save(&this.post_history); PrevPost::save(&this.post_history);
post_queue.iter().for_each(|post| { post_queue.iter().for_each(|post| {
println!("Posted: {}", post.name); println!("Posting: {}", post.name);
this.post(post.clone()); this.post(post.clone());
}); });