Customizable number of packages for search + broken pkg signing

This commit is contained in:
Listum 2023-11-03 03:03:52 +03:00
parent 4a23489c1c
commit ffc5ca7a16
4 changed files with 58 additions and 27 deletions

View File

@ -29,7 +29,7 @@ $ $env:TELOXIDE_TOKEN=<Your token here>
``` ```
4. Создайте симлинк до вашего локального репозитория 4. Создайте симлинк до вашего локального репозитория
```bash ```bash
ln -s /path/to/bot/repo /path/to/repo ln -s /path/to/bot_dir/repo /path/to/repo
``` ```
### Docker ### Docker
@ -63,7 +63,7 @@ docker compose up -d
## Использоание ## Использоание
1. Поиск пакетов в AUR 1. Поиск пакетов в AUR
`/search <название пакета>` `/search <название пакета> <кол-во отображаемых пакетов 1-255>`
2. Добавление пакетов в репозиторий 2. Добавление пакетов в репозиторий
`/upload <название пакета>` `/upload <название пакета>`

View File

@ -1,34 +1,53 @@
use git2::{Error, Repository}; use git2::{Error, Repository};
use std::process::Command; use std::process::Command;
use glob::glob;
use std::fs; use std::fs;
use std::path::Path; use std::path::{Path, PathBuf};
pub fn clone(pkg: String, dir: String) -> Result<Repository, Error> { pub fn clone(pkg: String, dir: String) -> Result<Repository, Error> {
let repo = format!("https://aur.archlinux.org/{}.git", pkg); let repo = format!("https://aur.archlinux.org/{}.git", pkg);
Repository::clone(repo.as_str(), dir.as_str()) Repository::clone(repo.as_str(), dir.as_str())
} }
pub async fn copy(dir: String, local_repo: String) -> Result<(), Box<dyn std::error::Error>> { pub fn copy(dir: String, local_repo: String) -> Result<(), Box<dyn std::error::Error>> {
let entries = fs::read_dir(dir)?; let entries = fs::read_dir(dir)?;
for entry in entries { for entry in entries {
let entry = entry?; let entry = entry?;
let file_path = entry.path(); let file_path = entry.path();
match std::env::var("GPGKEY") {
if file_path.is_file() && file_path.extension().unwrap_or_default() == "zst" { Ok(_) => {
zst(file_path.clone(), local_repo.clone())?;
if file_path.is_file() && file_path.extension().unwrap_or_default() == "sig" {
let file_name = file_path.file_name().unwrap(); let file_name = file_path.file_name().unwrap();
let local_repo = Path::new(local_repo.as_str()).join(file_name); let local_repo = Path::new(local_repo.as_str()).join(file_name);
fs::copy(&file_path, &local_repo)?; fs::copy(&file_path, &local_repo)?;
} }
} }
Err(_) => {
zst(file_path, local_repo.clone())?
}
}
}
Ok(()) Ok(())
} }
pub async fn build() -> Result<(), Box<dyn std::error::Error>> { pub fn build(default_dir: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
match std::env::var("GPGKEY") {
Ok(value) => {
Command::new("makepkg")
.arg("-s")
.arg("--sign")
.arg(format!("--key {}/{}",default_dir.as_os_str().to_str().unwrap() , value))
.arg("--noconfirm")
.output()?;
}
Err(_) => {
Command::new("makepkg") Command::new("makepkg")
.arg("-s") .arg("-s")
.arg("--noconfirm") .arg("--noconfirm")
.output()?; .output()?;
}
}
Ok(()) Ok(())
} }
@ -36,8 +55,8 @@ pub fn delete(dir: String) -> std::io::Result<()> {
fs::remove_dir_all(dir) fs::remove_dir_all(dir)
} }
pub async fn repo_add() -> Result<(), Box<dyn std::error::Error>> { pub fn repo_add() -> Result<(), Box<dyn std::error::Error>> {
let files: Vec<String> = glob("*.pkg.tar.zst") let files: Vec<String> = glob::glob("*.pkg.tar.zst")
.expect("Failed to read glob pattern") .expect("Failed to read glob pattern")
.filter_map(|entry| entry.ok()) .filter_map(|entry| entry.ok())
.filter_map(|path| path.to_str().map(String::from)) .filter_map(|path| path.to_str().map(String::from))
@ -54,3 +73,12 @@ pub async fn repo_add() -> Result<(), Box<dyn std::error::Error>> {
.output()?; .output()?;
Ok(()) Ok(())
} }
fn zst(file_path: PathBuf, local_repo: String) -> Result<(), Box<dyn std::error::Error>> {
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(())
}

View File

@ -1,10 +1,10 @@
use aur_rpc; use aur_rpc;
pub async fn search(pkg: String) -> String { pub async fn search(pkg: String, num: u8) -> String {
let mut packages = aur_rpc::search(pkg).await.unwrap(); let mut packages = aur_rpc::search(pkg).await.unwrap();
packages.sort_by(|a, b| b.num_votes.cmp(&a.num_votes)); packages.sort_by(|a, b| b.num_votes.cmp(&a.num_votes));
let mut result = Vec::new(); let mut result = Vec::new();
for (index, package) in packages.iter().enumerate().take(10) { for (index, package) in packages.iter().enumerate().take(num as usize) {
result.push(format!("{}. {}", index+1, package.name)); result.push(format!("{}. {}", index+1, package.name));
} }
let response = result.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("\n"); let response = result.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("\n");

View File

@ -2,15 +2,18 @@ use teloxide::{prelude::*, utils::command::BotCommands};
use crate::build::{clone, copy, build, delete, repo_add}; use crate::build::{clone, copy, build, delete, repo_add};
use crate::search; use crate::search;
use std::env; use std::env;
pub async fn main(bot: Bot){ pub async fn main(bot: Bot){
Commands::repl(bot, answer).await; Commands::repl(bot, answer).await;
} }
#[derive(BotCommands, Clone)] #[derive(BotCommands, Clone)]
#[command(rename_rule = "lowercase", description = "Commands:")] #[command(rename_rule = "lowercase", description = "Commands:")]
pub(crate) enum Commands{ enum Commands{
#[command(description = "Build package.")]
Upload(String), Upload(String),
Search(String) #[command(description = "Search packages", parse_with = "split")]
Search{ pkg: String, num: u8 }
} }
async fn answer(bot: Bot, msg: Message, cmd: Commands) -> ResponseResult<()> { async fn answer(bot: Bot, msg: Message, cmd: Commands) -> ResponseResult<()> {
match cmd { match cmd {
@ -26,14 +29,14 @@ async fn answer(bot: Bot, msg: Message, cmd: Commands) -> ResponseResult<()> {
bot.send_message(msg.chat.id, clone).await?; bot.send_message(msg.chat.id, clone).await?;
env::set_current_dir(pkg_dir.clone())?; env::set_current_dir(pkg_dir.clone())?;
let build = match build().await { let build = match build(default_dir.clone()) {
Ok(..) => { format!("Builded") }, Ok(..) => { format!("Builded") },
Err(e) => { format!("Build error: {}", e) } Err(e) => { format!("Build error: {}", e) }
}; };
bot.send_message(msg.chat.id, build).await?; bot.send_message(msg.chat.id, build).await?;
env::set_current_dir(default_dir.clone())?; env::set_current_dir(default_dir.clone())?;
let copy = match copy(pkg_dir.clone(), repo_dir.clone()).await { let copy = match copy(pkg_dir.clone(), repo_dir.clone()) {
Ok(..) => { format!("Copied") }, Ok(..) => { format!("Copied") },
Err(e) => { format!("Copy error: {}", e) } Err(e) => { format!("Copy error: {}", e) }
}; };
@ -46,7 +49,7 @@ async fn answer(bot: Bot, msg: Message, cmd: Commands) -> ResponseResult<()> {
bot.send_message(msg.chat.id, delete).await?; bot.send_message(msg.chat.id, delete).await?;
env::set_current_dir(repo_dir)?; env::set_current_dir(repo_dir)?;
let repo_add = match repo_add().await { let repo_add = match repo_add() {
Ok(..) => { format!("Added to repo") }, Ok(..) => { format!("Added to repo") },
Err(e) => { format!("Error adding package to repository: {}", e) } Err(e) => { format!("Error adding package to repository: {}", e) }
}; };
@ -54,8 +57,8 @@ async fn answer(bot: Bot, msg: Message, cmd: Commands) -> ResponseResult<()> {
env::set_current_dir(default_dir)?; env::set_current_dir(default_dir)?;
} }
Commands::Search(pkg) => { Commands::Search{pkg, num} => {
bot.send_message(msg.chat.id, search::search(pkg).await).await?; bot.send_message(msg.chat.id, search::search(pkg, num).await).await?;
} }
} }
Ok(()) Ok(())