From 9c17c780cc496da4be4ce286d89677dd5e36b224 Mon Sep 17 00:00:00 2001 From: Listum Date: Thu, 2 Nov 2023 13:52:08 +0300 Subject: [PATCH] Placement of actions by modules/functions + advanced logging --- Cargo.lock | 10 +++-- src/build.rs | 56 +++++++++++++++++++++++ src/main.rs | 5 ++- src/search.rs | 12 +++++ src/telegram.rs | 117 +++++++++++++++--------------------------------- 5 files changed, 113 insertions(+), 87 deletions(-) create mode 100644 src/build.rs create mode 100644 src/search.rs diff --git a/Cargo.lock b/Cargo.lock index b5e8e1b..5ae162e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,9 +48,7 @@ version = "0.1.0" dependencies = [ "aur-rpc", "git2", - "reqwest", - "serde", - "serde_json", + "glob", "teloxide", "tokio", ] @@ -402,6 +400,12 @@ dependencies = [ "url", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "h2" version = "0.3.21" diff --git a/src/build.rs b/src/build.rs new file mode 100644 index 0000000..032fd4e --- /dev/null +++ b/src/build.rs @@ -0,0 +1,56 @@ +use git2::{Error, Repository}; +use std::process::Command; +use glob::glob; +use std::fs; +use std::path::Path; + +pub fn clone(pkg: String, dir: String) -> Result { + let repo = format!("https://aur.archlinux.org/{}.git", pkg); + Repository::clone(repo.as_str(), dir.as_str()) +} + +pub async fn copy(dir: String, local_repo: String) -> Result<(), Box> { + let entries = fs::read_dir(dir)?; + for entry in entries { + let entry = entry?; + let file_path = entry.path(); + + if file_path.is_file() && file_path.extension().unwrap_or_default() == "zst" { + let file_name = file_path.file_name().unwrap(); + let local_repo = Path::new(local_repo.as_str()).join(file_name); + fs::copy(&file_path, &local_repo)?; + } + } + Ok(()) +} + +pub async fn build() -> Result<(), Box> { + Command::new("makepkg") + .arg("-s") + .arg("--noconfirm") + .output()?; + Ok(()) +} + +pub fn delete(dir: String) -> std::io::Result<()> { + fs::remove_dir_all(dir) +} + +pub async fn repo_add() -> Result<(), Box> { + let files: Vec = glob("*.pkg.tar.zst") + .expect("Failed to read glob pattern") + .filter_map(|entry| entry.ok()) + .filter_map(|path| path.to_str().map(String::from)) + .collect(); + + if files.is_empty() { + println!("No matching files found."); + } + + let vec_of_str_refs: Vec<&str> = files.iter().map(|s| s.as_str()).collect(); + Command::new("repo-add") + .arg("repo.db.tar.gz") + .arg(format!("{}", vec_of_str_refs.join(", "))) + .output()?; + Ok(()) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a5c5d7b..6b2bba8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ mod telegram; -use teloxide; - +mod build; +mod search; #[tokio::main] async fn main() { + telegram::main(teloxide::Bot::from_env()).await; } diff --git a/src/search.rs b/src/search.rs new file mode 100644 index 0000000..7317f57 --- /dev/null +++ b/src/search.rs @@ -0,0 +1,12 @@ +use aur_rpc; + pub async fn search(pkg: String) -> String { + let mut packages = aur_rpc::search(pkg).await.unwrap(); + packages.sort_by(|a, b| b.num_votes.cmp(&a.num_votes)); + let mut result = Vec::new(); + + for (index, package) in packages.iter().enumerate().take(10) { + result.push(format!("{}. {}", index+1, package.name)); + } + let response = result.iter().map(|x| x.to_string()).collect::>().join("\n"); + return response; +} \ No newline at end of file diff --git a/src/telegram.rs b/src/telegram.rs index 334ce09..3b3082a 100644 --- a/src/telegram.rs +++ b/src/telegram.rs @@ -1,108 +1,61 @@ use teloxide::{prelude::*, utils::command::BotCommands}; -use aur_rpc; -use git2::Repository; -use std::process::Command; +use crate::build::{clone, copy, build, delete, repo_add}; +use crate::search; use std::env; -use glob::glob; -use std::fs; -use std::path::Path; - - - pub async fn main(bot: Bot){ Commands::repl(bot, answer).await; } #[derive(BotCommands, Clone)] #[command(rename_rule = "lowercase", description = "Commands:")] -enum Commands{ +pub(crate) enum Commands{ Upload(String), - Clean, Search(String) } async fn answer(bot: Bot, msg: Message, cmd: Commands) -> ResponseResult<()> { match cmd { Commands::Upload(pkg) => { - let repo = format!("https://aur.archlinux.org/{}.git", pkg); - let dir = format!("pkgs/{}", pkg); + let default_dir = env::current_dir()?; + let pkg_dir = format!("pkgs/{}", pkg); + let repo_dir = format!("repo/"); - match Repository::clone(repo.as_str(), dir.as_str()) { - Ok(_) => bot.send_message(msg.chat.id, format!("Succsess {}", pkg)).await?, - Err(e) => bot.send_message(msg.chat.id, format!("Error: {}", e)).await?, + let clone = match clone(pkg, pkg_dir.clone()) { + Ok(..) => { format!("Cloned") }, + Err(e) => { format!("Clone error: {}", e) } }; + bot.send_message(msg.chat.id, clone).await?; - let default_dir = env::current_dir().expect("Failed to get default directory"); - env::set_current_dir(dir.clone())?; - let compile = Command::new("makepkg") - .arg("-s") - .arg("--noconfirm") - .output()?; - - if compile.status.success() { - bot.send_message(msg.chat.id, format!("Build succseed")).await?; - } else { - bot.send_message(msg.chat.id, format!("Build failed: {:?}", compile.status.to_string())).await?; - } + env::set_current_dir(pkg_dir.clone())?; + let build = match build().await { + Ok(..) => { format!("Builded") }, + Err(e) => { format!("Build error: {}", e) } + }; + bot.send_message(msg.chat.id, build).await?; env::set_current_dir(default_dir.clone())?; - let local_repo = "repo/"; - let entries = fs::read_dir(dir.clone())?; + let copy = match copy(pkg_dir.clone(), repo_dir.clone()).await { + Ok(..) => { format!("Copied") }, + Err(e) => { format!("Copy error: {}", e) } + }; + bot.send_message(msg.chat.id, copy).await?; - for entry in entries { - let entry = entry?; - let file_path = entry.path(); + let delete = match delete(pkg_dir) { + Ok(..) => { format!("Sources deleted")}, + Err(e) => { format!("Sources deletion error: {}", e) } + }; + bot.send_message(msg.chat.id, delete).await?; - if file_path.is_file() && file_path.extension().unwrap_or_default() == "zst" { - let file_name = file_path.file_name().unwrap(); - let local_repo = Path::new(local_repo).join(file_name); - fs::copy(&file_path, &local_repo).expect("Failed to copy"); - bot.send_message(msg.chat.id, format!("Package copied to local repo")).await?; - } - } - - match fs::remove_dir_all(dir) { - Ok(_) => println!("Sources successfully deleted."), - Err(err) => eprintln!("Error deleting sources: {}", err), - } - - env::set_current_dir("repo/")?; - let files: Vec = glob("*.pkg.tar.zst") - .expect("Failed to read glob pattern") - .filter_map(|entry| entry.ok()) - .filter_map(|path| path.to_str().map(String::from)) - .collect(); - - if files.is_empty() { - println!("No matching files found."); - } - - let vec_of_str_refs: Vec<&str> = files.iter().map(|s| s.as_str()).collect(); - let add = Command::new("repo-add") - .arg("repo.db.tar.gz") - .arg(format!("{}", vec_of_str_refs.join(", "))) - .output()?; - eprintln!("repo-add output: {:?}", String::from_utf8_lossy(&add.stderr)); - - if add.status.success() { - bot.send_message(msg.chat.id, format!("Added to repo successfuly")).await?; - } else { - bot.send_message(msg.chat.id, format!("Failed to add to repo: {:?}", compile.status.code())).await?; - } + env::set_current_dir(repo_dir)?; + let repo_add = match repo_add().await { + Ok(..) => { format!("Added to repo") }, + Err(e) => { format!("Error adding package to repository: {}", e) } + }; + bot.send_message(msg.chat.id, repo_add).await?; env::set_current_dir(default_dir)?; - } - Commands::Clean => { - bot.send_message(msg.chat.id, format!("Done")).await?; - } - Commands::Search(name) => { - let mut packages = aur_rpc::search(format!("{}", name)).await.unwrap(); - packages.sort_by(|a, b| b.num_votes.cmp(&a.num_votes)); - let mut result = Vec::new(); - for (index, package) in packages.iter().enumerate().take(10) { - result.push(format!("{}. {}", index+1, package.name)); - } - - bot.send_message(msg.chat.id, format!("{}", result.iter().map(|x| x.to_string()).collect::>().join("\n"))).await?; + } + Commands::Search(pkg) => { + bot.send_message(msg.chat.id, search::search(pkg).await).await?; } } Ok(())