this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

treewide: fmt

isabel 576c2b79 298d4a9a

+297 -217
+1 -1
src/commands/bot/bot.rs
··· 1 1 use crate::types::Context; 2 2 use color_eyre::eyre::Result; 3 3 use poise::{ 4 - serenity_prelude::{CreateEmbed, CreateEmbedAuthor}, 5 4 CreateReply, 5 + serenity_prelude::{CreateEmbed, CreateEmbedAuthor}, 6 6 }; 7 7 8 8 /// Displays information about the bot
+24 -24
src/commands/fun/height.rs
··· 5 5 6 6 #[poise::command(slash_command)] 7 7 pub async fn height( 8 - ctx: Context<'_>, 9 - #[description = "Selected user"] user: Option<User>, 8 + ctx: Context<'_>, 9 + #[description = "Selected user"] user: Option<User>, 10 10 ) -> Result<()> { 11 - let user = user.as_ref().unwrap_or_else(|| ctx.author()); 11 + let user = user.as_ref().unwrap_or_else(|| ctx.author()); 12 12 13 - let (feet, inches, cm) = match user.id.get() { 14 - 463566237918691338 => (8, 5, 256), 15 - 474274492810788864 => (4, 1, 124), 16 - _ => { 17 - let total_inches = rand::rng().random_range(49..=101); 18 - let feet = total_inches / 12; 19 - let inches = total_inches % 12; 20 - let cm = (total_inches as f32 * 2.54) as u32; 21 - (feet, inches, cm) 22 - } 23 - }; 13 + let (feet, inches, cm) = match user.id.get() { 14 + 463566237918691338 => (8, 5, 256), 15 + 474274492810788864 => (4, 1, 124), 16 + _ => { 17 + let total_inches = rand::rng().random_range(49..=101); 18 + let feet = total_inches / 12; 19 + let inches = total_inches % 12; 20 + let cm = (total_inches as f32 * 2.54) as u32; 21 + (feet, inches, cm) 22 + } 23 + }; 24 24 25 - ctx.say(format!( 26 - "🔮 **{}** is **{}'{}\"** (**{} cm**) tall!", 27 - user.display_name(), 28 - feet, 29 - inches, 30 - cm 31 - )) 32 - .await?; 25 + ctx.say(format!( 26 + "🔮 **{}** is **{}'{}\"** (**{} cm**) tall!", 27 + user.display_name(), 28 + feet, 29 + inches, 30 + cm 31 + )) 32 + .await?; 33 33 34 - Ok(()) 35 - } 34 + Ok(()) 35 + }
+1 -1
src/commands/fun/kittysay.rs
··· 1 1 use color_eyre::eyre::Result; 2 - use kittysay::{print, FormatOptions}; 2 + use kittysay::{FormatOptions, print}; 3 3 4 4 use crate::types::Context; 5 5
+1 -1
src/commands/fun/pet.rs
··· 1 1 use crate::types::Context; 2 2 use color_eyre::eyre::Result; 3 - use poise::{serenity_prelude::all::User, CreateReply}; 3 + use poise::{CreateReply, serenity_prelude::all::User}; 4 4 use serenity::all::CreateAttachment; 5 5 6 6 #[derive(serde::Serialize, serde::Deserialize)]
+1 -1
src/commands/misc/crates.rs
··· 1 1 use color_eyre::eyre::Result; 2 - use poise::{serenity_prelude::CreateEmbed, CreateReply}; 2 + use poise::{CreateReply, serenity_prelude::CreateEmbed}; 3 3 use reqwest::StatusCode; 4 4 use serde::Deserialize; 5 5 use serenity::all::{CreateEmbedAuthor, CreateEmbedFooter, Timestamp};
+14 -14
src/commands/moderation/ban.rs
··· 1 1 use crate::Result; 2 - use poise::serenity_prelude::all::User; 3 2 use poise::serenity_prelude::RoleId; 3 + use poise::serenity_prelude::all::User; 4 4 5 5 use crate::types::Context; 6 6 ··· 23 23 // Only check perms if user is in guild 24 24 if let Ok(user_member) = guild.member(ctx, &user).await { 25 25 let get_role_pos = |roles: &[RoleId]| { 26 - roles.iter() 27 - .filter_map(|role| guild.roles.get(role)) 28 - .max_by_key(|role| role.position) 26 + roles 27 + .iter() 28 + .filter_map(|role| guild.roles.get(role)) 29 + .max_by_key(|role| role.position) 29 30 }; 30 31 31 32 let user_highest_role = get_role_pos(&user_member.roles); ··· 44 45 } 45 46 46 47 if !guild 47 - .user_permissions_in( 48 - &ctx.guild_channel().await.unwrap(), 49 - &bot_member, 50 - ) 48 + .user_permissions_in(&ctx.guild_channel().await.unwrap(), &bot_member) 51 49 .ban_members() 52 50 { 53 51 ctx.say("Bot missing permission: ``Ban Members``").await?; 54 52 return Ok(()); 55 53 } 56 54 57 - guild.ban_with_reason( 58 - ctx, 59 - &user, 60 - delete_messages_day_count.unwrap_or(0), 61 - &reason.unwrap_or("No reason provided.".to_string()) 62 - ).await?; 55 + guild 56 + .ban_with_reason( 57 + ctx, 58 + &user, 59 + delete_messages_day_count.unwrap_or(0), 60 + &reason.unwrap_or("No reason provided.".to_string()), 61 + ) 62 + .await?; 63 63 64 64 ctx.say(format!("Banned user {user}.")).await?; 65 65
+1 -1
src/commands/moderation/purge.rs
··· 1 - use crate::types::Context; 2 1 use crate::Result; 2 + use crate::types::Context; 3 3 use poise::serenity_prelude::GetMessages; 4 4 5 5 #[poise::command(slash_command, guild_only, required_permissions = "BAN_MEMBERS")]
+59 -60
src/commands/nix/nix.rs
··· 5 5 #[allow(dead_code)] 6 6 const MEMES: &[&str] = &[ 7 7 // memes from github:gytis-ivaskevicius/high-quality-nix-content 8 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/aarch64-joke.jpg", 9 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/averagenixfan.png", 10 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/before-and-after-nix.png", 11 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/config-not-entierly-declarative.png", 12 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/dark-secret-nixpkgs.png", 13 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/debian-and-arch-bad.png", 14 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/do-not-get-mad.png", 15 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/eelco-nixpill.png", 16 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/eelco-prism.mp4", 17 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/electron.jpg", 18 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/flake-magic.png", 19 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/fleyks.png", 20 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/hard-to-swallow-pills.png", 21 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/heaviest-objects-in-the-universe.png", 22 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/hermetic-tooling.jpg", 23 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/homer-nix-bush.gif", 24 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/i-hate-docker.webp", 25 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/just-try-the-goddam-nix.webp", 26 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/legend-of-nixos.png", 27 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/mobile-nixos.png", 28 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/my-nixos-setup.png", 29 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nagatoro-nix-pervert.png", 30 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-20min-adventure.png", 31 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-expression-language-armor.jpeg", 32 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-god.jpg", 33 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-learning-curve.png", 34 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-path-supports-urls.jpg", 35 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-programming-socks.png", 36 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-vs-fhs.png", 37 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-vs-gentoo.png", 38 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixenv-vs-nixshell.png", 39 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-at-home.jpg", 40 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-deploy.png", 41 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-dominos.png", 42 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-fixes-this.jpg", 43 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-shilling.png", 44 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/no-going-back.png", 45 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/org-vs-com.png", 46 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/pinnacle-of-system-configuration.png", 47 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/pr-open.jpg", 48 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/quick-install-nixos.webp", 49 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/random-repos.png", 50 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/stay-on-freenode.jpg", 51 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/stop-using-nixos.webp", 52 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/superiority-complex.png", 53 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/techy-kid.png", 54 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/thank-you-for-changing-my-life.png", 55 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/the-declarative-trinity.webp", 56 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/they-dont-know-im-reproducible.png", 57 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/virgin-arch-vs-chad-nixos.png", 58 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/virtualbox-starts-compiling.jpg", 59 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/whats-the-difference.webp", 60 - "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/who-would-win.png", 61 - 62 - // memes from github:isabelroses/memes 63 - "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nix-fixes-this/nix-fixes-this.png", 64 - "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nix-fixes-this/nix-fixes-crowdstrike.png", 65 - "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nixgf/latest.png", 66 - "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nix-users-today.png", 67 - "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nix-is-a-slipper-slope.png", 8 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/aarch64-joke.jpg", 9 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/averagenixfan.png", 10 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/before-and-after-nix.png", 11 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/config-not-entierly-declarative.png", 12 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/dark-secret-nixpkgs.png", 13 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/debian-and-arch-bad.png", 14 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/do-not-get-mad.png", 15 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/eelco-nixpill.png", 16 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/eelco-prism.mp4", 17 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/electron.jpg", 18 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/flake-magic.png", 19 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/fleyks.png", 20 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/hard-to-swallow-pills.png", 21 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/heaviest-objects-in-the-universe.png", 22 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/hermetic-tooling.jpg", 23 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/homer-nix-bush.gif", 24 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/i-hate-docker.webp", 25 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/just-try-the-goddam-nix.webp", 26 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/legend-of-nixos.png", 27 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/mobile-nixos.png", 28 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/my-nixos-setup.png", 29 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nagatoro-nix-pervert.png", 30 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-20min-adventure.png", 31 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-expression-language-armor.jpeg", 32 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-god.jpg", 33 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-learning-curve.png", 34 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-path-supports-urls.jpg", 35 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-programming-socks.png", 36 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-vs-fhs.png", 37 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nix-vs-gentoo.png", 38 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixenv-vs-nixshell.png", 39 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-at-home.jpg", 40 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-deploy.png", 41 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-dominos.png", 42 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-fixes-this.jpg", 43 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/nixos-shilling.png", 44 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/no-going-back.png", 45 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/org-vs-com.png", 46 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/pinnacle-of-system-configuration.png", 47 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/pr-open.jpg", 48 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/quick-install-nixos.webp", 49 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/random-repos.png", 50 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/stay-on-freenode.jpg", 51 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/stop-using-nixos.webp", 52 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/superiority-complex.png", 53 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/techy-kid.png", 54 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/thank-you-for-changing-my-life.png", 55 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/the-declarative-trinity.webp", 56 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/they-dont-know-im-reproducible.png", 57 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/virgin-arch-vs-chad-nixos.png", 58 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/virtualbox-starts-compiling.jpg", 59 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/whats-the-difference.webp", 60 + "https://raw.githubusercontent.com/gytis-ivaskevicius/high-quality-nix-content/master/memes/who-would-win.png", 61 + // memes from github:isabelroses/memes 62 + "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nix-fixes-this/nix-fixes-this.png", 63 + "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nix-fixes-this/nix-fixes-crowdstrike.png", 64 + "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nixgf/latest.png", 65 + "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nix-users-today.png", 66 + "https://media.githubusercontent.com/media/isabelroses/memes/refs/heads/main/nix-is-a-slipper-slope.png", 68 67 ]; 69 68 70 69 /// nix fixes this
+49 -38
src/commands/nix/nixpkg.rs
··· 1 + use crate::types::Context; 2 + use color_eyre::eyre::{Result, eyre}; 1 3 use once_cell::sync::Lazy; 4 + use poise::{CreateReply, serenity_prelude::CreateEmbed}; 2 5 use rusqlite::{Connection, params}; 3 6 use std::sync::Mutex; 4 - use crate::types::Context; 5 - use color_eyre::eyre::{Result, eyre}; 6 - use poise::{serenity_prelude::CreateEmbed, CreateReply}; 7 7 8 8 static DB: Lazy<Mutex<Connection>> = Lazy::new(|| { 9 - let db_path = std::env::var("NIXPKGS_DB") 10 - .unwrap_or_else(|_| "nixpkgs.db".to_string()); 9 + let db_path = std::env::var("NIXPKGS_DB").unwrap_or_else(|_| "nixpkgs.db".to_string()); 11 10 Mutex::new(Connection::open(db_path).expect("Failed to open database")) 12 11 }); 13 12 ··· 41 40 github: String, 42 41 } 43 42 44 - /// Track nixpkgs PRs 43 + /// Get information about a Nix package 45 44 #[poise::command( 46 45 slash_command, 47 46 install_context = "Guild|User", ··· 52 51 #[description = "package name"] package: String, 53 52 ) -> Result<()> { 54 53 ctx.defer().await?; 55 - 54 + 56 55 let (mut pkg, maintainers) = { 57 56 let db = DB.lock().unwrap(); 58 - 57 + 59 58 let mut stmt = db.prepare( 60 59 "SELECT pname, version, description, homepage, license_spdx_id, 61 60 position, broken, insecure, unfree 62 - FROM packages WHERE package_name = ?1" 61 + FROM packages WHERE package_name = ?1", 63 62 )?; 64 - 65 - let pkg = stmt.query_row(params![&package], |row| { 66 - Ok(Package { 67 - pname: row.get(0)?, 68 - version: row.get(1)?, 69 - meta: PackageMeta { 70 - description: row.get(2)?, 71 - homepage: row.get(3)?, 72 - license: License { 73 - spdx_id: row.get::<_, Option<String>>(4)?.unwrap_or_else(|| "Unknown".to_string()), 63 + 64 + let pkg = stmt 65 + .query_row(params![&package], |row| { 66 + Ok(Package { 67 + pname: row.get(0)?, 68 + version: row.get(1)?, 69 + meta: PackageMeta { 70 + description: row.get(2)?, 71 + homepage: row.get(3)?, 72 + license: License { 73 + spdx_id: row 74 + .get::<_, Option<String>>(4)? 75 + .unwrap_or_else(|| "Unknown".to_string()), 76 + }, 77 + position: row 78 + .get::<_, Option<String>>(5)? 79 + .unwrap_or_else(|| "unknown".to_string()), 80 + broken: row.get::<_, i32>(6)? != 0, 81 + insecure: row.get::<_, i32>(7)? != 0, 82 + unfree: row.get::<_, i32>(8)? != 0, 83 + maintainers: Vec::new(), 74 84 }, 75 - position: row.get::<_, Option<String>>(5)?.unwrap_or_else(|| "unknown".to_string()), 76 - broken: row.get::<_, i32>(6)? != 0, 77 - insecure: row.get::<_, i32>(7)? != 0, 78 - unfree: row.get::<_, i32>(8)? != 0, 79 - maintainers: Vec::new(), 80 - }, 85 + }) 81 86 }) 82 - }).map_err(|_| eyre!("Package not found"))?; 83 - 84 - let mut maint_stmt = db.prepare( 85 - "SELECT name, github FROM maintainers WHERE package_name = ?1" 86 - )?; 87 - 87 + .map_err(|_| eyre!("Package not found"))?; 88 + 89 + let mut maint_stmt = 90 + db.prepare("SELECT name, github FROM maintainers WHERE package_name = ?1")?; 91 + 88 92 let maintainers: Vec<Maintainers> = maint_stmt 89 93 .query_map(params![&package], |row| { 90 94 Ok(Maintainers { 91 - name: row.get::<_, Option<String>>(0)?.unwrap_or_else(|| "Unknown".to_string()), 92 - github: row.get::<_, Option<String>>(1)?.unwrap_or_else(|| "".to_string()), 95 + name: row 96 + .get::<_, Option<String>>(0)? 97 + .unwrap_or_else(|| "Unknown".to_string()), 98 + github: row 99 + .get::<_, Option<String>>(1)? 100 + .unwrap_or_else(|| "".to_string()), 93 101 }) 94 102 })? 95 103 .filter_map(Result::ok) 96 104 .collect(); 97 - 105 + 98 106 (pkg, maintainers) 99 107 }; 100 - 108 + 101 109 pkg.meta.maintainers = maintainers; 102 - 110 + 103 111 let file = pkg.meta.position.split(':').next().unwrap_or("unknown"); 104 112 105 113 let embed = CreateEmbed::new() 106 114 .title(format!("{} {}", pkg.pname, pkg.version)) 107 - .url(format!("https://github.com/nixos/nixpkgs/blob/master/{file}")) 115 + .url(format!( 116 + "https://github.com/nixos/nixpkgs/blob/master/{file}" 117 + )) 108 118 .description(pkg.meta.description) 109 119 .field( 110 120 "Homepage", ··· 120 130 if pkg.meta.maintainers.is_empty() { 121 131 "None".to_string() 122 132 } else { 123 - pkg.meta.maintainers 133 + pkg.meta 134 + .maintainers 124 135 .iter() 125 136 .filter(|m| !m.github.is_empty()) 126 137 .map(|m| format!("[{}](https://github.com/{})", m.name, m.github))
+1 -1
src/commands/nix/nixpkgs.rs
··· 1 1 use color_eyre::eyre::Result; 2 2 use nixpkgs_track_lib::{branch_contains_commit, fetch_nixpkgs_pull_request}; 3 - use poise::{serenity_prelude::CreateEmbed, CreateReply}; 3 + use poise::{CreateReply, serenity_prelude::CreateEmbed}; 4 4 use std::fmt::Write as _; 5 5 6 6 use crate::types::Context;
+1 -1
src/commands/user/color_me.rs
··· 1 1 use crate::types::Context; 2 2 use color_eyre::eyre::Result; 3 - use poise::serenity_prelude::{Colour, EditRole}; 4 3 use poise::CreateReply; 4 + use poise::serenity_prelude::{Colour, EditRole}; 5 5 6 6 /// Change your display color or remove your color role. 7 7 #[poise::command(slash_command)]
+1 -1
src/commands/user/whois.rs
··· 1 1 use crate::types::Context; 2 2 use color_eyre::eyre::Result; 3 3 use poise::{ 4 - serenity_prelude::{CreateEmbed, User}, 5 4 CreateReply, 5 + serenity_prelude::{CreateEmbed, User}, 6 6 }; 7 7 8 8 /// Displays your or another user's info
+1 -1
src/event_handler/code_expantion.rs
··· 1 1 // the logic here is pretty much ripped from https://github.com/uncenter/discord-forum-bot/blob/main/src/modules/expandGitHubLinks.ts 2 2 // with some modifications so I can make it work on diffrent git hosts 3 3 4 - use color_eyre::eyre::{eyre, Result}; 4 + use color_eyre::eyre::{Result, eyre}; 5 5 use poise::serenity_prelude::{Context, FullEvent}; 6 6 use regex::Regex; 7 7 use reqwest::Client;
+1 -1
src/event_handler/kitten.rs
··· 1 - use color_eyre::eyre::{eyre, Result}; 1 + use color_eyre::eyre::{Result, eyre}; 2 2 use poise::serenity_prelude::{Context, FullEvent}; 3 3 use serenity::all::{ChannelId, Member, RoleId, UserId}; 4 4
+141 -71
src/main.rs
··· 4 4 mod types; 5 5 6 6 use dotenv::dotenv; 7 - use std::{env, sync::Arc, path::Path}; 7 + use std::{env, path::Path, sync::Arc}; 8 8 9 9 use color_eyre::eyre::Result; 10 10 use poise::serenity_prelude::{ActivityData, ClientBuilder, GatewayIntents}; 11 - use sha2::{Sha256, Digest}; 11 + use sha2::{Digest, Sha256}; 12 12 13 13 #[derive(Debug)] 14 14 struct NixpkgsRelease { ··· 19 19 async fn get_latest_nixpkgs_release() -> Result<NixpkgsRelease> { 20 20 let base_url = env::var("NIXPKGS_CHANNEL") 21 21 .unwrap_or_else(|_| "https://channels.nixos.org/nixpkgs-unstable".to_string()); 22 - 22 + 23 23 let response = reqwest::get(&base_url).await?; 24 24 let html = response.text().await?; 25 - 26 - let url_regex = regex::Regex::new(r#"<a href='([^']+/packages\.json\.br)'>packages\.json\.br</a>"#)?; 27 - let hash_regex = regex::Regex::new(r#"packages\.json\.br</a></td><td align='right'>\d+</td><td><tt>([a-f0-9]{64})</tt>"#)?; 28 - 29 - let url = url_regex.captures(&html) 25 + 26 + let url_regex = 27 + regex::Regex::new(r#"<a href='([^']+/packages\.json\.br)'>packages\.json\.br</a>"#)?; 28 + let hash_regex = regex::Regex::new( 29 + r#"packages\.json\.br</a></td><td align='right'>\d+</td><td><tt>([a-f0-9]{64})</tt>"#, 30 + )?; 31 + 32 + let url = url_regex 33 + .captures(&html) 30 34 .and_then(|cap| cap.get(1)) 31 35 .map(|m| { 32 36 let path = m.as_str(); ··· 39 43 } 40 44 }) 41 45 .ok_or_else(|| color_eyre::eyre::eyre!("Could not find packages.json.br URL"))?; 42 - 43 - let hash = hash_regex.captures(&html) 46 + 47 + let hash = hash_regex 48 + .captures(&html) 44 49 .and_then(|cap| cap.get(1)) 45 50 .map(|m| m.as_str().to_string()) 46 51 .ok_or_else(|| color_eyre::eyre::eyre!("Could not find packages.json.br hash"))?; 47 - 52 + 48 53 Ok(NixpkgsRelease { url, hash }) 49 54 } 50 55 ··· 61 66 62 67 async fn ensure_nixpkgs_database() -> Result<()> { 63 68 let db_path = env::var("NIXPKGS_DB").unwrap_or_else(|_| "nixpkgs.db".to_string()); 64 - 69 + 65 70 println!("Checking for nixpkgs updates..."); 66 71 let release = get_latest_nixpkgs_release().await?; 67 72 let stored_hash = get_stored_hash(); 68 - 73 + 69 74 if Path::new(&db_path).exists() && stored_hash.as_deref() == Some(&release.hash) { 70 75 println!("nixpkgs database is up to date"); 71 76 return Ok(()); 72 77 } 73 - 78 + 74 79 if Path::new(&db_path).exists() { 75 80 println!("New nixpkgs release detected, updating database..."); 76 81 std::fs::remove_file(&db_path)?; 77 82 } else { 78 83 println!("nixpkgs database not found, building..."); 79 84 } 80 - 85 + 81 86 println!("Downloading from {}...", release.url); 82 87 let response = reqwest::get(&release.url).await?; 83 88 let compressed = response.bytes().await?; ··· 101 106 102 107 println!("Parsing JSON..."); 103 108 let json_data: serde_json::Value = serde_json::from_slice(&decompressed)?; 104 - 105 - let packages = json_data["packages"].as_object().ok_or_else(|| { 106 - color_eyre::eyre::eyre!("Invalid packages.json format") 107 - })?; 108 - 109 + 110 + let packages = json_data["packages"] 111 + .as_object() 112 + .ok_or_else(|| color_eyre::eyre::eyre!("Invalid packages.json format"))?; 113 + 109 114 println!("Creating database with {} packages...", packages.len()); 110 - 115 + 111 116 let mut conn = rusqlite::Connection::open(&db_path)?; 112 - 117 + 113 118 conn.execute( 114 119 "CREATE TABLE packages ( 115 120 package_name TEXT PRIMARY KEY, ··· 135 140 )", 136 141 [], 137 142 )?; 138 - 143 + 139 144 conn.execute( 140 145 "CREATE TABLE maintainers ( 141 146 id INTEGER PRIMARY KEY AUTOINCREMENT, ··· 149 154 )", 150 155 [], 151 156 )?; 152 - 153 - conn.execute("CREATE INDEX idx_package_name ON packages(package_name)", [])?; 157 + 158 + conn.execute( 159 + "CREATE INDEX idx_package_name ON packages(package_name)", 160 + [], 161 + )?; 154 162 conn.execute("CREATE INDEX idx_pname ON packages(pname)", [])?; 155 - conn.execute("CREATE INDEX idx_maintainers_package ON maintainers(package_name)", [])?; 156 - 163 + conn.execute( 164 + "CREATE INDEX idx_maintainers_package ON maintainers(package_name)", 165 + [], 166 + )?; 167 + 157 168 let total = packages.len(); 158 169 let mut count = 0; 159 170 let batch_size = 1000; 160 - 171 + 161 172 let mut package_batch = Vec::new(); 162 173 let mut maintainer_batch = Vec::new(); 163 - 174 + 164 175 for (pkg_name, pkg_data) in packages { 165 176 let meta = &pkg_data["meta"]; 166 177 let license_data = &meta["license"]; 167 - 178 + 168 179 let license_spdx = match license_data { 169 - serde_json::Value::Object(obj) => obj.get("spdxId").and_then(|v| v.as_str()).map(|s| s.to_string()), 180 + serde_json::Value::Object(obj) => obj 181 + .get("spdxId") 182 + .and_then(|v| v.as_str()) 183 + .map(|s| s.to_string()), 170 184 serde_json::Value::Array(arr) => { 171 - let ids: Vec<&str> = arr.iter() 185 + let ids: Vec<&str> = arr 186 + .iter() 172 187 .filter_map(|v| v.get("spdxId")) 173 188 .filter_map(|v| v.as_str()) 174 189 .collect(); 175 - if ids.is_empty() { None } else { Some(ids.join(", ")) } 190 + if ids.is_empty() { 191 + None 192 + } else { 193 + Some(ids.join(", ")) 194 + } 176 195 } 177 196 serde_json::Value::String(s) => Some(s.clone()), 178 197 _ => None, 179 198 }; 180 - 181 - let homepage = meta.get("homepage") 182 - .and_then(|h| match h { 183 - serde_json::Value::String(s) => Some(s.as_str()), 184 - serde_json::Value::Array(arr) => arr.first().and_then(|v| v.as_str()), 185 - _ => None, 186 - }); 187 - 199 + 200 + let homepage = meta.get("homepage").and_then(|h| match h { 201 + serde_json::Value::String(s) => Some(s.as_str()), 202 + serde_json::Value::Array(arr) => arr.first().and_then(|v| v.as_str()), 203 + _ => None, 204 + }); 205 + 188 206 package_batch.push(( 189 207 pkg_name.clone(), 190 - pkg_data.get("pname").and_then(|v| v.as_str()).map(|s| s.to_string()), 191 - pkg_data.get("version").and_then(|v| v.as_str()).map(|s| s.to_string()), 192 - pkg_data.get("name").and_then(|v| v.as_str()).map(|s| s.to_string()), 193 - pkg_data.get("system").and_then(|v| v.as_str()).map(|s| s.to_string()), 194 - pkg_data.get("outputName").and_then(|v| v.as_str()).map(|s| s.to_string()), 195 - meta.get("available").and_then(|v| v.as_bool()).unwrap_or(false) as i32, 196 - meta.get("broken").and_then(|v| v.as_bool()).unwrap_or(false) as i32, 197 - meta.get("description").and_then(|v| v.as_str()).map(|s| s.to_string()), 208 + pkg_data 209 + .get("pname") 210 + .and_then(|v| v.as_str()) 211 + .map(|s| s.to_string()), 212 + pkg_data 213 + .get("version") 214 + .and_then(|v| v.as_str()) 215 + .map(|s| s.to_string()), 216 + pkg_data 217 + .get("name") 218 + .and_then(|v| v.as_str()) 219 + .map(|s| s.to_string()), 220 + pkg_data 221 + .get("system") 222 + .and_then(|v| v.as_str()) 223 + .map(|s| s.to_string()), 224 + pkg_data 225 + .get("outputName") 226 + .and_then(|v| v.as_str()) 227 + .map(|s| s.to_string()), 228 + meta.get("available") 229 + .and_then(|v| v.as_bool()) 230 + .unwrap_or(false) as i32, 231 + meta.get("broken") 232 + .and_then(|v| v.as_bool()) 233 + .unwrap_or(false) as i32, 234 + meta.get("description") 235 + .and_then(|v| v.as_str()) 236 + .map(|s| s.to_string()), 198 237 homepage.map(|s| s.to_string()), 199 - meta.get("insecure").and_then(|v| v.as_bool()).unwrap_or(false) as i32, 200 - meta.get("unfree").and_then(|v| v.as_bool()).unwrap_or(false) as i32, 201 - meta.get("unsupported").and_then(|v| v.as_bool()).unwrap_or(false) as i32, 202 - meta.get("position").and_then(|v| v.as_str()).map(|s| s.to_string()), 203 - meta.get("longDescription").and_then(|v| v.as_str()).map(|s| s.to_string()), 204 - meta.get("mainProgram").and_then(|v| v.as_str()).map(|s| s.to_string()), 238 + meta.get("insecure") 239 + .and_then(|v| v.as_bool()) 240 + .unwrap_or(false) as i32, 241 + meta.get("unfree") 242 + .and_then(|v| v.as_bool()) 243 + .unwrap_or(false) as i32, 244 + meta.get("unsupported") 245 + .and_then(|v| v.as_bool()) 246 + .unwrap_or(false) as i32, 247 + meta.get("position") 248 + .and_then(|v| v.as_str()) 249 + .map(|s| s.to_string()), 250 + meta.get("longDescription") 251 + .and_then(|v| v.as_str()) 252 + .map(|s| s.to_string()), 253 + meta.get("mainProgram") 254 + .and_then(|v| v.as_str()) 255 + .map(|s| s.to_string()), 205 256 license_spdx, 206 257 None::<String>, 207 258 0, 208 259 None::<String>, 209 260 )); 210 - 261 + 211 262 if let Some(maintainers) = meta.get("maintainers").and_then(|v| v.as_array()) { 212 263 for m in maintainers { 213 264 if let Some(obj) = m.as_object() { 214 265 maintainer_batch.push(( 215 266 pkg_name.clone(), 216 - obj.get("name").and_then(|v| v.as_str()).map(|s| s.to_string()), 217 - obj.get("email").and_then(|v| v.as_str()).map(|s| s.to_string()), 218 - obj.get("github").and_then(|v| v.as_str()).map(|s| s.to_string()), 267 + obj.get("name") 268 + .and_then(|v| v.as_str()) 269 + .map(|s| s.to_string()), 270 + obj.get("email") 271 + .and_then(|v| v.as_str()) 272 + .map(|s| s.to_string()), 273 + obj.get("github") 274 + .and_then(|v| v.as_str()) 275 + .map(|s| s.to_string()), 219 276 obj.get("githubId").and_then(|v| v.as_i64()), 220 - obj.get("matrix").and_then(|v| v.as_str()).map(|s| s.to_string()), 277 + obj.get("matrix") 278 + .and_then(|v| v.as_str()) 279 + .map(|s| s.to_string()), 221 280 )); 222 281 } 223 282 } 224 283 } 225 - 284 + 226 285 count += 1; 227 - 286 + 228 287 if package_batch.len() >= batch_size { 229 288 let tx = conn.transaction()?; 230 289 { 231 290 let mut stmt = tx.prepare_cached("INSERT INTO packages VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")?; 232 291 for p in &package_batch { 233 - stmt.execute(rusqlite::params![p.0, p.1, p.2, p.3, p.4, p.5, p.6, p.7, p.8, p.9, p.10, p.11, p.12, p.13, p.14, p.15, p.16, p.17, p.18, p.19])?; 292 + stmt.execute(rusqlite::params![ 293 + p.0, p.1, p.2, p.3, p.4, p.5, p.6, p.7, p.8, p.9, p.10, p.11, p.12, p.13, 294 + p.14, p.15, p.16, p.17, p.18, p.19 295 + ])?; 234 296 } 235 297 } 236 298 { ··· 240 302 } 241 303 } 242 304 tx.commit()?; 243 - 244 - println!("Progress: {}/{} ({:.1}%)", count, total, (count as f64 / total as f64) * 100.0); 305 + 306 + println!( 307 + "Progress: {}/{} ({:.1}%)", 308 + count, 309 + total, 310 + (count as f64 / total as f64) * 100.0 311 + ); 245 312 package_batch.clear(); 246 313 maintainer_batch.clear(); 247 314 } 248 315 } 249 - 316 + 250 317 if !package_batch.is_empty() { 251 318 let tx = conn.transaction()?; 252 319 { 253 320 let mut stmt = tx.prepare_cached("INSERT INTO packages VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")?; 254 321 for p in &package_batch { 255 - stmt.execute(rusqlite::params![p.0, p.1, p.2, p.3, p.4, p.5, p.6, p.7, p.8, p.9, p.10, p.11, p.12, p.13, p.14, p.15, p.16, p.17, p.18, p.19])?; 322 + stmt.execute(rusqlite::params![ 323 + p.0, p.1, p.2, p.3, p.4, p.5, p.6, p.7, p.8, p.9, p.10, p.11, p.12, p.13, p.14, 324 + p.15, p.16, p.17, p.18, p.19 325 + ])?; 256 326 } 257 327 } 258 328 { ··· 263 333 } 264 334 tx.commit()?; 265 335 } 266 - 336 + 267 337 println!("Vacuuming..."); 268 338 conn.execute("VACUUM", [])?; 269 - 339 + 270 340 store_hash(&release.hash)?; 271 - 341 + 272 342 println!("Database created successfully: {db_path}"); 273 343 Ok(()) 274 344 } ··· 342 412 eprintln!("HTTP server error: {e}"); 343 413 } 344 414 }); 345 - 415 + 346 416 tokio::spawn(async { 347 417 let mut interval = tokio::time::interval(std::time::Duration::from_secs(3600)); 348 418 loop {