commit 58577ea45e41c56ea3628dfb47edc1649f4feb12
parent ff3588022872e8851cda6d6c5d746407c830ac1c
Author: devnibo <kroekerrobin@gmail.com>
Date: Sun, 24 Sep 2023 15:49:00 +0200
Use rustfmt
Diffstat:
| M | src/i18n.rs | | | 214 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
| M | src/main.rs | | | 1030 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
2 files changed, 629 insertions(+), 615 deletions(-)
diff --git a/src/i18n.rs b/src/i18n.rs
@@ -2,138 +2,140 @@ use std::fs;
#[derive(Clone)]
pub struct ReportMsgs {
- pub msg: String,
- pub error_msg: String,
- pub success_msg: String,
- pub cancel_msg: String
+ pub msg: String,
+ pub error_msg: String,
+ pub success_msg: String,
+ pub cancel_msg: String,
}
#[derive(Clone)]
pub struct I18n {
- lang: String,
- pub start_msg: String,
- pub song_not_found: String,
- pub report: ReportMsgs
+ lang: String,
+ pub start_msg: String,
+ pub song_not_found: String,
+ pub report: ReportMsgs,
}
impl I18n {
- pub fn new(lang: String, songs_path: String) -> Self {
- match lang.as_str() {
- "de" => {
- Self {
- lang,
- start_msg: String::from(format!(
- "Hallo. Dies ist ein digitales Liederbuch. :)\n\
+ pub fn new(lang: String, songs_path: String) -> Self {
+ match lang.as_str() {
+ "de" => Self {
+ lang,
+ start_msg: String::from(format!(
+ "Hallo. Dies ist ein digitales Liederbuch. :)\n\
Befehle:\n\
/list - Listet alle Lieder auf\n\
{}\
Ansonsten tippe einfach den Titel oder Teile des Titels \
des Liedes ein und du bekommst dein Lied zugeschickt.",
- get_commands(songs_path).as_str()
- )),
- song_not_found: String::from("Kein Lied mit diesem Titel gefunden."),
- report: ReportMsgs{
- msg: String::from("Bitte sende einen gefundenen Fehler \
- entweder als Text oder Sprachnachricht."),
- error_msg: String::from("Das hat nicht funktioniert. Versuche es nochmal oder /cancel."),
- success_msg: String::from("Deine Korrektur wurde erfolgreich gemeldet."),
- cancel_msg: String::from("Das Fehlermelden wurde abgebrochen.")
- }
- }
- },
- "md" => {
- Self {
- lang,
- start_msg: String::from(format!(
- "Salut! Această e o carte de cântari digitală. :)\n\
+ get_commands(songs_path).as_str()
+ )),
+ song_not_found: String::from("Kein Lied mit diesem Titel gefunden."),
+ report: ReportMsgs {
+ msg: String::from(
+ "Bitte sende einen gefundenen Fehler \
+ entweder als Text oder Sprachnachricht.",
+ ),
+ error_msg: String::from(
+ "Das hat nicht funktioniert. Versuche es nochmal oder /cancel.",
+ ),
+ success_msg: String::from("Deine Korrektur wurde erfolgreich gemeldet."),
+ cancel_msg: String::from("Das Fehlermelden wurde abgebrochen."),
+ },
+ },
+ "md" => Self {
+ lang,
+ start_msg: String::from(format!(
+ "Salut! Această e o carte de cântari digitală. :)\n\
Comenzi:\n\
/list - Listează toate cântările\n\
{}\
Deasemenea puteți introduce titlul sau cuvinte din titlul \
cântării iar bot-ul va găsi piesa corespondentă.",
- get_commands(songs_path).as_str()
- )),
- song_not_found: String::from("Niciun cântec găsit cu acest nume"),
- report: ReportMsgs{
- msg: String::from("Vă rugăm să trimiteți eroare pe care \
- ați găsit-o fie ca mesaj text sau vocal."),
- error_msg: String::from("Asta nu a mers. Încercați din nou sau /cancel"),
- success_msg: String::from("A raportat corect corectia."),
- cancel_msg: String::from("Raportarea a fost anulată.")
- }
- }
- },
- _ => {
- Self {
- lang,
- start_msg: String::from(format!(
- "Hello. This is a digital song book. :)\n\
+ get_commands(songs_path).as_str()
+ )),
+ song_not_found: String::from("Niciun cântec găsit cu acest nume"),
+ report: ReportMsgs {
+ msg: String::from(
+ "Vă rugăm să trimiteți eroare pe care \
+ ați găsit-o fie ca mesaj text sau vocal.",
+ ),
+ error_msg: String::from("Asta nu a mers. Încercați din nou sau /cancel"),
+ success_msg: String::from("A raportat corect corectia."),
+ cancel_msg: String::from("Raportarea a fost anulată."),
+ },
+ },
+ _ => Self {
+ lang,
+ start_msg: String::from(format!(
+ "Hello. This is a digital song book. :)\n\
Commands:\n\
/list - Lists all songs\n\
{}\
Otherwise simply type the title or parts of the title \
of the song and you will receive the song.",
- get_commands(songs_path).as_str()
- )),
- song_not_found: String::from("Didn't find any song with this title."),
- report: ReportMsgs{
- msg: String::from("Please send an error you found \
- either as text or voice message."),
- error_msg: String::from("That didn't work. Try again or /cancel."),
- success_msg: String::from("Successfully reported your correction."),
- cancel_msg: String::from("Reporting canceled.")
- }
- }
- }
- }
- }
- pub fn format(&self, name: &String) -> String {
- let mut formatted_name = name.to_string();
- match self.lang.as_str() {
- "de" => {
- formatted_name = formatted_name.replace("Ö", "Oe");
- formatted_name = formatted_name.replace("ö", "oe");
- formatted_name = formatted_name.replace("Ü", "Ue");
- formatted_name = formatted_name.replace("ü", "ue");
- formatted_name = formatted_name.replace("Ä", "Ae");
- formatted_name = formatted_name.replace("ä", "ae");
- formatted_name = formatted_name.replace("ß", "ss");
- },
- "md" => {
- formatted_name = formatted_name.replace("ă", "a");
- formatted_name = formatted_name.replace("â", "a");
- formatted_name = formatted_name.replace("î", "i");
- formatted_name = formatted_name.replace("ș", "s");
- formatted_name = formatted_name.replace("ț", "t");
- },
- _ => {}
- }
- formatted_name = formatted_name.replace("-", "_");
- formatted_name = formatted_name.replace(" ", "_");
- return formatted_name;
- }
+ get_commands(songs_path).as_str()
+ )),
+ song_not_found: String::from("Didn't find any song with this title."),
+ report: ReportMsgs {
+ msg: String::from(
+ "Please send an error you found \
+ either as text or voice message.",
+ ),
+ error_msg: String::from("That didn't work. Try again or /cancel."),
+ success_msg: String::from("Successfully reported your correction."),
+ cancel_msg: String::from("Reporting canceled."),
+ },
+ },
+ }
+ }
+ pub fn format(&self, name: &String) -> String {
+ let mut formatted_name = name.to_string();
+ match self.lang.as_str() {
+ "de" => {
+ formatted_name = formatted_name.replace("Ö", "Oe");
+ formatted_name = formatted_name.replace("ö", "oe");
+ formatted_name = formatted_name.replace("Ü", "Ue");
+ formatted_name = formatted_name.replace("ü", "ue");
+ formatted_name = formatted_name.replace("Ä", "Ae");
+ formatted_name = formatted_name.replace("ä", "ae");
+ formatted_name = formatted_name.replace("ß", "ss");
+ }
+ "md" => {
+ formatted_name = formatted_name.replace("ă", "a");
+ formatted_name = formatted_name.replace("â", "a");
+ formatted_name = formatted_name.replace("î", "i");
+ formatted_name = formatted_name.replace("ș", "s");
+ formatted_name = formatted_name.replace("ț", "t");
+ }
+ _ => {}
+ }
+ formatted_name = formatted_name.replace("-", "_");
+ formatted_name = formatted_name.replace(" ", "_");
+ return formatted_name;
+ }
}
fn get_commands(songs_path: String) -> String {
- let mut commands: String = String::new();
- for name in get_folder_names(&songs_path) {
- commands.push_str(&("/".to_owned() + name.as_str() + "\n"));
- }
- return commands;
+ let mut commands: String = String::new();
+ for name in get_folder_names(&songs_path) {
+ commands.push_str(&("/".to_owned() + name.as_str() + "\n"));
+ }
+ return commands;
}
pub fn get_folder_names(songs_path: &String) -> Vec<String> {
- let songs_dir = fs::read_dir(songs_path).unwrap();
- let mut folder_names: Vec<String> = vec![];
- let mut is_dir: bool;
- let mut dir_entry;
- for f in songs_dir {
- dir_entry = f.expect("Error: f");
- is_dir = dir_entry.file_type().unwrap().is_dir();
- if is_dir {
- let name: String = dir_entry.file_name().to_str().unwrap().to_string();
- folder_names.push(name)
- }
- }
- return folder_names;
+ let songs_dir = fs::read_dir(songs_path).unwrap();
+ let mut folder_names: Vec<String> = vec![];
+ let mut is_dir: bool;
+ let mut dir_entry;
+ for f in songs_dir {
+ dir_entry = f.expect("Error: f");
+ is_dir = dir_entry.file_type().unwrap().is_dir();
+ if is_dir {
+ let name: String = dir_entry.file_name().to_str().unwrap().to_string();
+ folder_names.push(name)
+ }
+ }
+ return folder_names;
}
diff --git a/src/main.rs b/src/main.rs
@@ -1,23 +1,23 @@
+use bytes::Bytes;
use clap::Parser;
-use frankenstein::Api;
-use frankenstein::TelegramApi;
-use frankenstein::SendMessageParams;
-use frankenstein::GetUpdatesParams;
-use frankenstein::ChatId;
-use frankenstein::Message;
use frankenstein::api_params::File;
-use frankenstein::api_params::InputFile;
use frankenstein::api_params::GetFileParams;
+use frankenstein::api_params::InputFile;
use frankenstein::api_params::SendDocumentParams;
-use frankenstein::objects::UpdateContent;
use frankenstein::objects::AllowedUpdate;
+use frankenstein::objects::UpdateContent;
+use frankenstein::Api;
+use frankenstein::ChatId;
+use frankenstein::GetUpdatesParams;
+use frankenstein::Message;
+use frankenstein::SendMessageParams;
+use frankenstein::TelegramApi;
use std::fs::DirEntry;
-use std::{fs, thread, time, process};
use std::io::Write;
-use bytes::Bytes;
+use std::{fs, process, thread, time};
mod i18n;
-use i18n::I18n;
use config_file::FromConfigFile;
+use i18n::I18n;
use serde::Deserialize;
/*
@@ -31,578 +31,590 @@ const MAX_TEXT_LEN: usize = 4096;
#[derive(Parser, Debug, Deserialize)]
struct Config {
- #[arg(short, long, help = "telegram bot api token")]
- token: Option<String>,
- #[arg(short, long, help = "path to folder with pdf files")]
- songs_path: Option<String>,
- #[arg(short, long, default_value = "en", help = "language that the bot speaks: 'en', 'de' or 'md'")]
- lang: Option<String>,
- #[arg(short = 'f', long, help = "path to search file")]
- search_file: Option<String>,
- #[arg(short, long, help = "path to folder where reports will be saved")]
- reports_path: Option<String>,
- #[arg(short, long, help = "path to yml config file")]
- config: Option<String>
+ #[arg(short, long, help = "telegram bot api token")]
+ token: Option<String>,
+ #[arg(short, long, help = "path to folder with pdf files")]
+ songs_path: Option<String>,
+ #[arg(
+ short,
+ long,
+ default_value = "en",
+ help = "language that the bot speaks: 'en', 'de' or 'md'"
+ )]
+ lang: Option<String>,
+ #[arg(short = 'f', long, help = "path to search file")]
+ search_file: Option<String>,
+ #[arg(short, long, help = "path to folder where reports will be saved")]
+ reports_path: Option<String>,
+ #[arg(short, long, help = "path to yml config file")]
+ config: Option<String>,
}
impl Config {
- pub fn new() -> Self {
- Self {
- token: None,
- songs_path: None,
- lang: None,
- search_file: None,
- reports_path: None,
- config: None
- }
- }
+ pub fn new() -> Self {
+ Self {
+ token: None,
+ songs_path: None,
+ lang: None,
+ search_file: None,
+ reports_path: None,
+ config: None,
+ }
+ }
}
struct SongNotFound {
- message: String
+ message: String,
}
struct HandleArg {
- api: Api,
- msg: Option<Message>,
- token: String,
- reports_path: Option<String>,
- i18n: I18n,
- songs_path: String,
- search_file: Option<String>
+ api: Api,
+ msg: Option<Message>,
+ token: String,
+ reports_path: Option<String>,
+ i18n: I18n,
+ songs_path: String,
+ search_file: Option<String>,
}
struct HandleResult {
- wait_for_report: bool
+ wait_for_report: bool,
}
enum OutgoingTextMsg {
- DirEntry(Vec<DirEntry>),
- String(Vec<String>)
+ DirEntry(Vec<DirEntry>),
+ String(Vec<String>),
}
struct FindSongArgs {
- songs_path: String,
- i18n: I18n,
- search_string: String,
- search_type: SearchType,
- search_file: String
+ songs_path: String,
+ i18n: I18n,
+ search_string: String,
+ search_type: SearchType,
+ search_file: String,
}
#[derive(Debug)]
enum SearchType {
- Title,
- FullText
+ Title,
+ FullText,
}
struct SearchResult {
- ss_in_title: Vec<String>,
- ss_in_lyrics: Vec<String>
+ ss_in_title: Vec<String>,
+ ss_in_lyrics: Vec<String>,
}
enum ReportFileType {
- Voice(Bytes),
- Text(String)
+ Voice(Bytes),
+ Text(String),
}
fn main() {
- let config = get_config();
- let api = Api::new(&config.token.clone().unwrap().as_str());
- let is_reports_path = config.reports_path.is_some();
- let songs_path: String = add_ending_slash(config.songs_path.unwrap());
- let mut handle_arg = HandleArg {
- api: api.clone(),
- msg: None,
- token: config.token.unwrap().clone(),
- reports_path: config.reports_path.clone(),
- i18n: I18n::new(config.lang.unwrap(), songs_path.clone()),
- songs_path: songs_path.clone(),
- search_file: config.search_file.clone()
- };
- let mut updates_params = GetUpdatesParams::builder()
- .allowed_updates(vec![AllowedUpdate::Message])
- .build();
- let mut res = HandleResult{ wait_for_report: false };
- let mut handle_res: Option<HandleResult>;
- loop {
- let dur = time::Duration::from_millis(500);
- thread::sleep(dur);
- let result = TelegramApi::get_updates(&api, &updates_params);
- match result {
- Ok(val) => {
- for update in &val.result {
- updates_params.offset = Some(i64::from(update.update_id) + 1);
- match &update.content {
- UpdateContent::Message(msg) => {
- handle_arg.msg = Some(msg.clone());
- if is_reports_path && res.wait_for_report {
- handle_res = handle_report(&handle_arg);
- if handle_res.is_some() {
- res = handle_res.unwrap();
- }
- continue;
- }
- if msg.text.is_some() {
- handle_res = handle_text_message(&handle_arg);
- if handle_res.is_some() {
- res = handle_res.unwrap();
- }
- }
- },
- _ => {}
- }
- }
- },
- Err(_err) => {
- eprintln!("Error receiving updates from Telegram Bot API.");
- }
- }
- }
+ let config = get_config();
+ let api = Api::new(&config.token.clone().unwrap().as_str());
+ let is_reports_path = config.reports_path.is_some();
+ let songs_path: String = add_ending_slash(config.songs_path.unwrap());
+ let mut handle_arg = HandleArg {
+ api: api.clone(),
+ msg: None,
+ token: config.token.unwrap().clone(),
+ reports_path: config.reports_path.clone(),
+ i18n: I18n::new(config.lang.unwrap(), songs_path.clone()),
+ songs_path: songs_path.clone(),
+ search_file: config.search_file.clone(),
+ };
+ let mut updates_params = GetUpdatesParams::builder()
+ .allowed_updates(vec![AllowedUpdate::Message])
+ .build();
+ let mut res = HandleResult {
+ wait_for_report: false,
+ };
+ let mut handle_res: Option<HandleResult>;
+ loop {
+ let dur = time::Duration::from_millis(500);
+ thread::sleep(dur);
+ let result = TelegramApi::get_updates(&api, &updates_params);
+ match result {
+ Ok(val) => {
+ for update in &val.result {
+ updates_params.offset = Some(i64::from(update.update_id) + 1);
+ match &update.content {
+ UpdateContent::Message(msg) => {
+ handle_arg.msg = Some(msg.clone());
+ if is_reports_path && res.wait_for_report {
+ handle_res = handle_report(&handle_arg);
+ if handle_res.is_some() {
+ res = handle_res.unwrap();
+ }
+ continue;
+ }
+ if msg.text.is_some() {
+ handle_res = handle_text_message(&handle_arg);
+ if handle_res.is_some() {
+ res = handle_res.unwrap();
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+ Err(_err) => {
+ eprintln!("Error receiving updates from Telegram Bot API.");
+ }
+ }
+ }
}
fn get_config() -> Config {
- let mut config: Config = Config::new();
- let args = Config::parse();
- if args.config.is_some() {
- config = Config::from_config_file(args.config.unwrap()).unwrap();
- }
- if args.token.is_some() {
- config.token = args.token;
- }
- if args.songs_path.is_some() {
- config.songs_path = args.songs_path;
- }
- if args.lang.is_some() {
- config.lang = args.lang;
- }
- if args.search_file.is_some() {
- config.search_file = args.search_file;
- }
- if args.reports_path.is_some() {
- config.reports_path = args.reports_path;
- }
- if config.token.is_none() || config.songs_path.is_none() {
- eprintln!("Provide at least a --token and a --songs-path.");
- process::exit(-1);
- }
- config
+ let mut config: Config = Config::new();
+ let args = Config::parse();
+ if args.config.is_some() {
+ config = Config::from_config_file(args.config.unwrap()).unwrap();
+ }
+ if args.token.is_some() {
+ config.token = args.token;
+ }
+ if args.songs_path.is_some() {
+ config.songs_path = args.songs_path;
+ }
+ if args.lang.is_some() {
+ config.lang = args.lang;
+ }
+ if args.search_file.is_some() {
+ config.search_file = args.search_file;
+ }
+ if args.reports_path.is_some() {
+ config.reports_path = args.reports_path;
+ }
+ if config.token.is_none() || config.songs_path.is_none() {
+ eprintln!("Provide at least a --token and a --songs-path.");
+ process::exit(-1);
+ }
+ config
}
fn add_ending_slash(path: String) -> String {
- if !path.ends_with("/") {
- let mut new_path = path.to_owned();
- new_path.push_str("/");
- return new_path;
- }
- else {
- return path;
- }
+ if !path.ends_with("/") {
+ let mut new_path = path.to_owned();
+ new_path.push_str("/");
+ return new_path;
+ } else {
+ return path;
+ }
}
fn handle_text_message(args: &HandleArg) -> Option<HandleResult> {
- let mut find_song_args = FindSongArgs {
- search_string: String::new(),
- songs_path: args.songs_path.clone(),
- i18n: args.i18n.clone(),
- search_type: SearchType::Title,
- search_file: String::new()
- };
- if args.search_file.as_ref().is_some() {
- let search_file = args.search_file.as_ref().unwrap();
- if fs::File::open(search_file).is_ok() {
- find_song_args.search_type = SearchType::FullText;
- find_song_args.search_file = search_file.to_string();
- }
- }
- let msg = args.msg.clone().unwrap();
- let text: &str = msg.text.as_ref().unwrap();
- let chat_id: u64 = msg.from.as_ref().unwrap().id;
- let mut params = SendMessageParams::builder()
- .chat_id(ChatId::Integer(chat_id.try_into().unwrap()))
- .text("")
- .build();
- match text {
- "/start" => {
- params.text = (args.i18n.start_msg).to_string();
- send_message(&args.api, &mut params);
- },
- "/list" => {
- let songs = get_songs(&args.songs_path, None);
- params.text = form_msg(OutgoingTextMsg::DirEntry(songs));
- send_message(&args.api, &mut params);
- },
- "/report" => {
- params.text = args.i18n.report.msg.clone();
- send_message(&args.api, &mut params);
- return Some(HandleResult{ wait_for_report: true });
- },
- _ => {
- if text.starts_with("/") {
- for name in i18n::get_folder_names(&args.songs_path) {
- if text == "/".to_owned() + name.as_str() {
- let songs = get_songs(&args.songs_path, Some(&name));
- params.text = form_msg(OutgoingTextMsg::DirEntry(songs));
- send_message(&args.api, &mut params);
- return None;
- }
- }
- let len = text.as_bytes().len();
- find_song_args.search_string = text[1..len].to_string();
- match title_search(&find_song_args) {
- Ok(files) => {
- let file = files.get(0);
- let input_file = InputFile::builder()
- .path(file.unwrap().path())
- .build();
- let send_document_params = SendDocumentParams::builder()
- .chat_id(ChatId::Integer(chat_id.try_into().unwrap()))
- .document(File::InputFile(input_file))
- .build();
- send_document(&args.api, &send_document_params);
- },
- Err(err) => {
- eprintln!("{}", err.message);
- params.text = (args.i18n.song_not_found).to_string();
- send_message(&args.api, &mut params);
- }
- }
- }
- else {
- find_song_args.search_string = text.to_string();
- match find_song_args.search_type {
- SearchType::Title => {
- match title_search(&find_song_args) {
- Ok(files) => {
- params.text = form_msg(OutgoingTextMsg::DirEntry(files));
- send_message(&args.api, &mut params);
- },
- Err(err) => {
- eprintln!("{}", err.message);
- params.text = (args.i18n.song_not_found).to_string();
- send_message(&args.api, &mut params);
- }
- }
- },
- SearchType::FullText => {
- match full_text_search(&find_song_args) {
- Ok(search_result) => {
- let ss_in_title = form_msg(OutgoingTextMsg::String(search_result.ss_in_title));
- let ss_in_lyrics = form_msg(OutgoingTextMsg::String(search_result.ss_in_lyrics));
- params.text.push_str(&ss_in_title);
- params.text.push_str(&ss_in_lyrics);
- send_message(&args.api, &mut params);
- },
- Err(err) => {
- eprintln!("{}", err.message);
- params.text = (args.i18n.song_not_found).to_string();
- send_message(&args.api, &mut params);
- }
- }
- }
- }
- }
- }
- }
- return None;
+ let mut find_song_args = FindSongArgs {
+ search_string: String::new(),
+ songs_path: args.songs_path.clone(),
+ i18n: args.i18n.clone(),
+ search_type: SearchType::Title,
+ search_file: String::new(),
+ };
+ if args.search_file.as_ref().is_some() {
+ let search_file = args.search_file.as_ref().unwrap();
+ if fs::File::open(search_file).is_ok() {
+ find_song_args.search_type = SearchType::FullText;
+ find_song_args.search_file = search_file.to_string();
+ }
+ }
+ let msg = args.msg.clone().unwrap();
+ let text: &str = msg.text.as_ref().unwrap();
+ let chat_id: u64 = msg.from.as_ref().unwrap().id;
+ let mut params = SendMessageParams::builder()
+ .chat_id(ChatId::Integer(chat_id.try_into().unwrap()))
+ .text("")
+ .build();
+ match text {
+ "/start" => {
+ params.text = (args.i18n.start_msg).to_string();
+ send_message(&args.api, &mut params);
+ }
+ "/list" => {
+ let songs = get_songs(&args.songs_path, None);
+ params.text = form_msg(OutgoingTextMsg::DirEntry(songs));
+ send_message(&args.api, &mut params);
+ }
+ "/report" => {
+ params.text = args.i18n.report.msg.clone();
+ send_message(&args.api, &mut params);
+ return Some(HandleResult {
+ wait_for_report: true,
+ });
+ }
+ _ => {
+ if text.starts_with("/") {
+ for name in i18n::get_folder_names(&args.songs_path) {
+ if text == "/".to_owned() + name.as_str() {
+ let songs = get_songs(&args.songs_path, Some(&name));
+ params.text = form_msg(OutgoingTextMsg::DirEntry(songs));
+ send_message(&args.api, &mut params);
+ return None;
+ }
+ }
+ let len = text.as_bytes().len();
+ find_song_args.search_string = text[1..len].to_string();
+ match title_search(&find_song_args) {
+ Ok(files) => {
+ let file = files.get(0);
+ let input_file = InputFile::builder().path(file.unwrap().path()).build();
+ let send_document_params = SendDocumentParams::builder()
+ .chat_id(ChatId::Integer(chat_id.try_into().unwrap()))
+ .document(File::InputFile(input_file))
+ .build();
+ send_document(&args.api, &send_document_params);
+ }
+ Err(err) => {
+ eprintln!("{}", err.message);
+ params.text = (args.i18n.song_not_found).to_string();
+ send_message(&args.api, &mut params);
+ }
+ }
+ } else {
+ find_song_args.search_string = text.to_string();
+ match find_song_args.search_type {
+ SearchType::Title => match title_search(&find_song_args) {
+ Ok(files) => {
+ params.text = form_msg(OutgoingTextMsg::DirEntry(files));
+ send_message(&args.api, &mut params);
+ }
+ Err(err) => {
+ eprintln!("{}", err.message);
+ params.text = (args.i18n.song_not_found).to_string();
+ send_message(&args.api, &mut params);
+ }
+ },
+ SearchType::FullText => match full_text_search(&find_song_args) {
+ Ok(search_result) => {
+ let ss_in_title =
+ form_msg(OutgoingTextMsg::String(search_result.ss_in_title));
+ let ss_in_lyrics =
+ form_msg(OutgoingTextMsg::String(search_result.ss_in_lyrics));
+ params.text.push_str(&ss_in_title);
+ params.text.push_str(&ss_in_lyrics);
+ send_message(&args.api, &mut params);
+ }
+ Err(err) => {
+ eprintln!("{}", err.message);
+ params.text = (args.i18n.song_not_found).to_string();
+ send_message(&args.api, &mut params);
+ }
+ },
+ }
+ }
+ }
+ }
+ return None;
}
fn handle_report(args: &HandleArg) -> Option<HandleResult> {
- let msg = args.msg.clone().unwrap();
- let reports_path = args.reports_path.clone().unwrap();
- let chat_id: u64 = msg.from.as_ref().unwrap().id;
- let mut params = SendMessageParams::builder()
- .chat_id(ChatId::Integer(chat_id.try_into().unwrap()))
- .text("")
- .build();
- if msg.voice.is_some() {
- let voice = msg.voice.clone().unwrap();
- match args.api.get_file(&GetFileParams{ file_id: voice.file_id }) {
- Ok(file) => {
- let file_path = file.result.file_path.unwrap();
- match download_file(&args.token, &file_path) {
- Ok(bytes) => save_file(ReportFileType::Voice(bytes), &reports_path),
- Err(_) => {}
- }
- },
- Err(_) => {}
- }
- params.text = args.i18n.report.success_msg.clone();
- send_message(&args.api, &mut params);
- return Some(HandleResult{ wait_for_report: false });
- }
- else if msg.text.is_some() {
- let text = msg.text.clone().unwrap();
- if text == String::from("/cancel") {
- params.text = String::from(args.i18n.report.cancel_msg.clone());
- send_message(&args.api, &mut params);
- return Some(HandleResult{ wait_for_report: false });
- }
- params.text = args.i18n.report.success_msg.clone();
- send_message(&args.api, &mut params);
- save_file(ReportFileType::Text(text), &reports_path);
- return Some(HandleResult{ wait_for_report: false });
- }
- else {
- params.text = args.i18n.report.error_msg.clone();
- send_message(&args.api, &mut params);
- return Some(HandleResult{ wait_for_report: true });
- }
+ let msg = args.msg.clone().unwrap();
+ let reports_path = args.reports_path.clone().unwrap();
+ let chat_id: u64 = msg.from.as_ref().unwrap().id;
+ let mut params = SendMessageParams::builder()
+ .chat_id(ChatId::Integer(chat_id.try_into().unwrap()))
+ .text("")
+ .build();
+ if msg.voice.is_some() {
+ let voice = msg.voice.clone().unwrap();
+ match args.api.get_file(&GetFileParams {
+ file_id: voice.file_id,
+ }) {
+ Ok(file) => {
+ let file_path = file.result.file_path.unwrap();
+ match download_file(&args.token, &file_path) {
+ Ok(bytes) => save_file(ReportFileType::Voice(bytes), &reports_path),
+ Err(_) => {}
+ }
+ }
+ Err(_) => {}
+ }
+ params.text = args.i18n.report.success_msg.clone();
+ send_message(&args.api, &mut params);
+ return Some(HandleResult {
+ wait_for_report: false,
+ });
+ } else if msg.text.is_some() {
+ let text = msg.text.clone().unwrap();
+ if text == String::from("/cancel") {
+ params.text = String::from(args.i18n.report.cancel_msg.clone());
+ send_message(&args.api, &mut params);
+ return Some(HandleResult {
+ wait_for_report: false,
+ });
+ }
+ params.text = args.i18n.report.success_msg.clone();
+ send_message(&args.api, &mut params);
+ save_file(ReportFileType::Text(text), &reports_path);
+ return Some(HandleResult {
+ wait_for_report: false,
+ });
+ } else {
+ params.text = args.i18n.report.error_msg.clone();
+ send_message(&args.api, &mut params);
+ return Some(HandleResult {
+ wait_for_report: true,
+ });
+ }
}
fn download_file(token: &String, file_path: &String) -> Result<Bytes, reqwest::Error> {
- let url = format!("https://api.telegram.org/file/bot{token}/{file_path}");
- let bytes = reqwest::blocking::get(url)?.bytes()?;
- return Ok(bytes);
+ let url = format!("https://api.telegram.org/file/bot{token}/{file_path}");
+ let bytes = reqwest::blocking::get(url)?.bytes()?;
+ return Ok(bytes);
}
fn save_file(t: ReportFileType, reports_path: &String) {
- let timestamp = chrono::offset::Utc::now().timestamp_millis();
- let filepath = reports_path.to_owned() + "/" + ×tamp.to_string();
- match t {
- ReportFileType::Voice(bytes) => {
- match fs::File::create(filepath + ".ogg") {
- Ok(mut file) => {
- let _res = file.write(&bytes);
- },
- Err(_) => {}
- }
- },
- ReportFileType::Text(mut text) => {
- match fs::File::create(filepath + ".txt") {
- Ok(mut file) => {
- text = text + "\n";
- let _res = file.write(text.as_bytes());
- },
- Err(_) => {}
- }
- }
- }
+ let timestamp = chrono::offset::Utc::now().timestamp_millis();
+ let filepath = reports_path.to_owned() + "/" + ×tamp.to_string();
+ match t {
+ ReportFileType::Voice(bytes) => match fs::File::create(filepath + ".ogg") {
+ Ok(mut file) => {
+ let _res = file.write(&bytes);
+ }
+ Err(_) => {}
+ },
+ ReportFileType::Text(mut text) => match fs::File::create(filepath + ".txt") {
+ Ok(mut file) => {
+ text = text + "\n";
+ let _res = file.write(text.as_bytes());
+ }
+ Err(_) => {}
+ },
+ }
}
fn send_document(api: &Api, params: &SendDocumentParams) {
- let result = api.send_document(params);
- match result {
- Err(err) => {
- eprintln!("send_document failed.");
- dbg!(err);
- },
- Ok(_res) => {}
- }
+ let result = api.send_document(params);
+ match result {
+ Err(err) => {
+ eprintln!("send_document failed.");
+ dbg!(err);
+ }
+ Ok(_res) => {}
+ }
}
fn send_message(api: &Api, params: &mut SendMessageParams) {
- let text_len = params.text.chars().count();
- let msg_count = text_len as f64 / MAX_TEXT_LEN as f64;
- if msg_count <= 1.0 {
- let result = api.send_message(params);
- match result {
- Err(err) => {
- eprintln!("send_message failed.");
- dbg!(err);
- },
- Ok(_res) => {}
- }
- } else {
- let mut text: String = params.text.clone();
- let mut part: &str;
- loop {
- if text.chars().count() > MAX_TEXT_LEN {
- match find_last_line_break(text.clone()) {
- Ok(index) => {
- part = &text[..index];
- params.text = part.to_string();
- let result = api.send_message(params);
- match result {
- Err(err) => {
- eprintln!("send_message failed.");
- dbg!(err);
- },
- Ok(_res) => {}
- }
- text = text[index+1..].to_string();
- },
- Err(_) => {
- eprintln!("Dude, there's no line break. Deal with it.");
- }
- }
- } else {
- params.text = text;
- let result = api.send_message(params);
- match result {
- Err(err) => {
- eprintln!("send_message failed.");
- dbg!(err);
- },
- Ok(_res) => {}
- }
- break;
- }
- }
- }
+ let text_len = params.text.chars().count();
+ let msg_count = text_len as f64 / MAX_TEXT_LEN as f64;
+ if msg_count <= 1.0 {
+ let result = api.send_message(params);
+ match result {
+ Err(err) => {
+ eprintln!("send_message failed.");
+ dbg!(err);
+ }
+ Ok(_res) => {}
+ }
+ } else {
+ let mut text: String = params.text.clone();
+ let mut part: &str;
+ loop {
+ if text.chars().count() > MAX_TEXT_LEN {
+ match find_last_line_break(text.clone()) {
+ Ok(index) => {
+ part = &text[..index];
+ params.text = part.to_string();
+ let result = api.send_message(params);
+ match result {
+ Err(err) => {
+ eprintln!("send_message failed.");
+ dbg!(err);
+ }
+ Ok(_res) => {}
+ }
+ text = text[index + 1..].to_string();
+ }
+ Err(_) => {
+ eprintln!("Dude, there's no line break. Deal with it.");
+ }
+ }
+ } else {
+ params.text = text;
+ let result = api.send_message(params);
+ match result {
+ Err(err) => {
+ eprintln!("send_message failed.");
+ dbg!(err);
+ }
+ Ok(_res) => {}
+ }
+ break;
+ }
+ }
+ }
}
fn find_last_line_break(text: String) -> Result<usize, usize> {
- let mut i: usize = MAX_TEXT_LEN as usize;
- loop {
- if i == 0 {
- return Err(i);
- }
- match text.chars().nth(i) {
- Some(c) => {
- if c == '\n' {
- return Ok(i);
- }
- },
- None => {
- eprintln!("nth error");
- }
- }
- i -= 1;
- }
+ let mut i: usize = MAX_TEXT_LEN as usize;
+ loop {
+ if i == 0 {
+ return Err(i);
+ }
+ match text.chars().nth(i) {
+ Some(c) => {
+ if c == '\n' {
+ return Ok(i);
+ }
+ }
+ None => {
+ eprintln!("nth error");
+ }
+ }
+ i -= 1;
+ }
}
fn form_msg(songs: OutgoingTextMsg) -> String {
- let mut message = String::new();
- match songs {
- OutgoingTextMsg::DirEntry(songs) => {
- for song in songs {
- let file_name = song.file_name();
- let filename = file_name.to_str().unwrap();
- let s: Vec<&str> = filename.split(".").collect();
- let name = s.get(0).unwrap();
- let mut command: String = "/".to_string();
- command.push_str(name);
- command.push_str("\n");
- message.push_str(command.as_str());
- }
- },
- OutgoingTextMsg::String(songs) => {
- for song in songs {
- let mut command = String::from("/");
- command.push_str(&song);
- command.push_str("\n");
- message.push_str(command.as_str());
- }
- }
- }
- return message;
+ let mut message = String::new();
+ match songs {
+ OutgoingTextMsg::DirEntry(songs) => {
+ for song in songs {
+ let file_name = song.file_name();
+ let filename = file_name.to_str().unwrap();
+ let s: Vec<&str> = filename.split(".").collect();
+ let name = s.get(0).unwrap();
+ let mut command: String = "/".to_string();
+ command.push_str(name);
+ command.push_str("\n");
+ message.push_str(command.as_str());
+ }
+ }
+ OutgoingTextMsg::String(songs) => {
+ for song in songs {
+ let mut command = String::from("/");
+ command.push_str(&song);
+ command.push_str("\n");
+ message.push_str(command.as_str());
+ }
+ }
+ }
+ return message;
}
fn title_search(args: &FindSongArgs) -> Result<Vec<DirEntry>, SongNotFound> {
- let mut result: Vec<DirEntry> = vec![];
- let mut filename: String;
- let ss = args.i18n.format(&args.search_string).to_lowercase();
- for file in get_songs(&args.songs_path, None) {
- filename = file.file_name().to_str().unwrap().to_string();
- let f: Vec<&str> = filename.split(".").collect();
- let mut name: String = f.get(0).unwrap().to_string();
- name = name.to_lowercase();
- if name.starts_with(&ss) {
- // move found song to the beginning
- let mut one = vec![file];
- one.append(&mut result);
- result = one;
- } else if name.contains(&ss) {
- result.push(file);
- }
- }
- if result.len() > 0 {
- return Ok(result);
- } else {
- return Err(SongNotFound { message: String::from("Didn't find any song.") });
- }
+ let mut result: Vec<DirEntry> = vec![];
+ let mut filename: String;
+ let ss = args.i18n.format(&args.search_string).to_lowercase();
+ for file in get_songs(&args.songs_path, None) {
+ filename = file.file_name().to_str().unwrap().to_string();
+ let f: Vec<&str> = filename.split(".").collect();
+ let mut name: String = f.get(0).unwrap().to_string();
+ name = name.to_lowercase();
+ if name.starts_with(&ss) {
+ // move found song to the beginning
+ let mut one = vec![file];
+ one.append(&mut result);
+ result = one;
+ } else if name.contains(&ss) {
+ result.push(file);
+ }
+ }
+ if result.len() > 0 {
+ return Ok(result);
+ } else {
+ return Err(SongNotFound {
+ message: String::from("Didn't find any song."),
+ });
+ }
}
fn full_text_search(args: &FindSongArgs) -> Result<SearchResult, SongNotFound> {
- let mut ss_in_title: Vec<String> = vec![];
- let mut ss_in_lyrics: Vec<String> = vec![];
- let ss = prepare_for_fulltext_search(&args.search_string);
- let content = fs::read_to_string(&args.search_file).unwrap();
- for line in content.lines() {
- let s_line: Vec<&str> = line.split(':').collect();
- let name = s_line.get(0).unwrap();
- let song_title = s_line.get(1).unwrap();
- let song_lyrics = s_line.get(2).unwrap();
- if song_title.starts_with(&ss) {
- // move found song to the beginning
- let mut temp = vec![name.to_string()];
- temp.append(&mut ss_in_title);
- ss_in_title = temp;
- }
- else if song_title.contains(&ss) {
- ss_in_title.push(name.to_string());
- }
- else if song_lyrics.contains(&ss) {
- ss_in_lyrics.push(name.to_string());
- }
- }
- if ss_in_title.len() == 0 && ss_in_lyrics.len() == 0 {
- return Err(SongNotFound { message: String::from("Didn't find any song.") });
- } else {
- return Ok(SearchResult { ss_in_title, ss_in_lyrics });
- }
+ let mut ss_in_title: Vec<String> = vec![];
+ let mut ss_in_lyrics: Vec<String> = vec![];
+ let ss = prepare_for_fulltext_search(&args.search_string);
+ let content = fs::read_to_string(&args.search_file).unwrap();
+ for line in content.lines() {
+ let s_line: Vec<&str> = line.split(':').collect();
+ let name = s_line.get(0).unwrap();
+ let song_title = s_line.get(1).unwrap();
+ let song_lyrics = s_line.get(2).unwrap();
+ if song_title.starts_with(&ss) {
+ // move found song to the beginning
+ let mut temp = vec![name.to_string()];
+ temp.append(&mut ss_in_title);
+ ss_in_title = temp;
+ } else if song_title.contains(&ss) {
+ ss_in_title.push(name.to_string());
+ } else if song_lyrics.contains(&ss) {
+ ss_in_lyrics.push(name.to_string());
+ }
+ }
+ if ss_in_title.len() == 0 && ss_in_lyrics.len() == 0 {
+ return Err(SongNotFound {
+ message: String::from("Didn't find any song."),
+ });
+ } else {
+ return Ok(SearchResult {
+ ss_in_title,
+ ss_in_lyrics,
+ });
+ }
}
fn prepare_for_fulltext_search(string: &String) -> String {
- let mut res = String::new();
- // let mut is_last_line_break = false;
- for c in string.chars() {
- if c.is_alphabetic() {
- res.push(c);
- // is_last_line_break = false;
- }
- /* if c == '\n' || c == ' ' {
- if !is_last_line_break {
- res.push(' ');
- is_last_line_break = true;
- }
- } */
- }
- res = res.to_lowercase();
- return res;
+ let mut res = String::new();
+ // let mut is_last_line_break = false;
+ for c in string.chars() {
+ if c.is_alphabetic() {
+ res.push(c);
+ // is_last_line_break = false;
+ }
+ /* if c == '\n' || c == ' ' {
+ if !is_last_line_break {
+ res.push(' ');
+ is_last_line_break = true;
+ }
+ } */
+ }
+ res = res.to_lowercase();
+ return res;
}
fn get_songs(songs_path: &String, folder_name: Option<&String>) -> Vec<DirEntry> {
- match folder_name {
- Some(name) => {
- return get_files_recursive(&(songs_path.to_owned() + name));
- },
- None => {
- return get_files_recursive(songs_path);
- }
- }
+ match folder_name {
+ Some(name) => {
+ return get_files_recursive(&(songs_path.to_owned() + name));
+ }
+ None => {
+ return get_files_recursive(songs_path);
+ }
+ }
}
fn get_files_recursive(folder_path: &String) -> Vec<DirEntry> {
- let path = fs::read_dir(folder_path);
- let mut is_dir: bool;
- let mut songs: Vec<DirEntry> = vec![];
- match path {
- Ok(read_dir) => {
- for r in read_dir {
- match r {
- Ok(dir_entry) => {
- is_dir = dir_entry.file_type().unwrap().is_dir();
- if is_dir {
- let path = dir_entry.path().to_str().unwrap().to_string();
- for song in get_files_recursive(&path) {
- songs.push(song);
- }
- } else {
- songs.push(dir_entry);
- }
- },
- Err(err) => {
- eprintln!("Cannot access filepath.");
- dbg!(err);
- }
- }
- }
- },
- Err(_) => {
- eprintln!("Cannot open/read or what ever the path {}.", folder_path);
- }
- }
- songs.sort_by_key(|name| name.file_name().into_string().unwrap().to_lowercase());
- return songs;
+ let path = fs::read_dir(folder_path);
+ let mut is_dir: bool;
+ let mut songs: Vec<DirEntry> = vec![];
+ match path {
+ Ok(read_dir) => {
+ for r in read_dir {
+ match r {
+ Ok(dir_entry) => {
+ is_dir = dir_entry.file_type().unwrap().is_dir();
+ if is_dir {
+ let path = dir_entry.path().to_str().unwrap().to_string();
+ for song in get_files_recursive(&path) {
+ songs.push(song);
+ }
+ } else {
+ songs.push(dir_entry);
+ }
+ }
+ Err(err) => {
+ eprintln!("Cannot access filepath.");
+ dbg!(err);
+ }
+ }
+ }
+ }
+ Err(_) => {
+ eprintln!("Cannot open/read or what ever the path {}.", folder_path);
+ }
+ }
+ songs.sort_by_key(|name| name.file_name().into_string().unwrap().to_lowercase());
+ return songs;
}