diff --git a/src/main.rs b/src/main.rs index d3dcc04..3e92654 100644 --- a/src/main.rs +++ b/src/main.rs @@ -171,6 +171,7 @@ fn main() -> Result<(), Box> { &config["wiki-api-user"], &config["wiki-api-secret"], is_dry_run(), + &config["wiki-plenum-page"], ); trace_var_!(wiki); // get next plenum days diff --git a/src/mediawiki.rs b/src/mediawiki.rs index 31b062f..1de7a41 100644 --- a/src/mediawiki.rs +++ b/src/mediawiki.rs @@ -36,10 +36,15 @@ pub const CONFIG: CfgGroup<'static> = CfgGroup { key: "api-secret", description: "API secret / \"password\" used for authenticating as the bot.", }, + CfgField::Default { + key: "plenum-page", + default: "Plenum", + description: "The name of the wiki page where all new plenum pages will be linked.", + }, CfgField::Default { key: "eta", default: "no ETA, program never ran", - description: "ETA message for estimating time the program takes" + description: "ETA message for estimating time the program takes." } ], }; @@ -53,6 +58,7 @@ pub struct Mediawiki { is_dry_run: bool, login_token: String, csrf_token: String, + plenum_main_page_name: String, client: Client, } @@ -76,7 +82,7 @@ pub enum RequestType { impl Mediawiki { pub fn new( - server_url: &str, http_auth_user: &str, http_auth_password: &str, api_user: &str, api_secret: &str, is_dry_run: bool, + server_url: &str, http_auth_user: &str, http_auth_password: &str, api_user: &str, api_secret: &str, is_dry_run: bool, plenum_main_page_name: &str, ) -> Self { Self { server_url: server_url.to_string(), @@ -87,6 +93,7 @@ impl Mediawiki { is_dry_run, login_token: String::new(), csrf_token: String::new(), + plenum_main_page_name: plenum_main_page_name.to_string(), client: Client::builder().cookie_store(true).build().unwrap(), } } @@ -177,14 +184,80 @@ impl Mediawiki { let url = format!("{}/api.php?", self.server_url); let params: Box<[(&str, &str)]> = Box::from([ - ("action", "edit"), // Create and edit pages. + ("action", "edit"), // Create and edit pages. ("format", "json"), - ("title", page_title), // Title of the page to edit. Cannot be used together with pageid. - ("appendtext", page_content), // Add this text to the end of the page or section. Overrides text. + ("title", page_title), // Title of the page to edit. Cannot be used together with pageid. + ("text", page_content), // Add this text to the end of the page or section. Overrides text. ("token", self.csrf_token.as_str()), // A "csrf" token retrieved from action=query&meta=tokens ("bot", "true"), // Mark this edit as a bot edit. ]); - self.make_request(url, params, RequestType::Post) + let request_result = self.make_request(url, params, RequestType::Post); + + self.update_plenum_page(page_title)?; + + request_result + } + /// Downloads the main Plenum Page from Mediawiki, inserts the Link to the new Page and replaces the content of the mediawiki- + pub fn update_plenum_page (&self, new_page_title_to_link_to: &str) -> Result<(), Box> { + // 1. Download Plenum page content + let page_content = self.get_page_content(&self.plenum_main_page_name)?; + println!("---\nPage Content: {}\n---", page_content.red()); + let current_year = "2024"; // TODO: Datumslogik einbauen + let year_section = format!("=== {} ===\n", current_year); + if page_content.contains(&year_section) { + let mut content_split: Vec<&str> = page_content.split(&year_section).collect(); + println!("Length: {}", content_split.len()); + let rest_of_content = content_split.pop().unwrap_or_default(); + let updated_section = format!("{}{}\n* {}", content_split.join(&year_section), year_section, new_page_title_to_link_to); + //format!("{}{}", updated_section, rest_of_content) + } + Ok(()) + } + pub fn get_page_content (&self, page_title: &str) -> Result> { + let url = + format!("{}/api.php?", self.server_url); + let params: Box<[(&str, &str)]> = Box::from([ + ("action", "parse"), // Create and edit pages. + ("prop", "wikitext"), + ("format", "json"), + ("page", page_title), + ("formatversion", "2"), + ]); + let resp: Result> = self.make_request(url, params, RequestType::Get); + let resp = resp?; + let response_deserialized: ParseResponse = serde_json::from_str(&resp)?; + Ok(response_deserialized.parse.wikitext) + } + pub fn get_page_section_title (&self, page_title: &str, section_number: &str) -> Result> { + let url = + format!("{}/api.php?", self.server_url); + let params: Box<[(&str, &str)]> = Box::from([ + ("action", "parse"), // Create and edit pages. + ("contentmodel", "wikitext"), + ("format", "json"), + ("page", page_title), + ]); + let resp: Result> = self.make_request(url, params, RequestType::Get); + let resp = resp?; + todo!() + //let response_deserialized = serde_json::from_str(&resp)?; + //Ok(response_deserialized["parse"]) + } + pub fn edit_section (&self, page_title: &str, text_to_prepend: &str, section_number: &str) -> Result> { + let url = + format!("{}/api.php?", self.server_url); + let params: Box<[(&str, &str)]> = Box::from([ + ("action", "edit"), // Create and edit pages. + ("format", "json"), + ("title", page_title), // Title of the page to edit. Cannot be used together with pageid. + ("section", section_number), // Section identifier. 0 for the top section, new for a new section. Often a positive integer, but can also be non-numeric + ("prependtext", text_to_prepend), // Add this text to the end of the page or section. Overrides text. + ("token", self.csrf_token.as_str()), // A "csrf" token retrieved from action=query&meta=tokens + ("bot", "true"), // Mark this edit as a bot edit. + ]); + let request_result = self.make_request(url, params, RequestType::Post); + + request_result } } @@ -219,6 +292,28 @@ struct QueryTokensCsrf { struct TokensCsrf { csrftoken: String, } +// For get_page_content: +#[derive(Deserialize)] +struct ParseResponse { + parse: ParseContent, +} + +#[derive(Deserialize)] +struct ParseContent { + wikitext: String, +} +// For get_page_section: +/* +#[derive(Deserialize)] +struct ParseSectionResponse { + parse: ParseSectionContent, +} +#[derive(Deserialize)] +struct ParseSectionContent { + sections: , +} + + */ pub fn pad_ins_wiki(old_pad_content: String, wiki: &mut Mediawiki) -> Result<(), Box> { // Login to Wiki and get required tokens for logging in and writing @@ -239,7 +334,10 @@ pub fn pad_ins_wiki(old_pad_content: String, wiki: &mut Mediawiki) -> Result<(), // Convert to mediawiki and make new page let pad_converted = convert_md_to_mediawiki(old_pad_content); println!("Das kommt ins Wiki: {}", pad_converted); - //wiki.new_wiki_page("Page Test 5", &pad_converted)?; JUST AN EXAMPLE + let page_title = "Page Test 5"; + let page_title = format!("{}/{}", wiki.plenum_main_page_name, page_title); // Example: Plenum/13._August_2024 + wiki.new_wiki_page(&page_title, &pad_converted)?; + // Textdatei wieder einlesen @@ -291,3 +389,11 @@ fn convert_md_to_mediawiki(old_pad_content: String) -> String { println!("TEMP: {}", temp.purple()); temp } + +/* +fn create_title (nächster_plenumstermin: String) { + let date_simple = NaiveDate::from(nächster_plenumstermin); + let wiki_page_title = format!("{} {} {}", date_simple.day(), LongMonthName[date_simple.month()], date_simple.year()); +} + + */