feat: timezone implementation
This commit is contained in:
parent
41f9b6f3f5
commit
b2c44e9003
224
src/main.rs
224
src/main.rs
|
@ -1,13 +1,14 @@
|
|||
use copy_dir::copy_dir;
|
||||
use std::fs::{create_dir_all, remove_file, write, File, OpenOptions};
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::fs::{create_dir_all, read_to_string, remove_file, write, File, OpenOptions};
|
||||
use std::io::{BufRead, BufReader, Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Stdio;
|
||||
|
||||
use askama::Template;
|
||||
use base64::prelude::BASE64_STANDARD;
|
||||
use base64::Engine;
|
||||
use chrono::{DateTime, Days, Local};
|
||||
use chrono::offset::FixedOffset;
|
||||
use chrono::{DateTime, Days, Local, Utc};
|
||||
use clap::{command, Parser};
|
||||
use color_eyre::eyre::{eyre, OptionExt, Result};
|
||||
use futures::future::join_all;
|
||||
|
@ -42,6 +43,10 @@ struct Config {
|
|||
///The used as the journal
|
||||
#[arg(short, long)]
|
||||
url: String,
|
||||
|
||||
///The timezone used if none is given in the data folder
|
||||
#[arg(short, long)]
|
||||
timezone: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Template)]
|
||||
|
@ -89,11 +94,18 @@ async fn generate_post(config: &Config, client: &mut Client) -> Result<String> {
|
|||
attachments.push(id.to_string());
|
||||
}
|
||||
}
|
||||
let time = get_msg_time(&v).ok_or_eyre("Message without time???")?;
|
||||
let secs = config.timezone.parse::<i32>()?;
|
||||
println!("{:?}", secs);
|
||||
let tz = FixedOffset::east_opt(config.timezone.parse::<i32>()? * 3600)
|
||||
.ok_or_eyre("timezone von nem anderen planete?")?;
|
||||
let time = time.with_timezone(&tz);
|
||||
println!("{:?}", time);
|
||||
|
||||
msgs.push(Message {
|
||||
content: get_msg_text(&v).unwrap_or("").to_string(),
|
||||
attachments,
|
||||
time: get_msg_time(&v).ok_or_eyre("Message without time???")?,
|
||||
time: time.format("%H:%M").to_string(),
|
||||
});
|
||||
}
|
||||
if msgs.is_empty() {
|
||||
|
@ -117,10 +129,15 @@ async fn generate_post(config: &Config, client: &mut Client) -> Result<String> {
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let config = Config::parse();
|
||||
let mut config = Config::parse();
|
||||
if !Path::new(&config.data_folder).exists() {
|
||||
create_dir_all(&config.data_folder)?
|
||||
}
|
||||
let tz_data_path = format!("{}/tz.data", config.data_folder);
|
||||
if Path::new(&tz_data_path).exists() {
|
||||
config.timezone = read_to_string(&tz_data_path)?;
|
||||
}
|
||||
println!("{:?}", config.timezone);
|
||||
|
||||
let mut cmd = Command::new(COMMAND_PATH)
|
||||
.arg("jsonRpc")
|
||||
|
@ -146,131 +163,69 @@ async fn main() -> Result<()> {
|
|||
continue;
|
||||
} else if sender != &config.allowed_sender {
|
||||
println!("{:?}", sender);
|
||||
client
|
||||
.send(
|
||||
None,
|
||||
vec![sender.to_string()],
|
||||
Vec::new(),
|
||||
false,
|
||||
false,
|
||||
"This is the signal-to-blog bot, you are not in the list of allowed writers."
|
||||
.to_string(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
send(
|
||||
&client,
|
||||
sender,
|
||||
"This is the signal-to-blog bot, you are not in the list of allowed writers."
|
||||
.to_string(),
|
||||
)
|
||||
.await?;
|
||||
continue;
|
||||
};
|
||||
println!("{v}");
|
||||
println!("{:?}", text);
|
||||
if let Some(text) = text {
|
||||
// ©ontrol character
|
||||
if let Some(text) = text.strip_prefix("©").and_then(|x| Some(x.trim())) {
|
||||
match text {
|
||||
let cmds: Vec<&str> = text.split_whitespace().collect();
|
||||
if cmds.len() >= 2 && cmds[0] == "©" {
|
||||
match cmds[1] {
|
||||
"help" => {
|
||||
let text = "
|
||||
Available commands:
|
||||
- post: Generate post for yesterday
|
||||
- tz: change timezone
|
||||
"
|
||||
.to_string();
|
||||
send(&client, sender, text).await?;
|
||||
}
|
||||
"post" => {
|
||||
let res = generate_post(&config, &mut client).await;
|
||||
if let Ok(res) = res {
|
||||
client
|
||||
.send(
|
||||
None,
|
||||
vec![sender.to_string()],
|
||||
Vec::new(),
|
||||
false,
|
||||
false,
|
||||
format!("Generated blog post at: {}/{}", config.url, res)
|
||||
.to_string(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
send(
|
||||
&client,
|
||||
sender,
|
||||
format!("Generated blog post at: {}/{}", config.url, res),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
client
|
||||
.send(
|
||||
None,
|
||||
vec![sender.to_string()],
|
||||
Vec::new(),
|
||||
false,
|
||||
false,
|
||||
format!("Error generating blog post:\n{:?}", res).to_string(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
send(
|
||||
&client,
|
||||
sender,
|
||||
format!("Error generating blog post:\n{:?}", res),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
"tz" => {
|
||||
if cmds.get(2).is_some_and(|x| {
|
||||
x.parse::<i32>()
|
||||
.is_ok_and(|x| FixedOffset::east_opt(x * 3600).is_some())
|
||||
}) {
|
||||
println!("{}", tz_data_path);
|
||||
let mut file = OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.open(&tz_data_path)?;
|
||||
file.write_all(cmds[2].as_bytes())?;
|
||||
config.timezone = cmds[2].to_string();
|
||||
|
||||
send(&client, sender, format!("Updated tz data")).await?;
|
||||
} else {
|
||||
send(&client, sender, format!("Error parsing")).await?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
client
|
||||
.send(
|
||||
None,
|
||||
vec![sender.to_string()],
|
||||
Vec::new(),
|
||||
false,
|
||||
false,
|
||||
format!("Unknown command: {}", text).to_string(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
send(&client, sender, format!("Unknown command: {}", text)).await?;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
@ -283,6 +238,36 @@ async fn main() -> Result<()> {
|
|||
writeln!(file, "{}", v.to_string())?;
|
||||
}
|
||||
}
|
||||
async fn send(client: &Client, sender: &str, msg: String) -> Result<()> {
|
||||
client
|
||||
.send(
|
||||
None,
|
||||
vec![sender.to_string()],
|
||||
Vec::new(),
|
||||
false,
|
||||
false,
|
||||
msg,
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// make sure the directory exists before trying to save into it
|
||||
fn save_picture(file: &PathBuf, content: &str) -> Result<()> {
|
||||
|
@ -325,12 +310,11 @@ fn get_msg_sender(val: &Value) -> Option<&str> {
|
|||
val.pointer("/envelope/source").and_then(|x| x.as_str())
|
||||
}
|
||||
|
||||
fn get_msg_time(val: &Value) -> Option<String> {
|
||||
fn get_msg_time(val: &Value) -> Option<DateTime<Utc>> {
|
||||
let time = val
|
||||
.pointer("/envelope/timestamp")
|
||||
.and_then(|x| x.as_i64())?;
|
||||
let time = DateTime::from_timestamp(time, 0)?;
|
||||
Some(time.format("%H:%M").to_string())
|
||||
DateTime::from_timestamp_millis(time)
|
||||
}
|
||||
|
||||
fn get_msg_text(val: &Value) -> Option<&str> {
|
||||
|
|
Loading…
Reference in a new issue