2024-07-23 17:13:07 +00:00
|
|
|
use std::fmt::Display;
|
|
|
|
|
2024-07-22 17:15:03 +00:00
|
|
|
use crate::Context;
|
2024-07-23 17:13:07 +00:00
|
|
|
use anyhow::Error;
|
|
|
|
use poise::serenity_prelude::{ChannelId, ChannelType, GuildChannel};
|
|
|
|
|
|
|
|
struct Server {
|
|
|
|
channels: Vec<Channel>,
|
|
|
|
orphanage: Vec<GuildChannel>,
|
|
|
|
needs_clean: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Channel {
|
|
|
|
this: GuildChannel,
|
|
|
|
children: Vec<Channel>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for Server {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
|
|
|
fn print(f: &mut std::fmt::Formatter<'_>, tab: usize, channel: &Vec<Channel>) {
|
|
|
|
for i in channel {
|
|
|
|
for _ in 0..tab { let _ = write!(f, "\t"); }
|
|
|
|
let _ = writeln!(f, "{} {}", prefix(i.this.kind),i.this.name);
|
|
|
|
print(f, tab+1, &i.children);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn prefix(kind: ChannelType) -> &'static str {
|
|
|
|
match kind {
|
|
|
|
poise::serenity_prelude::ChannelType::Text => "💬",
|
|
|
|
poise::serenity_prelude::ChannelType::Private => "🕵️",
|
|
|
|
poise::serenity_prelude::ChannelType::Voice => "🔊",
|
|
|
|
poise::serenity_prelude::ChannelType::GroupDm => "👨👦👦",
|
|
|
|
poise::serenity_prelude::ChannelType::Category => "📁",
|
|
|
|
poise::serenity_prelude::ChannelType::News => "📢",
|
|
|
|
poise::serenity_prelude::ChannelType::NewsThread => "📢🧵",
|
|
|
|
poise::serenity_prelude::ChannelType::PublicThread => "🧵",
|
|
|
|
poise::serenity_prelude::ChannelType::PrivateThread => "🕵️🧵",
|
|
|
|
poise::serenity_prelude::ChannelType::Stage => "🎙️",
|
|
|
|
poise::serenity_prelude::ChannelType::Directory => "📒",
|
|
|
|
poise::serenity_prelude::ChannelType::Forum => "🗣️",
|
|
|
|
_ => "?",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
print(f, 0, &self.channels);
|
|
|
|
|
|
|
|
|
|
|
|
if self.needs_clean {
|
|
|
|
let _ = writeln!(f, "Orphans: (please clean() before displaying...)");
|
|
|
|
for i in &self.orphanage {
|
|
|
|
let _ = write!(f, "{} {},", prefix(i.kind),i.name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Server {
|
|
|
|
|
|
|
|
fn new() -> Self {
|
|
|
|
Self {
|
|
|
|
channels: Vec::new(),
|
|
|
|
orphanage: Vec::new(),
|
|
|
|
needs_clean: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO this might be broken
|
|
|
|
fn search<'a>(target: &'a mut Vec<Channel>, find: &ChannelId) -> Option<&'a mut Channel> {
|
|
|
|
for child in target {
|
|
|
|
if child.this.id == *find {
|
|
|
|
return Some(child);
|
|
|
|
}
|
|
|
|
match Self::search(&mut child.children, find) {
|
|
|
|
Some(x) => return Some(x),
|
|
|
|
None => {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add(&mut self, insert: GuildChannel) {
|
|
|
|
// make sure the new item wants a parent
|
|
|
|
if let Some(parent_id) = &insert.parent_id {
|
|
|
|
// find the parent (needs to go thru all nodes)
|
|
|
|
|
|
|
|
match Self::search(&mut self.channels, &parent_id) {
|
|
|
|
Some(parent_node) => {
|
|
|
|
parent_node.children.push(Channel { this: insert, children: Vec::new() });
|
|
|
|
},
|
|
|
|
None => {
|
|
|
|
// couldn't find parent, store somewhere else until it's parent is added...
|
|
|
|
self.orphanage.push(insert);
|
|
|
|
self.needs_clean = true;
|
|
|
|
},
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.channels.push(Channel { this: insert, children: Vec::new() })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn clean(&mut self) {
|
|
|
|
if !self.needs_clean {return;}
|
|
|
|
|
|
|
|
// Look thru the orphanage and try to find parents
|
|
|
|
for orphan in &self.orphanage {
|
|
|
|
if let Some(parent_id) = orphan.parent_id {
|
|
|
|
if let Some(found) = Self::search(&mut self.channels, &parent_id) {
|
|
|
|
found.children.push(Channel { this: orphan.clone(), children: Vec::new() });
|
|
|
|
} else {
|
|
|
|
panic!("⚠️ Couldn't find parent for orphan!");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
panic!("⚠️ All orphans should want a parent node!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.orphanage.clear();
|
|
|
|
self.needs_clean = false;
|
|
|
|
}
|
|
|
|
}
|
2024-07-22 17:15:03 +00:00
|
|
|
|
|
|
|
// NOTE!!! Make sure these names in quotes are lowercase!
|
2024-07-23 17:13:07 +00:00
|
|
|
#[poise::command(slash_command, rename = "index", guild_only)]
|
|
|
|
pub async fn index(ctx: Context<'_>) -> Result<(), Error> {
|
|
|
|
|
|
|
|
let guild = ctx.guild_id().unwrap().to_partial_guild(ctx.serenity_context()).await.unwrap();
|
|
|
|
match guild.channels(ctx.http()).await {
|
|
|
|
Ok(ok) => {
|
|
|
|
|
|
|
|
let mut server = Server::new();
|
|
|
|
|
|
|
|
// iterate thru all channels
|
|
|
|
ok.into_iter().for_each(|(_id, current)| {
|
|
|
|
match current.kind {
|
|
|
|
poise::serenity_prelude::ChannelType::Text => {
|
|
|
|
server.add(current);
|
|
|
|
// current.position,
|
|
|
|
},
|
|
|
|
poise::serenity_prelude::ChannelType::Private => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::Voice => {
|
|
|
|
server.add(current);
|
|
|
|
// current.user_limit,
|
|
|
|
// current.parent_id,
|
|
|
|
},
|
|
|
|
poise::serenity_prelude::ChannelType::GroupDm => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::Category => {
|
|
|
|
server.add(current);
|
|
|
|
},
|
|
|
|
poise::serenity_prelude::ChannelType::News => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::NewsThread => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::PublicThread => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::PrivateThread => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::Stage => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::Directory => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::Forum => todo!(),
|
|
|
|
poise::serenity_prelude::ChannelType::Unknown(_) => todo!(),
|
|
|
|
_ => todo!(),
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
server.clean();
|
|
|
|
println!("{}", server);
|
|
|
|
|
|
|
|
},
|
|
|
|
Err(_) => todo!(),
|
|
|
|
}
|
2024-07-22 17:15:03 +00:00
|
|
|
Ok(())
|
|
|
|
}
|